排序3——堆排序,歸併排序,快速排序

繼續講排序的方法
堆排序:

void heapify(int *a, int i, int len)
{
    int left = 2 * i + 1;
    int right = 2 * i + 2;
    int max = i;

    if(left < len && a[left] > a[max])
        max = left;
    if(right < len && a[right] > a[max])
        max = right;

    if(max != i)
    {
        swap(a, i, max);
        heapify(a, max, len);
    }
}

void heap_sort(int *a, int len)
{
    int i;
    for(i = len/2 - 1; i >= 0; i--)
    {
        heapify(a, i, len);
    }

    for(i = len - 1; i >= 0; i--)
    {
        swap(a, 0, i);
        len--;
        heapify(a, 0, len);
    }
}

堆排序是指利用堆積樹(堆)這種數據結構所設計的一種排序算法,它是選擇排序的一種。可以利用數組的特點快速定位指定索引的元素。堆分爲大根堆和小根堆,是完全二叉樹。大根堆的要求是每個節點的值都不大於其父節點的值,即A[PARENT[i]] >= A[i]。在數組的非降序排序中,需要使用的就是大根堆,因爲根據大根堆的要求可知,最大的值一定在堆頂。

快速排序:

int quick(int *a, int left, int right)
{
    int piovt = a[right];
    int index = left;
    int i;

    for(i = left; i < right; i++)
    {
        if(a[i] < piovt)
        {
            swap(a, i, index);
            index++;
        }
    }

    swap(a, index, right);

    return index;
}

void qSort(int *a, int left, int right)
{
    if(left < right)
    {
        int piovt = quick(a, left, right);
        qSort(a, left, piovt - 1);
        qSort(a, piovt + 1, right);
    }
}

快速排序的基本思想是:通過一趟排序將要排序的數據分割成獨立的兩部分,其中一部分的所有數據都比另外一部分的所有數據都要小,然後再按此方法對這兩部分數據分別進行快速排序,整個排序過程可以遞歸進行,以此達到整個數據變成有序序列。

歸併排序:

void merge(int *a, int left, int mid, int right, int *tmp)
{
    int i = left; 
    int j = mid + 1;
    int k = 0;

    while(i <= mid && j <= right)
    {
        if(a[i] > a[j])
        {
            tmp[k++] = a[j++];
        }
        else
        {
            tmp[k++] = a[i++];
        }   
    }

    while(i <= mid)
    {
        tmp[k++] = a[i++];
    }

    while(j <= right)
    {
        tmp[k++] = a[j++];
    }

    k = 0;

    for(i = left; i <= right; i++)
    {
        a[i] = tmp[k++];
    }
}

void mergeSort(int * a, int left, int right, int *tmp)
{
    if(left >=right)
        return;

    int mid = (left + right) / 2;
    mergeSort(a, left, mid, tmp);
    mergeSort(a, mid + 1, right, tmp);
    merge(a, left,mid,right,tmp);
}

歸併排序(MERGE-SORT)是建立在歸併操作上的一種有效的排序算法,該算法是採用分治法(Divide and Conquer)的一個非常典型的應用。將已有序的子序列合併,得到完全有序的序列;即先使每個子序列有序,再使子序列段間有序。若將兩個有序表合併成一個有序表,稱爲二路歸併。
歸併過程爲:比較a[i]和b[j]的大小,若a[i]≤b[j],則將第一個有序表中的元素a[i]複製到r[k]中,並令i和k分別加上1;否則將第二個有序表中的元素b[j]複製到r[k]中,並令j和k分別加上1,如此循環下去,直到其中一個有序表取完,然後再將另一個有序表中剩餘的元素複製到r中從下標k到下標t的單元。歸併排序的算法我們通常用遞歸實現,先把待排序區間[s,t]以中點二分,接着把左邊子區間排序,再把右邊子區間排序,最後把左區間和右區間用一次歸併操作合併成有序的區間[s,t]。

以上三種排序都用到了遞歸的思想,由此可見遞歸在我們的學習中是多麼的重要。

發佈了53 篇原創文章 · 獲贊 11 · 訪問量 1萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章