快速排序与归并排序

简单总结一下快速排序和归并排序的用法,这两种方法十分省时,在题目中常用。

快速排序

基本思想通过一趟排序将代拍记录分成两部分,一部分记录关键字比另一部分小,再对这两部分记录继续排序,达到整个序列有序。具体做法是附设两个指针i和j,初值分别为l,r,任选一个记录做枢纽取mid,首先从j位置向前搜找到第一个关键字小于mid的记录,再从i所指位置向后搜索,找到第一个大于mid的记录,将它们互相交换,重复两步直到i>j;

实现代码

#include<bits/stdc++.h>
using namespace std;
int a[100001];
void qsort(int l,int r)
{int i,j,mid;
i=l;
j=r;
mid=a[(l+r)/2];     //将当前序列在中间位置的数记为分隔数
do
{
while(a[i]<mid)    //左半部分寻找比中间数大的数
i++;
while(a[j]>mid)   //右半部分寻找比中间数小的数
j--;
if(i<=j)
{
    swap(a[i],a[j]);  //找到一组与目标不一致的数对就交换
    i++;
    j--;
}
}while(i<=j);
if(l<j)             //未达边界递归搜索左右
qsort(l,j);
if(i<r)
qsort(i,r);
}
int main()
{int n,i;
cin>>n;
for(i=1;i<=n;i++)
cin>>a[i];
qsort(1,n);
for(i=1;i<=n;i++)
cout<<a[i]<<" ";
cout<<endl;
return 0;
}

快排时间复杂度O(nlog2n) 但不稳定,就平均时间来讲,是目前最好的内部排序方法。

归并排序

先使每个子序列有序再使子序列段间有序,分两大步,分解合并,合并过程为:比较a[i],a[j]大小,若a[i]<=a[j],将第一个有序表中元素a[i]复制到r[k]中,并令i,k加一,否则,将第二个有序表中元素a[j]复制到r[k]中,并令j,k加一,循环下去直到其中一个有序表取完,然后再将另一个有序表中剩余元素复制到r中从下标k到t的单元,归并算法通常用递归实现。

实现代码

void msort(int s,int)

{if(s==t)  //如果只有一个数字返回无需排序

return;

int mid=(s+t)/2; 

msort(s,mid);  //分解左序列

msort(mid+1,t);  //分解右序列

int i=s,j=mid+1,k=s;    //合并开始了

while(i<=mid&&j<=t)

{if(a[i]<=a[j])

{r[k]=a[i];

k++;

i++;

}

else

{r[k]=a[j];

k++;

j++;

}

]

while(i<=mid) //复制左序列剩余

{r[k]=a[i];

k++;

i++;

]

while(j<=t) //复制右序列剩余

{r[k]=a[j];

k++;

j++;

}

for(int i=s;i<=t;i++)

a[i]=r[i];

}

归并时间复杂度O(nlog2n) 速度快同时稳定

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值