插入排序,希爾排序,堆排序詳解

本文將介紹三種排序算法--插入排序,希爾排序,堆排序。本文全部例子都是使用升序算法

  一.插入排序數組

   算法思想bash

    維護一個有序數組,將要插入的數據與有序數組自最後一個元素直到合適位置的數一一比較。ide

eg: 有序數組:1,3,5,6,7   如今待插入數據爲2,那麼他將會和7,6,5,3,依次做比較,當帶插入數據小於有序數組最後的元素大小,則將該元素後移,直到待插入元素找到合適位置爲止。學習

   代碼實現spa

void InsertSort(int* a, int size)
02
{
03
    assert(a);
04
    for (int i = 0; i < size - 1; ++i)
05
    {
06
        int end = i;                                 //標識有序數組的最後一位
07
        int tmp = a[end + 1];
08
        while (end >= 0 && tmp < a[end])
09
        {
10
            a[end + 1] = a[end];                     //待插入數據比有序數組的最後一個數小,將有序數組最後一位向後移位
11
            --end;
12
        }
13
        a[end + 1] = tmp;
14
    }
15
}

總結orm

wKiom1dAlf6C8SCwAABJqI_Mfjc653.png    1.插入排序能夠認爲是間距爲1的插入算法,說這個是爲了待會兒更好的理解希爾排序。blog

    2.插入排序的時間複雜度爲O(n^2);排序

    3.插入排序的空間複雜度爲O(1);get

    4.具備穩定性


 排序算法的穩定性是指,通過排序算法排序的相同元素的相對位置不會發生改變。

  二.希爾排序

   算法思想

    希爾排序能夠認爲是插入排序的加強版,由於,他加入了一個預排的過程,即在實現間距爲1的插入算法以前,他已經預先將間距爲gap(gap一直減減直到>0)的數組排列過了。因此,當進行gap = 1的插入排序以前使得待排序數組已經高度接近有序,使得此次進行的gap = 1的排序的時間複雜度,能夠小於O(N^2)(gap = 1的插入排序,最好狀況的時間複雜度爲O(1),前面的預排過程正是出於這個目的)。

   代碼實現

//希爾排序
02
void ShellSort(int* a,size_t size)
03
{
04
    assert(a);
05
    int gap = size / 2;
06
    while (gap > 0)
07
    {
08
        for (int i = 0; i < size - gap; ++i)
09
        {
10
            int end = i;                                
11
            int tmp = a[end + gap];
12
            while (end >= 0 && tmp < a[end])
13
            {
14
                a[end + gap] = a[end];                    
15
                end -= gap;
16
            }
17
            a[end + gap] = tmp;
18
        }
19
        --gap;
20
    }
21
}

總結

wKioL1dAmcezLq9UAAA-_4AF_-0959.png 上圖爲gap = 5 的時候的預排效果圖

 1.希爾排序預排的思想和插入排序的思想是一致的,只是,他把原數組分紅不一樣的區間。

 2.希爾排序的時間複雜度爲O(N^2),空間複雜度爲O(1);

 3,具備不穩定性


 三.堆排序

  算法思想

wKiom1dAmjOj5RrrAABza1LyiDI524.png代碼實現

void AdjustDown(int* a, size_t size, int parent)
02
{
03
    assert(a);
04
    int child = parent * 2 + 1;
05
    while (child<size)
06
    {
07
        if (child+1<size && a[child] < a[child + 1])
08
            ++child;
09
        if (a[parent] < a[child])
10
        {
11
            swap(a[parent], a[child]);
12
            parent = child;
13
            child = parent * 2 + 1;
14
        }
15
        else
16
        {
17
            break;
18
        }
19
         
20
    }
21
}
22
void HeapSort(int* a,size_t size)
23
{
24
    assert(a);
25
    //建堆
26
    for (int i = (size - 2) / 2; i >= 0; --i)  //從第一個非葉子節點開始調
27
    {
28
        AdjustDown(a, size, i);
29
    }
30
    for (size_t i = 0; i < size; ++i)
31
    {
32
        swap(a[0], a[size - 1 - i]);
33
        AdjustDown(a, size - i - 1, 0);
34
    }
35
}

總結


 1.時間複雜度爲O(N*lgN),空間複雜度爲O(1);


 2.具備不穩定性




 以上就是本人在學習過程當中的一些經驗總結。固然,本人能力有限,不免會有紕漏,但願你們能夠指正。

相關文章
相關標籤/搜索