算法题解----快速排序与归并排序

相信上过数据结构这门课的同学都接触过排序问题,一开始我们学习的是冒泡排序,虽然时间复杂度很糟糕,但是也是最经典最基础的排序算法。

今天我来介绍两种也很经典的排序算法:快速排序和归并排序。

首先是快速排序
快速排序用的是分而治之的思想。

① 首先我们来确定一个分界点,理论上是可以随机确定分界点的,但是我偏向于选择q[ ( l + r ) / 2 ] 这个分界点

② 调整排序区间,那么具体如何调整呢?如下图所示:

③递归处理左右两端

快速排序的时间复杂度平均来说是 O ( n logn) 同时快速排序也不是稳定排序。

话不多说 上代码~

 

# include <iostream>
# include <algorithm>
using namespace std;

const int N =1e6+10;
int n;
int q[N];

void quick_sort(int q[],int l,int r)
{
    if(l>=r) return;      //递归出口
    int x = q[( l + r ) / 2],i = l-1,j=r+1;    //确保排序不漏掉第一个和最后一个
    while(i<j)
    {
        do i++; while(q[i]<x);  //当i指向的数小于x,i后移
        do j--; while(q[j]>x);  //当j指向的数小于x,j前移
        if(i<j)  swap(q[i] , q[j]);  //当i j停止 调换位置
     }
     quick_sort(q,l,j);
     quick_sort(q,j+1,r);  //递归
}

int main()
{
    cin.tie(0);
    cin>>n;
    for(int i = 0;i < n ; i ++)
    {
         cin>>q[i];
    }
    quick_sort(q,0,n-1);
    for(int i = 0;i < n ; i ++)
        cout<<q[i]<<" ";
    
    return 0;
}
        

下面再介绍另一种排序算法:归并排序

归并排序用的也是分治的思想。

① 首先找分界点mid = (l + r ) / 2

② 这里就与快速排序不同啦,我们这里先递归

③再归并 合二为一

我画一张图来帮助理解一下:

 

上代码~

# include <iostream>
# include <algorithm>
using namespace std;

const int N = 1e6+10;
int n;
int q[N],temp[N];

void merge_sort(int l,int r)
{
     if(l>=r) return;    //递归出口
     int mid = (l+r) / 2; 
     merge_sort(l,mid);
     merge_sort(mid+1,r);
     int i =l,j=mid+1,k=0;    //k是temp数组的指针
     while(i <= mid && j <= r)
     {
           if(q[i] <= q[j]) temp[k++] = q[i++];
           else temp[k++] = q[j++];
      }
       //存在一端已经存入temp中但是另一端还没存完的情况
      while(i<=mid) temp[k++] = q[i++];
      while(j<=r) temp[k++] = q[j++];   
      for(i = l,j = 0;i<=r;i++,j++)
           q[i] = temp[j];    //双指针用temp更新q
}

int main()
{
    cin.tie(0);
    cin>>n;
    for(int i = 0;i < n ; i ++)
    {
         cin>>q[i];
    }
    merge_sort(0,n-1);
    for(int i = 0;i < n ; i ++)
        cout<<q[i]<<" ";
    
    return 0;
}

归并排序的时间复杂度是稳定的O(nlogn) 同时归并也是稳定的排序算法~

 

虽然我们平时在做题的时候想排序直接用algorithm库中的sort函数,但是这种分治的思想也很重要。

话说sort函数好像也不是用的快速排序,分情况用堆排序还是快速排序。

posted @ 2021-08-22 10:53  Apak陈柏宇  阅读(94)  评论(0编辑  收藏  举报