快速排序
快速排序的基本原理就是取序列中的一个值,使用一定的移动策略,最终使此值左侧小于该值,右侧大于该值,然后以此值为分界点使用前面的方法进行分治。下面我们直接给出代码,
1 int partition(int table[], int l, int r) 2 { 3 int i = l; 4 int j = r; 5 int x = table[l]; // x 选取的策略可以变更 6 while (i < j) 7 { 8 // 从最右侧开始查找比 x 小的值 9 while (i < j && x <= table[j]) 10 j--; 11 // 一旦找到,将此值扔到那个最开始取 x 的那个位置上,不过此处就留下了一个位置 12 if (i < j) 13 { 14 table[i] = table[j]; 15 i++; 16 } 17 18 // 从最左侧开始查找比 x 大的值 19 while (i < j && x >= table[i]) 20 i++; 21 // 一旦找到,将此值扔到上面留下来的位置上 22 if (i < j) 23 { 24 table[j] = table[i]; 25 j--; 26 } 27 } 28 29 table[i] = x; 30 return i; 31 }
1 void quick_sort(int table[], int l, int r) 2 { 3 if (l < r) 4 { 5 int i = partition(table, l, r); 6 // i 的左右两侧进行分治 7 quick_sort(table, l, i-1); 8 quick_sort(table, i+1, r); 9 } 10 }
可见最终要的过程为上面的 partition 方法,下面就此描述下这个过程,
1.下面是 table 的初始状态,蓝色代表 i 的位置,红色代表 j 的位置
2.执行 9~16 行
3.执行 19~26 行
4.执行 9~16 行
5.执行 19~26 行
6.执行 9~16 行(i == j)
7.执行 29 行
8.返回下标 3
整个过程就是两边向中间逼近,最后把取出来的值放回去。
另外参考值的选取可以使用随机的方法选取,或者取中间的,以应对不同分布的源数据。而且这个算法是递归的,可以在 quick_sort 函数中判断 l 和 r 距离不是很大时采用其他非递归的排序算法,如插入排序或者冒泡排序,避免递归过深。