排序是很基础的东西了,本篇文章总结了一下常用的排序方法,选择排序,插入排序,冒泡排序,归并排序,快速排序。
前面三种排序算法效率都比较低,时间复杂度都是O(n²)
选择排序法:
选择排序是从N个待排序的数中找到最小的数,放到第0个位置上,然后再从剩下的N-1个数里找到最小的,放到第1个位置上……,直到所有元素排好序。
void selectionsort(int a[],int size) //选择排序法
{
int i,j,min,swap;
for(i=0;i<size-1;i++){
min=i;
for(j=i+1;j<size;j++){
if(a[j]<a[min]){
min=j;
}
swap=a[i];
a[i]=a[min];
a[min]=swap;
}}
for(int i=0;i<size;i++){
cout<<a[i];
cout<<" ";
}
}
插入排序法:
- 插入排序法是将待排序的数组分为有序和无序两部分,前者在左边,后者在右边。
- 开始时有序数组只有a[0]一个元素,其余都属于无序部分
- 每次取出无序部分的第一个元素,插入到有序部分,假设插入到合适的位置p,则原p位置及其后面的有序部分元素都要依次向右移动一个位子,有序部分即增加了一个元素。
- 直到无序部分没有元素
void insertationsort(int a[],int size) //插入排序
{
int i,j,temp;
for(i=1;i<size;i++){//i为无序数组的第一个元素
for(j=0;j<i;j++){
//找到a[i]的合适位置
if(a[j]>a[i]){
temp=a[i];
//a[i]及后面有序部分元素依次右移
for(int k=i;k>j;k--){
a[k]=a[k-1];
}
a[j]=temp;
break;
}
}
}
for(int i=0;i<size;i++){
cout<<a[i];
cout<<" ";
}
}
冒泡排序法:
- 冒泡排序法也是将待排序的算法分为有序和无序的两部分,前者在右,后者在左。
- 刚开始整个数组都是无序部分,有序部分没有元素。
- 每次要使得无序部分最大的元素移动到有序部分第一个元素的左边。移动的方法是:依次比较相邻的两个元素,如果前面的比后面的大,就交换他们的位置。这样,大的元素就像水里的气泡一样不断往上浮。移动结束,有序部分就增加了一个元素。
- 直到无序部分没有元素。
下面是代码实现
void bubblesort(int a[],int size)
{
for(int i=0;i<size-1;i++)
for(int j=0;j<size-i;j++){
if(a[j]>a[j+1]){
int tmp=a[j];
a[j]=a[j+1];
a[j+1]=tmp;
}
}
for(int i=0;i<size;i++){
cout<<a[i]<<" ";
}
}
下面两种排序法的时间复杂度均为O(nlogn)
归并排序:
- 把前一部分排序
- 把后一部分排序
- 把两半归并到一个新的有序数组里,然后再拷贝回原数组
void Merge(int a[],int s,int m,int e,int tmp[])
{//a[]是待排序数组,tmp[]是临时存放的空数组
//s是待排序部分数组起始下标,m是中间下标,e是结束下标
int pb=0;
int p1=s,p2=m+1;
//将s到m,m+1到s两部分按大小顺序归并到tmp数组里
while(p1<=m&&p2<=e){
if(a[p1]<a[p2])
tmp[pb++]=a[p1++];
else
tmp[pb++]=a[p2++];
}
//两部分剩下的部分依次存到tmp数组里
while(p1<=m)
tmp[pb++]=a[p1++];
while(p2<=e)
tmp[pb++]=a[p2++];
for(int i=0;i<e-s+1;i++){
a[s+i]=tmp[i];
}
}
void Mergesort(int a[],int s,int e,int tmp[])
{
if(s<e){
int m=s+(e-s)/2;
Mergesort(a,s,m,tmp);
Mergesort(a,m+1,e,tmp);
Merge(a,s,m,e,tmp);
}
}
快速排序:
- 设k=a[0],将k挪到适当位置,使得比k小的元素都在k左边,比k大的元素都在k右边,和k相等的,不关心在k左右出现均可。
- 把k左边的部分快速排序
- 把k右边的部分快速排序
void swap(int &a,int &b)
{
int tmp=a;
a=b;
b=tmp;
}
void Quicksort(int a[],int s,int e)
{//a[]为待排序数组,s为待排序部分起始下标,e为结束下标
if(s>=e)
return;
int k=a[s];
int i=s,j=e;
while(i!=j){
while(a[j]>=k&&i<j)
j--;
swap(a[i],a[j]);
while(a[i]<=k&&i<j)
i++;
swap(a[i],a[j]);
}
Quicksort(a,s,i-1);
Quicksort(a,i+1,e);
}