荷兰国旗问题(三元素数组排序问题)

荷兰国旗是红白蓝三个横条,荷兰国旗问题就是一个排序问题,这个待排数组只包含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)
原文地址:https://www.cnblogs.com/weiyinfu/p/6054008.html