荷兰国旗是红白蓝三个横条,荷兰国旗问题就是一个排序问题,这个待排数组只包含0,1,2三种元素.
import random a = [random.randint(0, 2) for i in range(10)] print("最初的数组为",a) beg, cur, end = 0, 0, len(a)-1 while cur <= end: if a[cur] == 0: a[cur], a[beg] = a[beg], a[cur] if cur==beg:cur+=1 beg += 1 elif a[cur] == 2: a[cur], a[end] = a[end], a[cur] end -= 1 else: cur += 1 print(a)
三个指针头,中,尾,中间的指针不断向后移动,直到与尾指针重合,尾指针尽量指向最后一个非2的元素,头指针指向的是第一个非0的元素.中间指针一旦遇到0,就与头指针交换,遇到2就与尾指针交换,遇到1直接向后走.这样此算法为线性复杂度,且没有额外的空间.
对于这种元素种数有限的排序问题,完全可以用另一种方式:定义set box[n],定义n个盒子,n为种类数,每个元素放进一个盒子就可以了.
还可以定义int box[n],只需要统计每种元素的个数,然后根据个数输出一下就可以了,这适用于同一种类的元素完全相同的情况.
如果要求不占用额外的空间,那就要用荷兰国旗类似的思路了.这种算法只适用于三种元素问题吗?多种元素多个指针可不可以?我觉得可以,算法沦为带多个指针的插入排序.复杂度为O(种类数*长度),如果种类数=长度,那么复杂度沦为O(N*N).这可以看作是插入排序的一个变种,带种类指针的插入排序:
import random kind=5 a = [random.randint(0, kind-1) for i in range(20)] print("最初的数组为",a) p=[0 for i in range(kind)] while p[kind-1]<len(a): x=a[p[kind-1]] a[p[x]],a[p[kind-1]]=a[p[kind-1]],a[p[x]] p[x]+=1 for i in range(x,kind): p[i]=max(p[i],p[x]) print("指针数组为",p) print("现在数组为",a) input("====wait=====") print(a)