荷兰国旗问题
问题可以抽象为:将一个数组依次分成三个子序列,要求三个子序列按一定顺序排列,每个子序列中元素相同。
算法思想
借助快速排序的分治思想,前后同时遍历,遇到逆序交换元素。将红色条块交换到前面,蓝色条块交换到最后面,白色位于红蓝之间。
为三个子序列设置三个移动变量(i,j,k),第二个子序列是排序的关键,因为当从前往后遍历整个数组时,我们必须聚焦到第二个子序列的移动变量,i必须小于等于j,j必须小于等于k,根据j指向元素的颜色,决定将其交换到前部还是尾部。i之前的元素为红色,i,j之间的元素为白色;k之后为蓝色。
实现代码
typedef enum{RED,WHITE,BLUE} color;//设置枚举数组
void Flag_Arrange(color a[],int n){
int i=0,j=0,k=n-1;
while(j<=k){
switch(a[j]){
case RED:{
//不考虑交换后a[j]不为白色,是因为明确知道a[i],a[j]是什么颜色,a[i]为白,a[j]为红
Swap(a[i],a[j]);
i++;j++;
break;
}
case WHITE:0{
Swap(a[i],a[j]);
j++;
break;
}
case BLUE:{//这里没有j++语句以防止交换后a[j]不为白色的情况
Swap(a[k],a[j]);
k--;
}
}
}
}