氣泡排序,快速排序,堆排序,歸併排序
1.氣泡排序
(1)基本思想:從無序序列頭部開始,進行兩兩比較,根據大小交換位置,直到最後將最大(最小)的資料元素交換到了無序序列的隊尾,從而成為有序序列的一部分;下一次繼續這個過程,直到所有資料元素都排好序。演算法的核心在於:每次通過兩兩比較交換位置。選出剩餘無序序列裡最大(最小)的資料元素放到隊尾。
(2)C++實現程式碼:
#include<stdio.h> void bubble_sort(int arr[],int len) { int i,j,temp; for(i=0;i<len-1;i++){ for(j=0;j<len-1-i;j++){ if(arr[j]>arr[j+1]) temp=arr[j]; arr[j]=arr[j+1]; arr[j+1]=temp; } } }
(3)時間複雜度:O(n^2) 空間複雜度:O(1)
2.快速排序:快速排序是十分常用的高效率演算法
(1)基本思想:先選一個‘標尺’,用它把整個佇列過一遍篩子,以保證,其左邊的元素都不大於他,其右邊的元素都不小與他。
這樣,排序問題就被分割為兩個子區間,再分別對子區間排序就可以了。
(2)c++實現程式碼:
#include<iostream> #include<cstdio> #include<cmath> #include<cstdlib> #include<algorithm> using namespace std; int partitions(int a[],int beg,int en){ int key=a[beg]; int i=beg,j=en; while(i<j){ while(i<j&&a[j]>=key) j--; if(i<j){ int tmp=a[i]; a[i]=a[j]; a[j]=tmp; i++; } while(i<j&&a[i]<key) i++; if(i<j){ int tmp=a[i]; a[i]=a[j]; a[j]=tmp; j--; } } a[i]=key; return i; } void quick_sort(int a[],int beg,int en){ if(beg<en){ int middle=partitions(a,beg,en); quick_sort(a,beg,middle-1); quick_sort(a,middle+1,en); } } int main () { int a[]={1,4,5,2,9,6,8,0,3,7}; quick_sort(a,0,9); for(int i=0;i<10;i++) { cout<<a[i]<<" "; } cout<<endl; int *p=a; while(p!=a+10){ cout<<*p<<" "; p++; } cout<<endl; }
(3)時間複雜度O(nlogn)
3.堆排序
(1)堆的定義:堆是一棵完全二叉樹,它的每個節點的值都大於或等於其左右孩子節點的值,稱為大頂堆(最大堆),或者每個節點的值都小於等於其左右孩子節點的值,稱為小頂堆(最小堆)。
如下圖:
同時,我們對堆中的結點按層進行編號,將這種邏輯結構對映到陣列中就是下面這個樣子
該陣列從邏輯上講就是一個堆結構,我們用簡單的公式來描述一下堆的定義就是:
大頂堆:arr[i] >= arr[2i+1] && arr[i] >= arr[2i+2]
小頂堆:arr[i] <= arr[2i+1] && arr[i] <= arr[2i+2]
(2)堆排序的步驟:
步驟一 構造初始堆。將給定無序序列構造(也就是調整)成一個大頂堆(一般升序採用大頂堆,降序採用小頂堆)。
步驟二 將堆頂元素與末尾元素進行交換,使末尾元素最大。然後繼續調整堆,再將堆頂元素與末尾元素交換,得到第二大元素。如此反覆進行交換、重建、交換。
(3)實現程式碼:
#include<stdio.h>
//構建初始大頂堆
void init(int arr[],int len)
{
for(int i=len/2-1;i>=0;i--){
adjust(arr,i,len);
}
}
//堆調整
void adjust(int arr[],int r,int len)
{
int temp=arr[r],k;
for(k=2*r+1;k<len;k=k*2+1){
if(k+1<len&&arr[k]<arr[k+1])
k++;
if(arr[k]>temp){
arr[r]=arr[k];
r=k;
}
else
break;
}
arr[r]=temp;
}
//交換
void swp(int arr[],int i,int j)
{
int temp=arr[i];
arr[i]=arr[j];
arr[j]=temp;
}
//堆排序
void sort_h(int arr[],int len)
{
for(int i=len-1;i>0;i--){
swp(arr,0,i);
adjust(arr,0,i);
}
}
(4)時間複雜度O(nlogn)
4.歸併排序
(1)程式碼實現:
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<algorithm>
using namespace std;
void merge1(int a[],int p,int q,int r){
int i,j,k;
int n1=q-p+1;
int n2=r-q;
int l[n1];
int rr[n2];
for(i=0;i<n1;i++){
l[i]=a[p+i];
}
for(j=0;j<n2;j++)
rr[j]=a[q+1+j];
i=0;j=0;k=p;
while(i<n1&&j<n2){
if(l[i]<=rr[j]){
a[k]=l[i];
i++;
k++;
}
else{
a[k]=rr[j];
j++;
k++;
}
}
while(i<n1){
a[k]=l[i];
i++;
k++;
}
while(j<n2){
a[k]=rr[j];
j++;
k++;
}
}
void merge_sort(int a[],int p,int r){
if(p<r){
int q=(p+r)/2;
merge_sort(a,p,q);
merge_sort(a,q+1,r);
merge1(a,p,q,r);
}
}
void show(int a[]){
for(int i=0;i<10;i++){
cout<<a[i]<<" ";
}
}
int main ()
{
int a[]={1,0,9,3,2,4,5,7,6,8};
merge_sort(a,0,9);
show(a);
cout<<endl;
}
(2)時間複雜度:O(nlogn)