算法:C++ 实现 快速排序、归并排序

x33g5p2x  于2022-04-10 转载在 其他  
字(2.5k)|赞(0)|评价(0)|浏览(419)

1、快速排序

快速排序:说白了就是给基准数据找其正确索引位置的过程。

  1. 设置最开始的基准数据定义为数组中间的元素,用变量去存储基准数据,即mid=a[头+尾)/2];
  2. 以mid为界,然后分别从数组的两端扫描数组,设两个指示标志:begin指向起始位置,end指向末尾。当begin与end相遇前,交换位置的值,直到两者相遇。
  3. 重新调用函数qsort(),直到不满足条件if(h<end);if(begin<r)。
  1. #include <iostream>
  2. #include <cstdio>
  3. #include <cstring>
  4. using namespace std;
  5. const int Max = 100; //定义数组长度
  6. int a[Max];
  7. void qsort(int,int);
  8. int main(){
  9. int n,i;
  10. cout<<"输入n个整数:";
  11. cin>>n;
  12. cout<<"每个整数按空格隔开:"<<endl;
  13. for(i=1;i<=n;i++) //输入数据
  14. cin>>a[i];
  15. qsort(1,n); //调用函数
  16. cout<<"快速排序结果:"<<endl;
  17. for(i=1;i<=n;i++) //输出数据
  18. cout<<a[i]<<" ";
  19. cout<<endl;
  20. }
  21. void qsort(int h,int r){
  22. int begin,end,mid,p;
  23. begin=h; //标记开头
  24. end=r; //标记尾巴
  25. mid=a[(h+r)/2]; // 定义数组中间的元素基准数
  26. do
  27. {
  28. while(a[begin]<mid) begin++; //左部分寻找比中间大的数位置
  29. while(a[end]>mid) end--; //右部分寻找比中间小的数位置
  30. if(begin<=end) //找到位置,交换值,直到两个标记相遇
  31. { //在左边数比mid大 or 右边数比mid小的情况-->交换值
  32. p=a[begin];
  33. a[begin]=a[end];
  34. a[end]=p;
  35. begin++;
  36. end--;
  37. }
  38. }while(begin<=end);
  39. // 一趟过后,begin>end; mid的左边数<mid; mid的右边数>mid;
  40. if(h<end) //mid左边满足条件
  41. qsort(h,end); // 递归->对h,end的范围进行qsort()判断
  42. if(begin<r) //mid右边满足条件
  43. qsort(begin,r); // 递归->
  44. }

快速排序是不稳定的排序方法,时间复杂度是O(nlog2n),速度快,平均时间来说,快速排序是最好的一种内部排序方法。但快速排序需要一个栈空间实现递归,每一趟排序都会将记录序列分割成两个子序列,栈最大深度为log(n+1)。

2、归并排序

归并的思路(分治)是把一个大问题a拆解成两个小问题b和c,解决了两个子问题再整合一下,就解决了原问题。用递归的方法,先分解再合并(分治是一种解决问题的处理思想,递归是一种编程技巧,这两者并不冲突)。

  • 稳定性:稳定;
  • 空间复杂度O(n);
  • 复杂度:时间复杂度O(nlogn);
  • 优缺点:效率高且稳定,但是消耗的辅助空间与原数据空间成正比。

1. 若low>high,则将序列分从中间mid=(low+high)/2分开;
2. 对左半部分[low, mid]递归地进行归并排序;
3. 对右半部分[mid+1, high]递归地进行归并排序;
4. 将左右两个有序子序列Merge为一个。

  1. #include <iostream>
  2. #include <cstdio>
  3. #include <cstring>
  4. using namespace std;
  5. const int Max = 1000; //定义数组长度
  6. int a[Max]; //定义数组
  7. int r[Max]; //定义辅助函数
  8. void merge(int a[],int low,int mid,int high){ //2.3
  9. int i=low,j=mid+1,k=low; //i,j标记mid分割后左右序列的首位置,k记录序列首位置
  10. for(k;k<=high;k++) //把数组a复制到数组r上;
  11. r[k]=a[k];
  12. for(k=i;i<=mid && j<=high; k++){ //在范围内
  13. if(r[i]<=r[j]) //比较左、右序列的值,把小的值存在数组a;
  14. a[k]=r[i++]; //以此类推,保证数组a[]顺序存储从小到大;
  15. else
  16. a[k]=r[j++];
  17. } //剩下的不在在范围内
  18. while(i<=mid) a[k++]=r[i++]; //保存到数组a[]后面
  19. while(j<=high) a[k++]=r[j++];
  20. }
  21. void msort(int a[],int low,int high){ //2.1
  22. if(low<high){
  23. int mid=(low+high)/2;
  24. msort(a,low,mid);
  25. msort(a,mid+1,high); //当函数msort()递归到只有一个元素组成的序列
  26. merge(a,low,mid,high); //2.2 就调用这个方法
  27. }
  28. }
  29. int main(){
  30. int n;
  31. cout<<"输入n个整数:";
  32. cin>>n;
  33. cout<<"每个整数按空格隔开:"<<endl;
  34. for(int i=1;i<=n;i++) //1、输入数据
  35. cin>>a[i];
  36. msort(a,1,n); //2、调用函数
  37. cout<<"归并排序结果:"<<endl;
  38. for(int i=1;i<=n;i++) //3、输出数据
  39. cout<<a[i]<<" ";
  40. cout<<endl;
  41. }

相关文章