题目
现有n个红白蓝三种不同颜色的小球,乱序排列在一起,请通过两两交换任意两个球,使得从左至右的球依次为红球、白球、蓝球。
思路
这道题又是快速排序中的划分算法的变种,是一种三向切分,把球排序分成三堆。为了方便讨论,用数字0表示红球,1表示白球,2表示蓝球。声明三个指针begin、current、end,其中current指针用来遍历整个数组。对于current指针所指向的值,有三种情况:
(1)当current所指的值是0的时候,与begin指针所指的元素交换,然后current++,begin++。
(2)当current所指的值是2的时候,与end指针所指的元素交换,然后end–。注意此时current不能++,因为交换后current所指的值可能是0,若直接++则会跳过。
(3)当current所指的值是1的时候,直接current++。
代码
//
// Created by huxijie on 17-3-18.
// 荷兰国旗
#include <iostream>
using namespace std;
void Swap(int src[],int i, int j) {
int tmp = src[i];
src[i] = src[j];
src[j] = tmp;
}
//三向切分
void ThreeSort(int src[],int len) {
int begin = 0, current = 0, end = len - 1;
while (current <= end) {
if (0 == src[current]) {
Swap(src, begin++, current++);
} else if (2 == src[current]) {
Swap(src, end--, current);
} else {
current++;
}
}
for (int i = 0; i < len; ++i) {
cout<<src[i]<<" ";
}
cout<<endl;
}
int main() {
default_random_engine e;
e.seed(time(0));
uniform_int_distribution<int> u(0, 2);
int n =10;
int src[n];
cout<<"Before Sorting: ";
for (int i = 0; i < n; ++i) {
src[i] = u(e);
cout<<src[i]<<" ";
}
cout<<endl;
ThreeSort(src, n);
cout<<"After Sorting: ";
for (int i = 0; i < n; ++i) {
cout<<src[i]<<" ";
}
cout<<endl;
return 0;
}
运行结果
Before Sorting: 0 2 1 2 1 1 0 1 2 2
After Sorting: 0 0 1 1 1 1 2 2 2 2
Process finished with exit code 0