简单总结一下快速排序和归并排序的用法,这两种方法十分省时,在题目中常用。
快速排序
基本思想通过一趟排序将代拍记录分成两部分,一部分记录关键字比另一部分小,再对这两部分记录继续排序,达到整个序列有序。具体做法是附设两个指针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) 速度快同时稳定