排序算法总结

 

【1】插入排序:

是一个对少量元素进行排序的有效算法。实现比较简单。时间复杂度:O(n^2),空间复杂度:O(1)。是稳定的排序方法。

代码:

  1. //insertion sort   
  2. #include <iostream>   
  3. using namespace std;  
  4.   
  5. //insertion sort   
  6. void InsertionSort(int *a,int n)  
  7. {  
  8.     int temp;  
  9.     for(int i = 1;i < n;++i)  
  10.     {  
  11.         temp = *(a + i);  
  12.         int j = i - 1;  
  13.         while(j >= 0 && *(a + j) > temp)  
  14.         {  
  15.             *(a + j + 1) = *(a + j);  
  16.             --j;  
  17.         }  
  18.         *(a + j + 1) = temp;  
  19.     }  
  20. }  
  21.   
  22. int main()  
  23. {  
  24.     int n,temp;  
  25.     cout<<"please input the number of the values that need to sort:"<<endl;  
  26.     cin>>n;  
  27.     int *a = (int*)malloc(n * sizeof(int));  
  28.     cout<<"please input each value:"<<endl;  
  29.     for(int i = 0;i < n;++i)  
  30.     {  
  31.         cin>>temp;  
  32.         *(a + i) = temp;  
  33.     }  
  34.     /* 
  35.     //insertion sort 
  36.     for(int i = 1;i < n;++i) 
  37.     { 
  38.         temp = *(a + i); 
  39.         int j = i - 1; 
  40.         while(j >= 0 && *(a + j) > temp) 
  41.         { 
  42.             *(a + j + 1) = *(a + j); 
  43.             --j; 
  44.         } 
  45.         *(a + j + 1) = temp; 
  46.     }*/  
  47.     InsertionSort(a,n);  
  48.   
  49.     cout<<"the values after sort:"<<endl;  
  50.     for(int i = 0;i < n;++i)  
  51.         cout<<*(a + i)<<" ";  

数据测试:


上述代码可以改进的一个地方是:在查找插入位置的时候可以采用二分查找,但是这样依然不可以把时间复杂度降低为O(nlogn),因为移动元素的复杂度没有降低。所以时间复杂度仍然是O(n^2)。

做此改进需要添加函数InsertLoc用于二分查找需要插入的位置,以及修改函数InsertionSort的实现。具体如下:

  1. //改进:用二分查找来找到插入的位置   
  2. //在数组a[low]---a[high]查找val插入的位置   
  3. int InsertLoc(int *a,int low,int high,int val)  
  4. {  
  5.     if(low == high)  
  6.     {  
  7.         if(val > *(a + low))return (low + 1);  
  8.         else  
  9.             return low;  
  10.     }  
  11.     int mid = (low + high) / 2;  
  12.     if(val > *(a + mid) && val > *(a + mid + 1))  
  13.         return InsertLoc(a,mid + 1,high,val);  
  14.     else if(val < *(a + mid) && val < *(a + mid + 1))  
  15.         return InsertLoc(a,low,mid,val);  
  16.     else  
  17.         return mid;  
  18. }  
  19.   
  20. void InsertionSort(int *a,int n)  
  21. {  
  22.     int temp,insert_location;  
  23.     for(int i = 1;i < n;++i)  
  24.     {  
  25.         temp = *(a + i);  
  26.         int j = i - 1;  
  27.         insert_location = InsertLoc(a,0,j,temp);  
  28.         cout<<"insert_location:"<<insert_location<<endl;  
  29.         while(j >= insert_location)  
  30.         {  
  31.             *(a + j + 1) = *(a + j);  
  32.             --j;  
  33.         }  
  34.         *(a + insert_location) = temp;  
  35.         for(int m = 0;m <= i;++m)  
  36.             cout<<*(a + m)<<" ";  
  37.         cout<<endl;  
  38.     }  
  39. }  

【2】选择排序

第一次找出A中最小的元素,与A[0]交换,接着,找出A中次小得元素,与A[1]互换。对A中头n-1个元素执行这一过程。时间复杂度:O(n^2),不需要辅助空间。是稳定的排序方法。

代码:

  1. //选择排序   
  2. #include <iostream>   
  3. using namespace std;  
  4.   
  5. void ChoseSort(int* a,int n)  
  6. {  
  7.     int temp;  
  8.     for(int i = 0;i < n - 1;++i)  
  9.     {  
  10.         for(int j = i + 1;j < n;++j)  
  11.         {  
  12.             if(*(a + i) > *(a + j))  
  13.             {  
  14.                 temp = *(a + i);  
  15.                 *(a + i) = *(a + j);  
  16.                 *(a + j) = temp;  
  17.             }  
  18.         }  
  19.     }  
  20. }  
  21.   
  22. int main()  
  23. {  
  24.     int n,temp;  
  25.     cout<<"please input the number of the values that need to sort:"<<endl;  
  26.     cin>>n;  
  27.     int *a = (int*)malloc(n * sizeof(int));  
  28.     cout<<"please input each value:"<<endl;  
  29.     for(int i = 0;i < n;++i)  
  30.     {  
  31.         cin>>temp;  
  32.         *(a + i) = temp;  
  33.     }  
  34.     ChoseSort(a,n);  
  35.     cout<<"the values after sort:"<<endl;  
  36.     for(int i = 0;i < n;++i)  
  37.         cout<<*(a + i)<<" ";  
  38.     free(a);  

【3】合并排序

采用分治法。将n个元素分成各含n/2个元素的子序列,用合并排序法对两个子序列递归的排序(子序列长度为1时递归结束),最后合并两个已排序的子序列得到结果。时间复杂度:O(nlogn),空间复杂度:O(n)。不是稳定的排序

代码:

  1. //合并排序   
  2. #include <iostream>   
  3. using namespace std;  
  4.   
  5. #define MAX_VALUE 100000//用于设置哨兵,避免检查是否每一个堆都是空的   
  6.   
  7. //合并两个子数组的函数   
  8. void Merge(int *a,int p,int q,int r)  
  9. {  
  10.     int num1,num2;  
  11.     num1 = q - p + 1;  
  12.     num2 = r - q;  
  13.     int *a1 = (int*)malloc((num1 + 1) * sizeof(int));  
  14.     int *a2 = (int*)malloc((num2 + 1) * sizeof(int));  
  15.     for(int i = 0;i < num1;++i)  
  16.         *(a1 + i) = *(a + p + i);  
  17.     *(a1 + num1) = MAX_VALUE;//设置哨兵元素   
  18.     for(int i = 0;i < num2;++i)  
  19.         *(a2 + i) = *(a + q + 1 + i);  
  20.     *(a2 + num2) = MAX_VALUE;//设置哨兵元素   
  21.       
  22.     //进行排序   
  23.     int index1 = 0;  
  24.     int index2 = 0;  
  25.     for(int i = p;i <= r;++i)  
  26.     {  
  27.         if(*(a1 + index1) < *(a2 + index2))  
  28.         {  
  29.             *(a + i) = *(a1 + index1);  
  30.             ++index1;  
  31.         }  
  32.         else  
  33.         {  
  34.             *(a + i) = *(a2 + index2);  
  35.             ++index2;  
  36.         }  
  37.     }  
  38.     free(a1);  
  1. //递归合并排序算法   
  2. void MergeSort(int *a,int p,int r)  
  3. {  
  4.     if(p < r)  
  5.     {  
  6.         int q = (p + r) / 2;  
  7.         MergeSort(a,p,q);  
  8.         MergeSort(a,q + 1,r);  
  9.         Merge(a,p,q,r);  
  10.     }  
  11. }  
  12.   
  13. int main()  
  14. {  
  15.     int n,temp;  
  16.     cout<<"please input the number of the values that need to sort:"<<endl;  
  17.     cin>>n;  
  18.     int *a = (int*)malloc(n * sizeof(int));  
  19.     cout<<"please input each value:"<<endl;  
  20.     for(int i = 0;i < n;++i)  
  21.     {  
  22.         cin>>temp;  
  23.         *(a + i) = temp;  
  24.     }  
  25.     MergeSort(a,0,n - 1);  
  26.     cout<<"the values after sort:"<<endl;  
  27.     for(int i = 0;i < n;++i)  
  28.         cout<<*(a + i)<<" ";  
  29.     free(a);  

如果不使用哨兵元素,需要修改Merge函数,如下:

  1. //合并两个子数组的函数(不使用哨兵元素)   
  2. void Merge(int *a,int p,int q,int r)  
  3. {  
  4.     int num1,num2;  
  5.     num1 = q - p + 1;  
  6.     num2 = r - q;  
  7.     int *a1 = (int*)malloc(num1 * sizeof(int));  
  8.     int *a2 = (int*)malloc(num2 * sizeof(int));  
  9.     for(int i = 0;i < num1;++i)  
  10.         *(a1 + i) = *(a + p + i);  
  11.     for(int i = 0;i < num2;++i)  
  12.         *(a2 + i) = *(a + q + 1 + i);  
  13.       
  14.     //进行排序   
  15.     int index1 = 0;  
  16.     int index2 = 0;  
  17.     int index = p;  
  18.     while(index1 < num1 && index2 <num2)  
  19.     {  
  20.         if(*(a1 + index1) < *(a2 + index2))  
  21.         {  
  22.             *(a + index) = *(a1 + index1);  
  23.             ++index;  
  24.             ++index1;  
  25.         }  
  26.         else{  
  27.             *(a + index) = *(a2 + index2);  
  28.             ++index;  
  29.             ++index2;  
  30.         }  
  31.     }  
  32.     while(index1 < num1)  
  33.     {  
  34.         *(a + index) = *(a1 + index1);  
  35.         ++index;  
  36.         ++index1;  
  37.     }  
  38.     while(index2 < num2)  
  39.     {  
  40.         *(a + index) = *(a2 + index2);  
  41.         ++index;  
  42.         ++index2;  
  43.     }  
  44.     free(a1);<pre class="cpp" name="code">    free(a2);  
 
 
 

【4】冒泡排序

每一趟都比较相邻两个元素,若是逆序的,则交换。结束的条件应该是“在一趟排序过程中没有进行过交换元素的操作”。时间复杂度:O(n^2),不需要空间复杂度。是不稳定的排序。

  1. #include <iostream>   
  2. using namespace std;  
  3.   
  4. void BubbleSort(int *a,int n)  
  5. {  
  6.     int flag,temp;//标记是否进行过交换操作   
  7.     for(int i = 0;i < n - 1;++i)  
  8.     {  
  9.         flag = 0;  
  10.         for(int j = 0;j < n - 1 - i;++j)  
  11.         {  
  12.             if(*(a + j) > *(a + j + 1))  
  13.             {  
  14.                 temp = *(a + j);  
  15.                  *(a + j) =  *(a + j + 1);  
  16.                  *(a + j + 1) = temp;  
  17.                  flag = 1;  
  18.             }  
  19.         }  
  20.         if(flag == 0)break;  
  21.     }  
  22. }  
  23.   
  24. int main()  
  25. {  
  26.     int n,temp;  
  27.     cout<<"please input the number of the values that need to sort:"<<endl;  
  28.     cin>>n;  
  29.     int *a = (int*)malloc(n * sizeof(int));  
  30.     cout<<"please input each value:"<<endl;  
  31.     for(int i = 0;i < n;++i)  
  32.     {  
  33.         cin>>temp;  
  34.         *(a + i) = temp;  
  35.     }  
  36.     BubbleSort(a,n);  
  37.     cout<<"the values after sort:"<<endl;  
  38.     for(int i = 0;i < n;++i)  
  39.         cout<<*(a + i)<<" ";  
  40. <pre class="cpp" name="code"> free(a);  
 
 
 

【5】快速排序

它是对冒泡排序的一种改进。它的基本思想是:通过一趟排序将待排序元素分成两个部分,其中一部分元素比另一部分元素小。再分别对这两部分元素进行排序。以达到整个元素序列有序。时间复杂度:O(nlogn),空间复杂度O(1),是不稳定的算法。

代码:

  1. #include <iostream>   
  2. using namespace std;  
  3.   
  4. int Partition(int *a,int low,int high)  
  5. {  
  6.     int PivotKey = *(a + low);//用第一个元素做枢轴   
  7.     while(low < high)  
  8.     {  
  9.         while(low < high && *(a + high) > PivotKey)--high;  
  10.         *(a + low) = *(a + high);  
  11.         while(low < high && *(a + low) < PivotKey)++low;  
  12.         *(a + high) = *(a + low);  
  13.     }  
  14.     *(a + low) = PivotKey;  
  15.     return low;  
  16. }  
  17.   
  18. void QuickSort(int *a,int low,int high)  
  19. {  
  20.     if(low < high)  
  21.     {  
  22.         int PivotLoc = Partition(a,low,high);  
  23.         QuickSort(a,low,PivotLoc - 1);  
  24.         QuickSort(a,PivotLoc + 1,high);  
  25.     }  
  26. }  
  27.   
  28. int main()  
  29. {  
  30.     int n,temp;  
  31.     cout<<"please input the number of the values that need to sort:"<<endl;  
  32.     cin>>n;  
  33.     int *a = (int*)malloc(n * sizeof(int));  
  34.     cout<<"please input each value:"<<endl;  
  35.     for(int i = 0;i < n;++i)  
  36.     {  
  37.         cin>>temp;  
  38.         *(a + i) = temp;  
  39.     }  
  40.     QuickSort(a,0,n - 1);  
  41.     cout<<"the values after sort:"<<endl;  
  42.     for(int i = 0;i < n;++i)  
  43.         cout<<*(a + i)<<" ";  
  44.     free(a);  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值