QuickSort快速排序

来源:互联网 发布:长江水利委员会知乎 编辑:程序博客网 时间:2024/06/07 14:08

转自http://blog.csdn.net/caryaliu/article/details/7459623

算法描述:

在当前参加排序的序列array[0..n-1] 中任意选择一个元素(通常称该元素为分界元素或者基准元素), 把小于等于分界元素的所有元素都移到分界元素的前边,把大于等于分界元素的所有元素都移到分界元素的后边,这样,分界元素正好处在排序的最终位置上,并且把当前参加排序的序列分成前后两个子序列,前一个子序列中所有元素都小于等于分界元素,后一个子序列中所有元素都小于等于分解元素。然后分别对这两个子序列中长度大于1的序列递归地进行上述过程,直到使得所有元素都到达整个排序后它们所处的位置。

分界元素可以选取

1. 排序序列的第一个元素

2. 排序序列的最后一个元素

3. 位置居中的元素

这里选择排序序列的第一个元素。

排序过程中需要设定两个排序变量i, j.  

1. i的初始值设置为排序序列中第一个元素之后的一个元素, j的初始值设置为排序序列的最后一个元素位置

2. 当 array[i] <= array[0] && i < n - 1, 一直执行 i += 1;当array[j] >= array[0], 一直执行 j -= 1;

3. 如果 i < j, 交换 array[ i ] 和 array[ j ],重复步骤2和步骤3或者步骤4

4. 如果 i >= j, 交换 array[ 0 ] 和 array[ j ],然后分别递归的对序列 array[0..j-1] 和序列 array[j+1 . . n-1]中长度大于1的子序列执行上述过程,直到整个序列排序结束


看代码,只需关注函数 void quickSort(int array[], int left, int right) 和 void quick_sort(int array[], int n);

1. 快速排序的递归算法实现

[cpp] view plain copy
 print?
  1. #include <stdlib.h>  
  2. #include <stdio.h>  
  3.   
  4. void print_array(int array[], int n)  
  5. {  
  6.     int i;  
  7.     for( i = 0 ; i < n ; ++i )  
  8.     {  
  9.         printf("%d ", array[i]);  
  10.     }  
  11.     printf("\n");  
  12. }  
  13.   
  14. void swapElem(int *elem1, int *elem2)  
  15. {  
  16.     int temp;  
  17.     temp = *elem1;  
  18.     *elem1 = *elem2;  
  19.     *elem2 = temp;  
  20. }  
  21.   
  22. void quickSort(int array[], int left, int right)  
  23. {  
  24.     if( left < right )  
  25.     {  
  26.         int i = left + 1, j = right;  
  27.         int temp;  
  28.         while( 1 )  
  29.         {  
  30.             while( array[i] <= array[left] && i < right )  
  31.                 ++i;  
  32.   
  33.             while( array[j] >= array[left] && j > left )  
  34.                 --j;  
  35.   
  36.             if( i < j )  
  37.             {  
  38.                 swapElem(&array[i], &array[j]);  
  39.             }  
  40.             else  
  41.                 break;  
  42.         }  
  43.   
  44.         swapElem(&array[left], &array[j]);  
  45.   
  46.         quickSort(array, left, j-1);  
  47.         quickSort(array, j+1, right);  
  48.     }  
  49. }  
  50.   
  51. void quick_sort(int array[], int n)  
  52. {  
  53.     quickSort(array, 0, n - 1);  
  54. }  
  55.   
  56. int main()  
  57. {  
  58.     int array[]= {1, 5, 3, 12, 34, 1, 98, 56, 199};  
  59.     int n = sizeof(array) / sizeof(int);  
  60.     quick_sort(array, n);  
  61.     print_array(array, n);  
  62. }  


2. 快速排序算法的非递归算法C++实现, 参考点选用的是一个数组元素中的随机数

[cpp] view plain copy
 print?
  1. void swapElem(int &elem1, int &elem2)  
  2. {  
  3.     int temp;  
  4.     temp = elem1;  
  5.     elem1 = elem2;  
  6.     elem2 = temp;  
  7. }  
  8.   
  9. int RandomInRange(int start, int end)  
  10. {  
  11.     if(end > start)  
  12.     {  
  13.         srand(time(NULL));  
  14.         return start + rand()%(end-start);  
  15.     }  
  16.     return start;  
  17. }  
  18.   
  19. int partition(int array[], int length, int start, int end)  
  20. {  
  21.     if(array == NULL || length < 1 || start < 0 || end >= length)  
  22.         throw new std::exception();  
  23.   
  24.     int index = RandomInRange(start, end);  
  25.     swapElem(array[index], array[end]);  
  26.     int small = start - 1;  
  27.     for(index = start; index < end; ++index)  
  28.     {  
  29.         if(array[index] < array[end])  
  30.         {  
  31.             ++small;  
  32.             if(small != index)  
  33.             {  
  34.                 swapElem(array[index], array[small]);  
  35.             }  
  36.         }  
  37.     }  
  38.   
  39.     ++small;  
  40.     swapElem(array[small], array[end]);  
  41.   
  42.     return small;  
  43. }  
  44.   
  45. void quicksort(int array[], int length)  
  46. {  
  47.     if(array == NULL || length < 1)  
  48.         return;  
  49.   
  50.     stack<int> st;  
  51.     int start = 0;  
  52.     int end = length - 1;  
  53.     if(end > start)  
  54.     {  
  55.         st.push(start);  
  56.         st.push(end);  
  57.   
  58.         while(!st.empty()) {  
  59.             end = st.top();  
  60.             st.pop();  
  61.             start = st.top();  
  62.             st.pop();  
  63.             int index = partition(array, length, start, end);  
  64.             if(index - 1 > start) {  
  65.                 st.push(start);  
  66.                 st.push(index - 1);  
  67.             }  
  68.   
  69.             if(index + 1 < end) {  
  70.                 st.push(index + 1);  
  71.                 st.push(end);  
  72.             }  
  73.         }  
  74.     }  
  75. }  


算法时间复杂度:

1. worst case, 当初始序列已经是升序的序列,则第一次排序经过 n - 1次比较之后,将第1个元素确定在原来的位置上。由于得到的两个子序列中前一个子序列长度 小于 2,于是只得到一个长度为 n - 1 的子序列继续递归执行快速排序,由此可见总的排序次数为 (n - 1) + (n -2) + (n -3) + . . . + 1 = n(n-1) / 2, 时间复杂度是 O(n^2)

2. best case, 每趟快速排序之后,分界元素正好位于排序序列的正中间,于是将排序序列分成大小相等的两个子序列,直到子序列的长度为1

T(n) <= n + 2 T(n/2)

<= n + 2 * n/2 + 4T(n/4) = 2n + 4T(n/4)

. . . . . . 

< = n * log2 n + nT(1)

于是时间复杂度为 n * log2 n


原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 qq无法找到入口怎么办 玩游戏总是掉怎么办 ipad所有按键失灵怎么办 手机启动器停止运行怎么办 安卓版泰拉瑞亚联机失去连接怎么办 吃鸡安装不了怎么办 obb文件丢失了怎么办 dnf登录闪退怎么办 泰拉瑞亚地图找不到备份怎么办 服务器没远程管理卡怎么办 tplink上不了网怎么办 键盘端口坏了怎么办 小米路由dns错误怎么办 电脑内存性能低怎么办 nas硬盘坏了怎么办 360安装环境异常怎么办 连接不上服务器怎么办 路由器被绑定mac怎么办 mac地址绑定失败怎么办 触摸屏忘了密码怎么办? 小区高层水压低怎么办 高层楼房水压不够怎么办 热水器温度太高怎么办 热水器出热水小怎么办 天然气热水器水压不够怎么办 热水器水变小了怎么办 液压齿轮泵没力怎么办 gps总是浮点解怎么办 电源要做到稳压怎么办 变压器输出电压低怎么办 变压器输出电压高怎么办 家里空调带不动怎么办 小天才定位不准怎么办 伐木锯链条不出油怎么办 角磨机切割片卸不下来怎么办 油泵电机声音大怎么办 汽车油泵声音大怎么办 水泵电机噪音大怎么办 注塑机油泵超载怎么办 模具老是粘模怎么办 打印机提示卡纸2怎么办