QuickSort快速排序

转自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


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值