用分治法来解决排序问题(快速排序,归并排序)

一、快速排序
(1)基本思想

  • 在待排序的n个元素中任取一个元素(通常取第一个元素)作为基准,把该元素放入最终位置后,整个数据序列被基准值分割成两个子序列,所有小于基准值的元素放置在前子序列中,所有大于基准值的元素放置在后子序列中,并把基准值排在这两个子序列的中间,这个过程称作划分。
  • 然后对两个子序列分别重复上述过程,直至每个子序列内只有一个记录或空为止
  • 关键在于划分

在这里插入图片描述

在这里插入图片描述

(2)算法

int Partition(int r[]int s,int t) //划分算法
{   int i=s,j=t;
    int tmp=r[s]; //用序列的第1个记录作为基准
    while (i!=j) //从序列两端交替向中间扫描,直至i=j为止     
    {   while (j>i && r[j]>=tmp) 
      j--;     //从右向左扫描,找第1个关键字小于tmp的r[j]
        r[i]=r[j]; //将r[j]前移到r[i]的位置
        while (i<j && r[i]<=tmp) 
      i++;    //从左向右扫描,找第1个关键字大于tmp的r[i]
        r[j]=r[i]; //将r[i]后移到r[j]的位置
 }
 r[i]=tmp;
 return i;
}
void QuickSort(int r[]int s,int t) 
//对r[s..t]元素序列进行递增排序
{  if (s<t)    //序列内至少存在2个元素的情况
   {   int i=Partition(r,s,t);
       QuickSort(r,s,i-1); //对左子序列递归排序
       QuickSort(r,i+1,t); //对右子序列递归排序
   }
}

(3)时间复杂度与空间复杂度的分析
1.时间复杂度
在这里插入图片描述

2.空间复杂度分析
在这里插入图片描述

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

二、归并排序
(1)基本思想
关键在于合并算法,把俩个有序数组合并成一个新的有序数组在这里插入图片描述
自顶向下的二路归并排序算法
例如,对于{2,5,1,7,10,6,9,4,3,8}序列,说明其自顶向下的二路归并排序的过程。
在这里插入图片描述
在这里插入图片描述
(2)算法

void MergeSort(int r[]int s,int t)
//二路归并算法
{   int mid;
  if (s<t)   //子序列有两个或以上元素
  { mid=(s+t)/2;  //取中间位置
    MergeSort(r,s,mid); //对a[s..mid]子序列排序
    MergeSort(r,mid+1,t); //对a[mid+1..t]子序列排序
    Merge(r,s,mid,t); //将两子序列合并,见前面的算法
  }
}
void Merge(int r[]int s,int mid,int t)
//r[s..mid]和r[mid+1..t]→r[s..t]
{  
   int *tmpa;   
   int i=s,j=mid+1,k=0;//k用来记录temp数组的长度
   tmpa=(int *)malloc((t-s+1)*sizeof(int));
   while (i<=mid && j<=t)
       if (r[i]<=r[j])  //将第1子表中的元素放入tmpa中
     {  
          tmpa[k]=r[i];  
          i++; 
          k++; 
     }
     else //将第2子表中的元素放入tmpa中
     {  
           tmpa[k]=r[j]; 
           j++; 
           k++; 
      } 
 while (i<=mid)  //将第1子表余下部分复制到tmpa
  {    
      tmpa[k]=r[i];   
      i++;  
      k++;  
  }
 while (j<=t)  //将第2子表余下部分复制到tmpa
 {    
      tmpa[k]=r[j];   
      j++;  
      k++; 
 }
 for (k=0,i=s;i<=t;k++,i++)  //将tmpa复制回数组r中
    r[i]=tmpa[k];
 free(tmpa);   //释放tmpa所占内存空间
}

(3)时间复杂度的分析与空间复杂度的分析
在这里插入图片描述
(4)自底向上的二路归并排序算法
在这里插入图片描述

基本思想:
在这里插入图片描述

void MergePass(int r[]int length,int n)
//一趟二路归并排序
{  int i;
   for (i=0;i+2*length-1<n;i=i+2*length)   //归并length长的两相邻子表
    Merge(a,i,i+length-1,i+2*length-1);
   if (i+length-1<n)       //余下两个子表,后者长度小于length
     Merge(a,i,i+length-1,n-1);  //归并这两个子表
}
void MergeSort(int  r[]int n) //二路归并算法
{  int length;
   for (length=1;length<n;length=2*length)
    MergePass(r,length,n);
}

在这里插入图片描述

  • 4
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值