日本免费高清视频-国产福利视频导航-黄色在线播放国产-天天操天天操天天操天天操|www.shdianci.com

學無先后,達者為師

網站首頁 編程語言 正文

C語言數據結構之堆排序詳解_C 語言

作者:清歡有道 ? 更新時間: 2022-05-13 編程語言

1.堆的概念及結構

如果有一個關鍵碼的集合K = {k0,k1, k2,…,kn-1},把它的所有元素按完全二叉樹(二叉樹具體概念參見——二叉樹詳解)的順序存儲方式存儲在一個一維數組中,并滿足:Ki <= K2i+1 且 Ki<= K2i+2 (Ki >= K2i+1 且 Ki >= K2i+2) i = 0,1,2…,則稱為小堆(或大堆)。將根節點最大的堆叫做最大堆或大根堆,根節點最小的堆叫做最小堆或小根堆。

堆的性質:

  • 堆中某個節點的值總是不大于或不小于其父節點的值;
  • 堆總是一棵完全二叉樹。

2.堆的實現

堆的實現請參見——二叉樹詳解(堆的實現)

2.1 堆的向下調整算法

(此文章都已建小堆為例)

向下調整算法前提:當前樹左右子樹都是小堆

核心思想:選出左右孩子中小的那個,和父親交換,小的往上浮,大的往下沉,這里是小堆,如果是大堆則相反。

代碼實現

void swap(int *x, int *y)
{
    int temp = *x;
    *x = *y;
    *y = temp;
}
//堆向下調整算法
void AdjustDown(int *a, int n, int root)
{
    int parent = root;
    int child = parent * 2 + 1;
    while (child a[child + 1] && child+1 < n)
            ++child;
        if (a[child] < a[parent])
        {
            swap(&a[child], &a[parent]);
            parent = child;
            child = parent * 2 + 1;
        }
        else
            break;
    }
}

2.2 堆的向上調整算法

使用場景:向上調整算法適用于向堆中插入數據,當向堆中插入數據就可能會導致堆失去大堆或者小堆的性質,此時需要重新調整,向上調整的思路與向下調整算法的思路類似,向上調整算法只需要從插入結點位置開始和父節點比較。

圖示:

代碼實現:

void AdjustUp(int *a, int child)
{
    int parent = (child - 1) / 2;
    while (child > 0)
    {
        if (a[parent] > a[child])
        {
            swap(&a[parent], &a[child]);
            child = parent;
            parent = (child - 1) / 2;
        }
        else
            break;
    }
}

2.3 建堆(數組)

從最后一個非葉子節點位置行依次開始調整,如圖:

代碼實現:

int parent = (n-2) / 2;
    //首先對每一個非葉子節點進行一次向下調整算法,保證每個非葉子節點的
    //孩子都小于它的父節點,然后可得到最小值,就在堆的頂端的父節點(也叫做建小堆)
    while (parent >= 0)
    {
        AdjustDown(a, n, parent);
        --parent;
    }

2.4 堆排序

升序建大堆,降序建小堆

void HeapSort(int *a, int n)
{
    int parent = (n-2) / 2;
    //首先對每一個非葉子節點進行一次向下調整算法,保證每個非葉子節點的
    //孩子都小于它的父節點,然后可得到最小值,就在堆的頂端的父節點(也叫做建小堆)
    while (parent >= 0)
    {
        AdjustDown(a, n, parent);
        --parent;
    }
    int end = n-1;
    while (end>0)
    {
        //將堆頂的數與最后的end,以此循環,進行交換就可得到有序序列
        //注意:建小堆,得到降序序列
        swap(&a[end], &a[0]);
        AdjustDown(a, end, 0);
        --end;
    }
}

2.5 堆排序的時間復雜度

所以建堆時間復雜度為O(N);

向下調整算法時間復雜度 O(logN);

所以堆排序的時間復雜度為 O(N*logN)

原文鏈接:https://blog.csdn.net/weixin_45796387/article/details/120461189

欄目分類
最近更新