1. 程式人生 > >常見排序演算法整理2(C++實現)

常見排序演算法整理2(C++實現)

1. 歸併排序

  • 時間複雜度:O(nlogn)
  • 空間複雜度:O(n)

  演算法的基本思想:將每兩個相鄰元素進行歸併,得到新的歸併陣列,每兩個一組再次進行歸併排序,直到所有元素均已排序。

  C++實現:

void mergehelp(int* A,int left,int mid,int right)
    {
        int* B=new int[right-left+1];
        int index=0;
        int i=left;
        int j=mid+1;
        while(i<=mid&&j<=right)
        {
            B[index++]=A[i]<=A[j]?A[i++]:A[j++];
        }
        while(i<=mid)
        {
            B[index++]=A[i++];
        }
        while(j<=right)
        {
            B[index++]=A[j++];
        }
        for(int i=0;i<index;i++)
        {
            A[left++]=B[i];
        }
    }
    void merge(int* A,int left,int right)
    {
        if(left>=right)
            return;
        int mid=(left+right)/2;
        merge(A,left,mid);
        merge(A,mid+1,right);
        mergehelp(A,left,mid,right);
    }
    int* mergeSort(int* A, int n) {
        int left=0;
        int right=n-1;
        merge(A,0,n-1);
        return A;

    }

2. 快速排序

  • 時間複雜度:O(nlogn)
  • 空間複雜度:O(logn)

  演算法的基本思想:

  通過partition函式尋找位置點,利用遞迴地思想,不斷對兩部分陣列進行劃分,直到陣列的個數為1。partition函式的思想,可以通過填坑法來尋找劃分點pivot,將大於等於pivot值的元素放在陣列右側,將小於等於pivot值的元素放在陣列左側,返回劃分點pivot的位置。

  C++實現:

int partition(int* A,int left,int right)
    {
        int pivot=A[left];
        while(left<right)
        {
            while(left<right&&A[right]>=pivot)
            {
                right--;
            }
            swap(A[left],A[right]);
            while(left<right&&A[left]<=pivot)
            {
                left++;
            }
            swap(A[left],A[right]);
        }
        return left;
    }
    void quickSortHelp(int* A,int left,int right)
    {
        if(left<right)
        {
            int pivot=partition(A,left,right);
            quickSortHelp(A,left,pivot-1);
            quickSortHelp(A,pivot+1,right);
        }
    }
    int* quickSort(int* A, int n) {
        int left=0;
        int right=n-1;
        quickSortHelp(A,left,right);
        return A;

    }

3. 堆排序

  • 時間複雜度:O(nlogn)
  • 空間複雜度:O(1)
  • 演算法的基本思想:構造一個最大堆,堆頂的元素為最大值,將堆頂元素與陣列的最後一個元素交換,則最後一個元素已排序好。不斷地將堆頂元素與最後一個元素交換,直到陣列的個數為一。每次交換後,都需要利用heapify函式對堆進行一次調整。構造最大堆的過程也是利用heapify函式對陣列值不斷進行調整。
  • C++實現:
void heapify(int* A,int left,int right)
    {
        int cur=left;
        int child=2*cur+1;
        while(child<right)
        {
            if(child+1<right&&A[child+1]>A[child])
            {
                child++;
            }
            if(A[child]>A[cur])
            {
                swap(A[cur],A[child]);
                cur=child;
                child=2*cur+1;
            }
            else
            {
                break;
            }
        }
    }
    int* heapSort(int* A, int n) {
        for(int i=n/2-1;i>=0;i--)
        {
            heapify(A,i,n-1);
        }
        for(int i=n-1;i>0;i--)
        {
            swap(A[i],A[0]);
            heapify(A,0,i);
        }
        return A;
    }

4. 希爾排序

  • 時間複雜度:O(nlogn)
  • 空間複雜度:O(1)
  • 演算法的基本思想:希爾排序是插入排序的衍生版本。設定一個增量d,將陣列元素分到d個增量中,在每一個增量中採用插入排序。之後縮小增量d的值,再次將元素分到d個增量中,進行插入排序。直到增量d為1,完成排序。
  C++實現:int* shellSort(int* A, int n) {
        int d=n/2;
        while(d>=1)
        {
            for(int i=d;i<n;i++)
            {
                int get=A[i];
                int j=i-d;
                while(j>=0&&A[j]>=get)
                {
                    A[j+d]=A[j];
                    j=j-d;
                }
                A[j+d]=get;
            }
            d=d/2;
        }
        return A;
    }