您的位置:首页 > 其它

排序相关——荷兰国旗问题

2017-07-14 21:43 260 查看
给定一个数组,它包括0,1,2三种数,如何做到0放到数组的左边,1放到数组的中间,2放到数组的右边。要求使用交换、原地排序,而不是利用计数进行排序。

这个问题其实就是荷兰国旗问题:

现有n个红白蓝三种不同颜色的小球,乱序排列在一起,请通过两两交换任意两个球,使得从左至右的球依次为红球、白球、蓝球。这个问题之所以叫荷兰国旗,是因为将红白蓝三色的小球弄成条状物,并有序排列后正好组成荷兰国旗。

思路:设定三个用于指定元素的下标指针(PS:在Java中没有指针,此处方便描述):一个前指针begin,一个中指针current,一个后指针end。Current指针遍历整个数组序列:

(1)当current指针所指元素为0时,与begin指针所指的元素交换,而后current++,begin++;

(2)当current指针所指元素为1时,不做任何交换,而后current++;

(3)当current指针所指元素为2时,与end指针所指的元素交换,而后current指针不动,end--.    为什么current指针不动,因为end指针所指的元素在交换前还没有遍历,所以交换后current还是需要停留在当前位置,判断这个交换过来的数是0还是1还是2.

(4)当current指针与end指针重合,遍历结束。

public class HollandFlagProblem {

public static void main(String[] args) {
// TODO Auto-generated method stub
int[] arr={1,1,0,0,2,1,1,0};
//int[] arr={0,1,2,0,1,2,0};
colorSort(arr);
for(int i=0;i<arr.length;i++){

System.out.println(arr[i]);
}

}

public static void colorSort(int[] arr){
if(arr==null||arr.length==0)
return;
int begin=0;
int current=0;
int end=arr.length-1;
while(current<=end){
if(arr[current]==1)
current++;
else if(arr[current]==0){
swap(arr,begin,current);
begin++;
current++;
}
else if(arr[current]==2){
swap(arr,end,current);
end--;  //需要注意的是交换后,当前指针位置不变
}
}
}

public static void swap(int[] arr, int a, int b){
int temp=arr[a];
arr[a]=arr[b];
arr[b]=temp;
}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: