算法系列--堆

0.引言

堆是一種比較常見的數據結構,堆排序也是面試時會常常遇到的問題,今天就分析一下堆。面試

1.堆結構

堆是一種相似於樹的數據結構,父節點和子節點之間存在必定的關係,子節點的數量根據堆的類型來決定,最長見得就是每一個父節點最多兩個子節點的二叉堆。api

如圖所示,咱們用一個數組類模擬二叉樹以構建二叉堆,從圖能夠看出,堆是從數組的1開始而不是0開始,這主要就是爲了構建子節點和父節點的關係,咱們能夠很清楚的看到這種關係:leftNodeIndex=rootIndex2; rightNodeIndex=rootIndex2+1。 咱們還能夠發現這個堆的父節點都是大於其子節點的,這就是一個最大堆,能夠用來進行從小到大的堆排序。數組

2.構建最大堆

構建最大堆,首先明確一個規則,堆的葉子節點的位置,假設堆的數量爲N=7; 那麼它的葉子節點就是 N/2+1,N/2+2,N/2+3,N/2+4,如圖所示:數據結構

那麼如今假設給了一個堆數組,構建成一個最大堆,從葉子節點的上一層節點開始直到根節點進行最大堆化操做

void build_maxheap (int Arr[ ])
{
    for(int i = N/2 ; i >= 1 ; i-- )
    {
        max_heapify (Arr, i) ;
    }
}


void max_heapify (int Arr[ ], int i, int N)
{
    int left = 2*i                   //left child
    int right = 2*i +1           //right child
    if(left<= N and Arr[left] > Arr[i] )
          largest = left;
    else
         largest = i;
    if(right <= N and Arr[right] > Arr[largest] )
        largest = right;
    if(largest != i )
    {
        swap (Arr[i] , Arr[largest]);
        max_heapify (Arr, largest,N);
    } 
 }
複製代碼

max_heapify就是遞歸的將父節點和左右子節點進行大小比較,將較大的值放到父節點的位置。下圖演示了一個構建最大堆的過程ui

最小堆和最大堆相反,就是根節點是小於子節點的,只要將max_heapify稍加改造就能夠了,就再也不贅言了。

3.堆排序

說到應用了,若是給定了一個無序的數組按照從小到大排序,那麼咱們就能夠利用最大堆的性質在O(NlogN)的時間複雜度內進行排序。 堆排序通常按照以下步驟: 1.構建最大堆。 2.交換第一個元素和最後一個元素的位置。 3.從根節點開始,進行堆最大化操做(max_heapfy),注意此時待排序節點的個數爲N-1,由於第二步的時候已經排序好一個值了。 4.重複2,3步驟直到排序完成。 若是是從大到小排序,那麼就用最小堆。 排序過程入下圖:spa

void heap_sort(int Arr[ ])
{
    int heap_size = N;
    build_maxheap(Arr);
    for(int i = N; i>=2 ; i-- )
    {
        swap(Arr[ 1 ], Arr[ i ]);
        heap_size = heap_size-1;
        max_heapify(Arr, 1, heap_size);
    }
}
複製代碼

至此堆的基礎知識就差很少了。3d

關注個人公衆號: code

相關文章
相關標籤/搜索