1. 程式人生 > >[數據結構(二)]七種排序算法的C++簡單實現

[數據結構(二)]七種排序算法的C++簡單實現

末尾 技術分享 下標 ima http 直接 wap temp 部分

技術分享

一.冒泡排序(Bubble Sort)

基本思想:兩兩比較相鄰記錄的關鍵字,如果反序則交換,直到沒有反序的記錄為止。

//冒泡排序
void BubbleSort(int *p, int length)
{
    for (int i = 0; i < length-1; i++)
    {
        for (int j =length-1; j>=i;j--)
        {
            if (p[j-1] > p[j])
            {
                swap(p[j-1], p[j]);
            }
        }
    }
}

排序前的順序為:9 1 5 8 3 7 4 6 2

當i=1時,交換的情況如下:

技術分享

技術分享

二.簡單選擇排序(Simple Selection Sort)

通過n-1次關鍵字間的比較,從n-i+1個記錄中選擇最小的記錄,並和第i次(1≤i≤n)記錄交換。

//簡單選擇排序
void SimSelSort(int *p, int length)
{
    int i, j, min;
    for (i = 0; i < length - 1; i++)
    {
        min = i;                       //記錄最小值的下標,初始化為i
        for
(j=i+1;j<=length-1;j++) { if (p[j] < p[min]) min = j; //通過不斷地比較,得到最小值的下標 } swap(p[i], p[min]); } }

技術分享

三.直接插入排序

把一個記錄直接插入到已經排好序的有序表中,從而得到一個新的,記錄數增1的有序表。

//直接插入排序
void StrInserSort(int *p, int length)
{
    int i, j;
    for (i =1; i <length; i++)
    {
        
if ( p[i]<p[i-1]) { int tmp; tmp = p[i]; for (j = i - 1; p[j] > tmp; j--) p[j+1] = p[j]; p[j+1] = tmp; } } }

技術分享

四.希爾排序(Shell Sort)

希爾排序是把記錄按下標的一定增量分組,對每組使用直接插入排序算法排序;隨著增量逐漸減少,每組包含的關鍵詞越來越多,當增量減至1時,整個文件恰被分成一組,算法便終止。

技術分享

void ShellSort(int *p, int length)
{
    int i, j;
    int increment = length;
    do {
         increment = increment / 3 +1;
         for (i = increment ; i <= length - 1; i++)
        {
              if (p[i] < p[i - increment])
              {
                int tmp;
                tmp = p[i];
                for (j = i - increment; j >= 0 && tmp < p[j]; j -= increment)
                  p[j + increment] = p[j];
                p[j + increment] = tmp;
              }
            }
    } while (increment > 1);
}

技術分享

五.堆排序(Heap Sort)

1.堆的定義

堆是具有下列性質的完全二叉樹:每個結點的值都大於或等於其左右孩子結點的值,稱為大頂堆;或者每個結點的值都小於或等於其左右孩子結點的值,稱為小頂堆。

技術分享

技術分享

2.堆排序

堆排序的基本思想(利用堆,如大頂堆進行排序):將待排序的序列構造成一個大頂堆。此時,整個序列的最大值就是堆頂的根結點。將它移走(其實就是將它與堆數組的末尾元素交換,此時末尾元素就是最大值),然後將剩余n-1個序列重新構造成一個堆,這樣就會得到n個元素的次小值。如此反復執行,便能得到一個有序序列。

技術分享

主要問題:

1.如何由一個無序序列構建成一個堆?

2.如何在輸出堆頂元素後,調整剩余元素成為一個新的堆?

//構造最大堆
void MaxHeapFixDown(int *p, int i, int length) {
    int j = 2 * i + 1;
    int temp = p[i];
    while (j<length) {
        if (j + 1<length && p[j]<p[j + 1])
            ++j;
        if (temp>p[j])
            break;
        else {
            p[i] = p[j];
            i = j;
            j = 2 * i + 1;
        }
    }
    p[i] = temp;
}

//堆排序
void HeapSort(int *p, int length) {
    for (int i = length / 2 - 1; i >= 0; i--)
    {
        MaxHeapFixDown(p, i, length);
    }
    for (int i = length - 1; i >= 1; i--)
    {
        swap(p[i], p[0]);
        MaxHeapFixDown(p, 0, i);
        cout << "i的值:" << i << " 排序:";
        ergodic(p, 9);
    }
}

技術分享

六.歸並排序(Merging Sort)

歸並排序就是利用歸並思想實現的排序方法。原理:假設初始序列含有n個記錄,則可以看成是n個有序的子序列,每個子序列長度為1,然後再兩兩歸並,得到[n/2]個長度為2或1的有序子序列;再兩兩歸並….,如此重復,直到的一個長度為n的有序序列為止,稱為2路歸並排序。

技術分享

七.快速排序(Quick Sort)

快速排序的基本思想是:通過一趟排序將待排記錄分割成獨立的兩部分,其中一部分記錄的關鍵字均比另外一部分記錄的關鍵字小,則可分別對這兩部分記錄繼續進行排序,以達到整個序列有序的目的。

//快速排序
void QuickSort(int *p, int l, int r)
{
    if (l< r)
    {
        int i = l, j = r, x = p[l];
        while (i < j)
        {
            while (i < j && p[j] >= x) // 從右向左找第一個小於x的數 
                j--;
            if (i < j)
                p[i++] = p[j];
            while (i < j && p[i]< x) // 從左向右找第一個大於等於x的數 
                i++;
            if (i < j)
                p[j--] = p[i];
        }
        p[i] = x;
        QuickSort(p, l, i - 1); // 遞歸調用 
        QuickSort(p, i + 1, r);  
    }
}

技術分享

總結

技術分享

參考:《大話數據結構》

[數據結構(二)]七種排序算法的C++簡單實現