快速排序

来源:互联网 发布:java oa工作流设计 编辑:程序博客网 时间:2024/05/10 13:54


一. 算法描述

    快速排序:快速排序采用分治法进行排序,首先是分割,选取数组中的任意一个元素value(默认选用第一个),将数组划分为两段,前一段小于value,后一段大于value;然后再分别对前半段和后半段进行递归快速排序。其实现细节如下图所示:


二. 算法分析

平均时间复杂度:O(nlog2n)

空间复杂度:O(n) 

稳定性:不稳定

三. 算法实现

[cpp] view plaincopyprint?
  1. /******************************************************** 
  2. *函数名称:Split 
  3. *参数说明:pDataArray 无序数组; 
  4. *          iBegin为pDataArray需要快速排序的起始位置 
  5. *          iEnd为pDataArray需要快速排序的结束位置 
  6. *函数返回:分割后的分割数位置 
  7. *说明:    以iBegin处的数值value作为分割数, 
  8.            使其前半段小于value,后半段大于value 
  9. *********************************************************/  
  10. int Split(int *pDataArray,int iBegin,int iEnd)  
  11. {  
  12.     int pData = pDataArray[iBegin];    //将iBegin处的值作为划分值  
  13.   
  14.     while (iBegin < iEnd)    //循环分割数组,使其前半段小于pData,后半段大于pData  
  15.     {  
  16.         while (iEnd > iBegin && pDataArray[iEnd] >= pData)    //从后向前寻找小于pData的数据位置  
  17.             iEnd--;  
  18.   
  19.         if (iEnd != iBegin)  
  20.         {  
  21.             pDataArray[iBegin] = pDataArray[iEnd];    //将小于pData数据存放到数组前方  
  22.             iBegin++;  
  23.   
  24.             while (iBegin < iEnd && pDataArray[iBegin] <= pData)  
  25.                 iBegin++;  
  26.               
  27.             if (iBegin != iEnd)  
  28.             {  
  29.                 pDataArray[iEnd] = pDataArray[iBegin];    //将大于pData数据存放到数组后方  
  30.                 iEnd--;  
  31.             }  
  32.         }  
  33.     }  
  34.   
  35.     pDataArray[iEnd] = pData;    //此时iBegin=iEnd,此处存储分割数据pData  
  36.     return iEnd;  
  37. }  
  38.   
  39. /******************************************************** 
  40. *函数名称:QSort 
  41. *参数说明:pDataArray 无序数组; 
  42. *          iBegin为pDataArray需要快速排序的起始位置 
  43. *          iEnd为pDataArray需要快速排序的结束位置 
  44. *说明:    快速排序递归函数 
  45. *********************************************************/  
  46. void QSort(int* pDataArray, int iBegin, int iEnd)  
  47. {  
  48.     if (iBegin < iEnd)  
  49.     {  
  50.         int pos = Split(pDataArray, iBegin, iEnd);    //获得分割后的位置  
  51.         QSort(pDataArray, iBegin, pos - 1);           //对分割后的前半段递归快排  
  52.         QSort(pDataArray, pos + 1, iEnd);             //对分割后的后半段递归快排  
  53.     }  
  54. }  
  55.   
  56. /******************************************************** 
  57. *函数名称:QuickSort 
  58. *参数说明:pDataArray 无序数组; 
  59. *          iDataNum为无序数据个数 
  60. *说明:    快速排序 
  61. *********************************************************/  
  62. void QuickSort(int* pDataArray, int iDataNum)  
  63. {  
  64.     QSort(pDataArray, 0, iDataNum - 1);  
  65. }  

四. 算法优化

    快排选用数组第一个元素作为分割元素,如果是一个已经基本有序的数组,那么时间复杂度将会提升到O(n2);可以从数组中随机选择一个元素作为划分数据,这样即使针对基本有序的数据来说,效率同样达到(nlog2n),优化后分割函数如下所示:
[cpp] view plaincopyprint?
  1. int Split(int *pDataArray,int iBegin,int iEnd)  
  2. {  
  3.     int rIndex = rand() % (iEnd - iBegin + 1);    //随机获得偏移位置  
  4.   
  5.     int pData = pDataArray[iBegin + rIndex];    //将iBegin+rIndex处的值作为划分值  
  6.   
  7.     while (iBegin < iEnd)    //循环分割数组,使其前半段小于pData,后半段大于pData  
  8.     {  
  9.         while (iEnd > iBegin && pDataArray[iEnd] >= pData)    //从后向前寻找小于pData的数据位置  
  10.             iEnd--;  
  11.   
  12.         if (iEnd != iBegin)  
  13.         {  
  14.             pDataArray[iBegin] = pDataArray[iEnd];    //将小于pData数据存放到数组前方  
  15.             iBegin++;  
  16.   
  17.             while (iBegin < iEnd && pDataArray[iBegin] <= pData)  
  18.                 iBegin++;  
  19.               
  20.             if (iBegin != iEnd)  
  21.             {  
  22.                 pDataArray[iEnd] = pDataArray[iBegin];    //将大于pData数据存放到数组后方  
  23.                 iEnd--;  
  24.             }  
  25.         }  
  26.     }  
  27.   
  28.     pDataArray[iEnd] = pData;    //此时iBegin=iEnd,此处存储分割数据pData  
  29.     return iEnd;  
  30. }  
0 0
原创粉丝点击