八大排序简单小结及c++实现

来源:互联网 发布:最优化袁亚湘 编辑:程序博客网 时间:2024/05/16 15:33

转自:http://blog.csdn.net/djixx/article/details/21551751

即插入排序、冒泡排序、选择排序、shell排序、基数排序、归并排序、快速排序、堆排序

、(直接)插入法(交换排序) 

1原理方法

       从第二个数开始与前面的一个一个比较,小于则交换、大于等于则下一个数的循环。

2、特点

1)、稳定性:稳定

2)、时间代价:O(n*n)

    最好——正序——时间代价Θ(n)    

    最差——倒序——时间代价Θ(n*n)  

    平均——乱序——时间代价Θ(n*n) 

3)、辅助存储空间:O(1)

4)、比较

①较为复杂、速度较慢

②n较小时(<=50) 、局部或整体有序时适用

   插入排序的最佳时间代价特性——基本有序。

③循环交换

循环不同:f(n)<=1/2*n*(n-1)<=1/2*n*n

交换不同(赋值操作)

3、代码

[cpp] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. #include <iostream>  
  2. using namespace std;  
  3.   
  4. void InsertSort(int*  , int );  
  5. int main()   
  6. {     
  7.     int data[]={1,-30,12,7,-1,5,4};  
  8.     InsertSort(data,7);  
  9.     for(int i=0;i<7;i++)  
  10.         cout<<dec<<data[i]<<"  ";  
  11.         cout<<"\n";  
  12.     //system ( "pause" );//getchar();  
  13.     return 0;  
  14.  }   
  15.   
  16. void  InsertSort(int* pData,int Count)  
  17. {  
  18.     int iTemp;  
  19.   int iPos;  
  20.     for(int i=1;i<Count;i++)  
  21.     {  
  22.         iPos=i-1;  
  23.         iTemp=pData[i];  
  24.         while((iPos>=0)&&(iTemp<pData[iPos]))  
  25.         {  
  26.             pData[iPos+1]=pData[iPos];  
  27.             iPos--;  
  28.         }  
  29.         pData[iPos+1]=iTemp;   
  30.     }  
  31. }  

二、冒泡法(交换排序)

1原理方法

1)、把小的元素往前调或者把大的元素往后调, 一趟得到一个最大值或最小值。

          若循环外设一个bool变量、最差(倒序)循环n-1趟、最好(正序)循环一趟

2)、有递归和非递归实现

2特点

1)、稳定性:稳定

2)、时间代价

    最好——正序、无交换(O(0))——时间代价Θ(n)(只循环一趟)

    最差——倒序、循环次数=交换次数(O(n*n))——时间代价Θ(n*n)  

    平均——乱序、中间状态                  ——时间代价Θ(n*n)  

3)、辅助存储空间:O(1)

4)、比较

①速度较慢、交换次数相对比较多

②n较小时(<=50) ,局部或整体有序时、较快

③循环交换

循环相同(若循环外不设判断条件):

           1+2+...+n-1=1/2*(n-1)*n<=1/2*n*nK*g(n)

              f(n)O(g(n))O(n*n)(循环复杂度)

交换不同

3、代码

1)、非递归循环实现

[cpp] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. #include <iostream>  
  2. using namespace std;  
  3.   
  4. void BubbleSort(int*  , int );  
  5. int main()   
  6. {     
  7.     int data[]={10,9,13,7,32,5,2};  
  8.     BubbleSort(data,7);  
  9.     for(int i=0;i<7;i++)  
  10.         cout<<dec<<data[i]<<"  ";  
  11.         cout<<"\n";  
  12.     return 0;  
  13.  }   
  14.   
  15. void  BubbleSort(int* pData,int n)  
  16. {  
  17.   int iTemp;  
  18.   
  19.     bool bFilish=fale;  
  20.     for(int i=0;i<n-1;i++)  
  21.   {  
  22.         if(bFlish=true)  
  23.             break;  
  24.         bFilish=true;  
  25.         for(int j=n-1;j>i;j--)  
  26.         {  
  27.             if(pData[j]<pData[j-1])  
  28.             {  
  29.                 iTemp=pData[j-1];  
  30.                 pData[j-1]=pData[j];  
  31.                 pData[j]=iTemp;  
  32.                 bFilish=false;  
  33.             }  
  34.   
  35.         }  
  36.     }  
  37. }  


2)、递归,下面采用双向冒泡
[cpp] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. #include <iostream>  
  2. using namespace std;  
  3.   
  4. void BilateralBubbleSort(int*  , int,int );  
  5. int main()   
  6. {     
  7.     int data[]={10,9,13,7,32,5,2};  
  8.     BilateralBubbleSort(data,0,6);  
  9.     for(int i=0;i<7;i++)  
  10.         cout<<dec<<data[i]<<"  ";  
  11.         cout<<"\n";  
  12.     return 0;  
  13. }   
  14.   
  15. void BilateralBubbleSort(int *a, int first, int last)   
  16. {  
  17.     if (first >= last) //退出条件  
  18.     {                            
  19.          return;  
  20.     }  
  21.   
  22.     int i = first;  
  23.     int j = last;  
  24.       
  25.     int temp = a[first];      
  26.     while (i != j)   
  27.     {                              
  28.         while (i<j && a[j]>=temp)    
  29.         {  
  30.             j--;  
  31.         }  
  32.         a[i] = a[j];  
  33.         while (i<j && a[i]<=temp)   
  34.         {  
  35.             i++;  
  36.         }  
  37.         a[j] = a[i];  
  38.     }  
  39.     a[i] = temp;  
  40.   
  41.     //递归,有点像快速排序,就是中间值放在临时变量而不是数组尾部  
  42.     BilateralBubbleSort(a, first, i-1);       
  43.     BilateralBubbleSort(a, i+1, last);  
  44.     
  45. }  

三、(简单或直接)选择法(交换排序)

1原理方法

1)、第一个元素开始,同其后的元素比较并记录最小值(放在当前位置)。

         每次得到一个最小值

2)、(改进)选择中间变量、减少交换次数

2特点

1)、稳定性:不稳定

2)、时间代价:O(n*n)

    最好——正序、无交换(O(0))                

    最差——倒序、循环次数=交换次数

    平均—— 乱序、中间状态                  

3)、辅助存储空间:O(1)

4)、比较

①速度较慢

②与冒泡法某些情况下稍好,在某些情况下稍差

  这3种中是很有效的, n较小时(<=50) 适用

③循环交换

循环相同:

         1/2*(n-1)*n

交换不同

3、代码

[cpp] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. #include <iostream>  
  2. using namespace std;  
  3.   
  4. void SelectSort(int*  , int );  
  5. int main()   
  6. {     
  7.     int data[]={1,9,12,7,26,5,4};  
  8.     SelectSort(data,7);  
  9.     for(int i=0;i<7;i++)  
  10.     cout<<dec<<data[i]<<"  ";  
  11.     cout<<"\n";  
  12.     return 0;  
  13. }   
  14.   
  15. void  SelectSort(int* pData,int Count)  
  16. {  
  17.     int iTemp;  
  18.     for(int i=0;i<Count-1;i++)  
  19.     {  
  20.     for(int j=i+1;j<Count;j++)  
  21.     {  
  22.         if(pData[i]<pData[j])  
  23.         {  
  24.         iTemp=pData[i];  
  25.         pData[i]=pData[j];  
  26.         pData[j]=iTemp;  
  27.         }  
  28.     }  
  29.     }  
  30. }  

四、快速排序

 1、原理方法

1)、分治法

2)、二叉查找树

像一个二叉树、递归实现

①(分割)首先选择一个轴值,如放在数组最后

②把比它小的放在左边,大的放在右边(两端移动下标,找到一对后交换)。

③直到相遇、返回下标k(右半部起始、即轴值下标)

④然后对两边分别使用这个过程

3)、轴值的选取

①第一个记录的关键码(正、逆序时有问题)

②随机抽取轴值(开销大)

③数组中间点(一般)

4)、最理想的情况
①数组的大小是2的幂,这样分下去始终可以被2整除

    假设为2k次方,即klog2(n)。 

②每次我们选择的值刚好是中间值、数组可以被等分。 

第一层递归,循环n次,第二层循环2*(n/2)...... 
所以共有n+2(n/2)+4(n/4)+...+n*(n/n) = n+n+n+...+nk*nlog2(n)*n 
所以算法复杂度为O(n*log2(n)) 

其他的情况只会比这种情况差,最差的情况是每次选择到的middle都是最小值或最大值,那么他将变成交换法(由于使用了递归,情况更糟)。

 2、特点

1)、稳定性:不稳定

2)、时间代价:O(n*logn) 

   最差——O(n*n) 

    平均——O(n*logn),介于最佳和最差之间

    最好——O(n*logn)

3)、辅助存储空间:O(logn)

4)、比较

 ①局部或整体有序时慢

 ②(大多数情况)平均最快

   n(9)较大时、关键字元素比较随机(杂乱无序)适用

 ③分割数组,多交换、少比较

3、代码

1)、一般的方法

[cpp] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. #include<iostream>  
  2. using namespace std;  
  3. typedef int* IntArrayPtr;  
  4.   
  5. int Divide(int a[],int left,int right)  
  6. {  
  7.     int k=a[left];  //轴值  
  8.     do  
  9.     {  
  10.     while(left<right&&a[right]>=k) --right;  
  11.         if(left<right)  
  12.         {  
  13.         a[left]=a[right];  
  14.         ++left;  
  15.         }  
  16.         
  17.     while(left<right&&a[left]<=k)++left;  
  18.     if(left<right)  
  19.     {  
  20.         a[right]=a[left];  
  21.         --right;  
  22.     }  
  23.     }while(left!=right);  
  24.     //排序后轴值位置,分为两个子序列  
  25.     a[left]=k;  
  26.     return left;  
  27. }  
  28.   
  29. void QuickSort(int a[],int left,int right)  
  30. {  
  31.     int mid;  
  32.     if(left>=right)return;  
  33.   
  34.     mid=Divide(a,left,right);  
  35.     cout<<a[mid]<<'\n';  
  36.     for(int j=left;j<=right;j++)  
  37.     cout<<a[j]<<" ";  
  38.     cout<<'\n';  
  39.   
  40.         //轴值左半部分  
  41.     QuickSort(a,left,mid-1);  
  42.         //轴值右半部分  
  43.     QuickSort(a,mid+1,right);  
  44. }  
  45.   
  46. void FillArray(int a[],int size)//输入数据  
  47. {  
  48.     cout<<"请输入"<<size<<"个整数,数字之间用空格隔开:"<<endl;  
  49.     for(int index=0;index<size;index++)  
  50.     cin>>a[index];  
  51. }  
  52.   
  53. void main()  
  54. {  
  55.     int array_size;  
  56.     cout<<"请输入需要排序的元素个数:";  
  57.     cin>>array_size;  
  58.     IntArrayPtr a;  
  59.     a=new int[array_size];//动态数组  
  60.       
  61.     FillArray(a,array_size);  
  62.     cout<<'\n'<<"快速排序开始:"<<endl;  
  63.       
  64.     QuickSort(a, 0, array_size-1);  
  65.     cout<<"end"<<'\n';  
  66.     for(int k=0;k<array_size;k++)  
  67.     {  
  68.     cout<<a[k]<<" ";  
  69.     }  
  70.     cout<<'\n';  
  71.     system("pause");//getchar();  
  72. }  

2)、剑指offer上一个比较好的方法,保存了数组的两个位置index向前遍历数组,small用于保存交换的小于轴值的数,找到一个前移一步。

[cpp] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. #include "stdafx.h"  
  2. #include <stdlib.h>  
  3. #include <exception>  
  4.   
  5. int RandomInRange(int min, int max)   //随机轴值  
  6. {  
  7.     int random = rand() % (max - min + 1) + min;  
  8.     return random;  
  9. }  
  10.   
  11. void Swap(int* num1, int* num2)  
  12. {  
  13.     int temp = *num1;  
  14.     *num1 = *num2;  
  15.     *num2 = temp;  
  16. }  
  17.   
  18. int Partition(int data[], int length, int start, int end)  
  19. {  
  20.     if(data == NULL || length <= 0 || start < 0 || end >= length)     
  21.         throw new std::exception("Invalid Parameters");  
  22.   
  23.     int index = RandomInRange(start, end);  
  24.     Swap(&data[index], &data[end]);  
  25.   
  26.     int small = start - 1;  
  27.     for(index = start; index < end; ++ index)     
  28.     {  
  29.         if(data[index] < data[end])  
  30.         {  
  31.             ++ small;  
  32.             if(small != index)     
  33.                 Swap(&data[index], &data[small]);  
  34.         }  
  35.     }  
  36.   
  37.     ++ small;       
  38.     Swap(&data[small], &data[end]);  
  39.   
  40.     return small;  
  41. }  
  42.   
  43. //递归快速排序  
  44. void QuickSort(int data[], int length, int start, int end)  
  45. {  
  46.     if(start=end)  
  47.         reurn;  
  48.   
  49.     int index=Partition(data, length, start, end);     
  50.     if(index>start)  
  51.         QuickSort(data, length, start, index-1);  
  52.     if(index<end)  
  53.         QuickSort(data, length,  index+1.end);  
  54. }  

五、Shell排序(缩小增量排序)(局部用的插入排序)

1、原理方法

       由于复杂的数学原因避免使用2的幂次步长,它能降低算法效率

        子序列——每轮等数量(大到小)、等增量、等长度——插入排序——合并再重复

实现:


(1)初始增量为3,该数组分为三组分别进行排序。(初始增量值原则上可以任意设置 

    (0<gap<n),没有限制)

2)将增量改为2,该数组分为2组分别进行排序。

3)将增量改为1,该数组整体进行排序。

 

2、特点

1)、稳定性:不稳定

2)、时间代价——依赖于增量序列

                                                   最好                            最差

 

  平均——()增量除3时是On1.5)、O(n*logn}~On2

3)、辅助存储空间:O(1)

4)、比较

    ①规模非常大的数据排序不是最优选择

    ②n为中等规模时是不错的选择

 3、代码

[cpp] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. #include <iostream>  
  2. using namespace std;  
  3.   
  4. int a[] = {70,30,40,10,80,20,90,100,75,60,45};  
  5. void shell_sort(int a[],int n);  
  6.   
  7. int main()  
  8. {  
  9.     cout<<"Before Sort: ";  
  10.     for(int i=0; i<11; i++)  
  11.     cout<<a[i]<<" ";  
  12.     cout<<endl;  
  13.     shell_sort(a, 11);  
  14.     cout<<"After Sort: ";  
  15.     for(int i=0; i<11; i++)  
  16.     cout<<a[i]<<" ";  
  17.     cout<<endl;  
  18.     system("pause");  //getchar();//gcc中没有system("pause");命令  
  19. }  
  20.   
  21. void shell_sort(int a[], int n)  
  22. {  
  23.     for(int gap = 3; gap >0; gap--)  
  24.    {  
  25.        for(int i=0; i<gap; i++)  
  26.        {  
  27.         for(int j = i+gap; j<n; j=j+gap)  
  28.        {  
  29.         if(a[j]<a[j-gap])  
  30.         {  
  31.             int temp = a[j];  
  32.             int k = j-gap;  
  33.             while(k>=0&&a[k]>temp)  
  34.             {  
  35.             a[k+gap] = a[k];  
  36.             k = k-gap;  
  37.             }  
  38.             a[k+gap] = temp;  
  39.         }  
  40.         }  
  41.         }  
  42.     }  
  43. }  

六、归并排序

 1、原理方法

分治法、归并操作算法)、稳定有效的排序方法(直接插入)、等长子序列

1归并操作

设有数列{62021003013881}

初始状态:6,202,100,301,38,81

第一次归并后:{6,202},{100,301},{8,38},{1},比较次数:3

第二次归并后:{6,100,202,301}{1,8,38},比较次数:4

第三次归并后:{1,6,8,38,100,202,301},比较次数:4

总的比较次数为:3+4+4=11,

逆序数为14

2)、将已有序的子序列合并,得到完全有序的序列若将两个有序表合并成一个有序表,称为二路归并

3)、非递归算法实现

假设序列共有n个元素

①将序列每相邻两个数字进行归并操作(merge),形成floor(n/2)个序列,排序后每个序列包含两个元素

②将上述序列再次归并,形成floor(n/4)个序列,每个序列包含四个元素

③重复上面步骤,直到所有元素排序完毕

 2、特点

1)、稳定性:稳定

2)、时间代价:O(n*logn)

3)、辅助存储空间:O(N)

4)、比较

①空间允许的情况下O(n)

②速度仅次于快速排序、n较大有序时适用

排序:一般用于对总体无序,但是各子项相对有序的数列

求逆序对数:具体思路是,在归并的过程中计算每个小区间的逆序对数,进而计算出大区间的逆序对数

3、代码

[cpp] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. #include <iostream>  
  2. #include <ctime>  
  3. #include <cstring>  
  4. using namespace std;  
  5.   
  6. void Merge(int* data, int a, int b, int length, int n)  
  7. {  
  8.     int right;  
  9.   if(b+length-1 >= n-1)  
  10.       right = n-b;  
  11.   else   
  12.       right = length;  
  13.     
  14.     int* temp = new int[length+right];  
  15.   int i = 0, j = 0;  
  16.     
  17.   while(i<=length-1&&j<=right-1)  
  18.   {  
  19.         if(data[a+i] <= data[b+j])  
  20.         {  
  21.             temp[i+j] = data[a+i];   
  22.             i++;   
  23.         }  
  24.         else  
  25.         {   
  26.             temp[i+j] = data[b+j];   
  27.             j++;   
  28.         }  
  29.     }  
  30.   
  31.   if(j == right)  
  32.   {  
  33.         memcpy(data+a+i+j, data+a+i,(length-i)*sizeof(int));  
  34.   }  
  35.   
  36.     memcpy(data+a, temp, (i+j)*sizeof(int) );  
  37.     delete temp;  
  38. }  
  39.   
  40. void MergeSort(int* data, int n)  
  41. {  
  42.   int step = 1;  
  43.   while(step < n)  
  44.   {  
  45.         for(int i = 0; i <= n-1-step; i += 2*step)  
  46.             Merge(data, i, i+step, step, n);  
  47.         step *= 2;  
  48.     }  
  49. }  
  50.   
  51. int main()  
  52. {  
  53.     int n;  
  54.     cin >> n;  
  55.     int *data = new int[n];  
  56.   if(!data)   
  57.       exit(1);  
  58.     int k = n;  
  59.   while(k --)  
  60.   {  
  61.         cin >> data[n-k-1];  
  62.   }  
  63.     
  64.   clock_t s = clock();  
  65.   MergeSort(data, n);  
  66.   clock_t e = clock();  
  67.     
  68.     k = n;  
  69.   while(k --)  
  70.   {  
  71.         cout << data[n-k-1] << ' ';  
  72.     }  
  73.     cout << endl;  
  74.     cout << "the algrothem used " << e-s << " miliseconds."<< endl;  
  75.     delete data;  
  76.   return 0;   
  77. }  

七、堆排序

1、原理方法

    BST、堆数据结构、利用数组快速定位、无序有序区

 

2、特点

1)、稳定性:不稳定

2)、时间代价:O(n*logn)

3)、辅助存储空间:O(1)

4)、比较

①常情况下速度要慢于快速排序(因为要重组堆)

②既能快速查找、又能快速移动元素。

     n较大时、关键字元素可能出现本身是有序时适用


 3、代码

[cpp] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. #include<iostream>  
  2. #include <ctime>  
  3. #include <cstring>  
  4. using namespace std;  
  5.   
  6. void HeapAdjust(int array[], int i, int nLength)  
  7. {  
  8.     int nChild;  
  9.   int nTemp;  
  10.     
  11.     for (nTemp = array[i]; 2 * i + 1 < nLength; i = nChild)  
  12.     {  
  13.         nChild = 2 * i + 1;  
  14.   
  15.         if ( nChild < nLength-1 && array[nChild + 1] > array[nChild])  
  16.             ++nChild;  
  17.   
  18.         if (nTemp < array[nChild])  
  19.         {  
  20.             array[i] = array[nChild];  
  21.             array[nChild]= nTemp;  
  22.         }  
  23.         else  
  24.             break;  
  25.     }  
  26. }  
  27.   
  28. // 堆排序算法  
  29. void HeapSort(int array[],int length)  
  30. {    
  31.     int tmp;  
  32.     for (int i = length / 2 - 1; i >= 0; --i)  
  33.         HeapAdjust(array, i, length);  
  34.   
  35.     for (int i = length - 1; i > 0; --i)  
  36.     {  
  37.         tmp = array[i];  
  38.         array[i] = array[0];  
  39.         array[0] = tmp;  
  40.         HeapAdjust(array, 0, i);  
  41.     }  
  42. }  
  43.   
  44. int main()  
  45. {  
  46.     int n;  
  47.     cin >> n;  
  48.     int *data = new int[n];  
  49.     if(!data)   
  50.         exit(1);  
  51.     int k = n;  
  52.     while(k --)  
  53.     {  
  54.          cin >> data[n-k-1];  
  55.     }  
  56.   
  57.     clock_t s = clock();  
  58.     HeapSort(data, n);  
  59.     clock_t e = clock();  
  60.   
  61.     k = n;  
  62.     while(k --)  
  63.     {  
  64.         cout << data[n-k-1] << ' ';  
  65.     }  
  66.     cout << endl;  
  67.     cout << "the algrothem used " << e-s << " miliseconds."<< endl;  
  68.     delete data;  
  69.     system("pause");  
  70. }  

八、基数排序(桶排序)(属于分配排序)

1、原理方法

     基数排序(radix sort)属于分配式排序distribution sort、又称桶子法bucket sortbin sort)。通过键值的查询,将要排序的元素分配至某些“桶”中,以达到排序的作用。

1)、分配排序(hash)

①关键码确定记录在数组中的位置,但只能对0n-1进行排序

②(扩展)允许关键码重复、数组元素可变长、每个元素成为链表的头节点

③(扩展)允许关键码范围大于n、关键码值(盒子数)比记录数大很多时效率很差(检查是否有元素)、同时存储的数组变大

④(扩展)桶式排序、每一个盒子与一组关键码相关、桶中(较少)记录用其它方法(收尾排序)排序

⑤堆排序

2)、LSD的基数排序

适用于位数小的数列

73, 22, 93, 43, 55, 14, 28, 65, 39, 81

首先根据个位数的数值,在走访数值时将它们分配至编号09的桶子中

0

1 81

2 22

3 73 93 43

4 14

5 55 65

6

7

8 28

9 39

接下来将这些桶子中的数值重新串接起来,成为以下的数列

81, 22, 73, 93, 43, 14, 55, 65, 28, 39

接着再进行一次分配,这次是根据十位数来分配:

0

1 14

2 22 28

3 39

4 43

5 55

6 65

7 73

8 81

9 93

接下来将这些桶子中的数值重新串接起来,成为以下的数列:

14, 22, 28, 39, 43, 55, 65, 73, 81, 93

这时候整个数列已经排序完毕;如果排序的对象有三位数以上,则持续进行以上的动作直至最高位数为止。

3)、MSD

①位数多由高位数为基底开始进行分配

②分配之后并不马上合并回一个数组中,而是在每个“桶子”中建立“子桶”,将每个桶子中的数值按照下一数位的值分配到“子桶”中。在进行完最低位数的分配后再合并回单一的数组中。

 

2、特点

1)、稳定性:稳定

2)、时间代价

n个记录、关键码长度为d(趟数)基数r(盒子数如10)、不同关键码值m(堆数<=n)

②链式基数排序的时间复杂度为O(d(n+r))

一趟分配时间复杂度为O(n)、一趟收集时间复杂度为O(radix)、共进行d趟分配和收集

③下面是一个近似值,可自己推导

O(nlog(r)m)、O(nlogn)(关键码全不同)

m<=nd>=log(r)m

3)、辅助存储空间

2*r个指向队列的辅助空间、用于静态链表的n个指针

4)、比较

    ①空间允许情况下

    ②适用于:

      关键字在一个有限范围内

      有些情况下效率高于其它比较性排序法

      记录数目比关键码长度大很多

      调节r得到较好性能

3、代码

[cpp] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. int MaxBit(int data[],int n)   
  2. {  
  3.     int maxBit = 1;   
  4.     int temp =10;  
  5.     for(int i = 0;i < n; ++i)  
  6.     {  
  7.         while(data[i] >= temp)  
  8.         {  
  9.             temp *= 10;  
  10.             ++maxBit;  
  11.         }  
  12.     }  
  13.     return maxBit;  
  14. }  
  15.   
  16. //基数排序  
  17. void RadixSort(int data[],int n)  
  18. {  
  19.     int maxBit = MaxBit(data,n);  
  20.   
  21.     int* tmpData = new int[n];     
  22.     int* cnt = new int[10];    
  23.   int  radix = 1;         
  24.   int  i,j,binNum;        
  25.     
  26.     for(i = 1; i<= maxBit;++i)   
  27.     {  
  28.         for(j = 0;j < 10;++j)  
  29.             cnt[j] = 0;   
  30.   
  31.         for(j = 0;j < n; ++j)  
  32.         {  
  33.             binNum = (data[j]/radix)%10;   
  34.             cnt[binNum]++;  
  35.         }  
  36.   
  37.         for(binNum=1;binNum< 10;++binNum)  
  38.             cnt[binNum] = cnt[binNum-1] + cnt[binNum];   
  39.   
  40.         for(j = n-1;j >= 0;--j)   
  41.         {  
  42.             binNum= (data[j]/radix)%10;              
  43.             tmpData[cnt[binNum]-1] = data[j];      
  44.             cnt[binNum]--;                          
  45.         }  
  46.   
  47.         for(j = 0;j < n;++j)  
  48.             data[j] = tmpData[j];  
  49.         radix = radix*10;  
  50.     }  
  51.     delete [] tmp;  
  52.     delete [] cnt;  
  53. }  
0 0
原创粉丝点击