排序總結(C語言)
阿新 • • 發佈:2018-12-16
排序是很基礎的東西了,本篇文章總結了一下常用的排序方法,選擇排序,插入排序,氣泡排序,歸併排序,快速排序。
前面三種排序演算法效率都比較低,時間複雜度都是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);
}