1. 程式人生 > >氣泡排序,快速排序,堆排序,歸併排序

氣泡排序,快速排序,堆排序,歸併排序

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)