考研資料結構筆記—堆排序

來源:互聯網
上載者:User

標籤:全域   i+1   堆排序   strong   演算法   子節點   選擇   完全   記錄   

完全二叉樹是效率很高的資料結構,堆是一種完全二叉樹或者近似完全二叉樹,所以效率同樣極高。目前十分常用的排序演算法、Dijkstra演算法、Prim演算法等都要用堆才能最佳化。

堆排序是一種選擇排序演算法,與原序列的初始排列次序無關,即最好、最壞和一般情況排序的時間複雜度不變,均為O(nlgn)。而且,堆排序只需要一個記錄記錄元素大小的輔助空間(供交換使用),故空間複雜度為O(1)。正由於堆排序不僅時間複雜度小,而且空間複雜度O(1)也是最小,所以是用於排序的最佳選擇。

堆的定義

n個元素序列 { k0,k1,..., kn } 若且唯若滿足下列條件之一時,稱之為堆(其中 i = 0, 1, ..., n/2 向下取整)。

  • ki <= k2i+1 且 ki <= k2i+2(最小堆)
  • ki >= k2i+1 且 ki >= k2i+2(最大堆)

堆排序實現

方法1:

利用最小堆性質實現堆排序

/*交換數組中兩個元素的值*/void swap(int *arr, int a, int b){    int temp = arr[a];    arr[a] = arr[b];    arr[b] = temp;}/*(小根)堆調整*/void minHeapify(int *arr, int heapSize, int curNode){    /*找出當前節點和其左右節點三者的最小值*/    int minNode = curNode;      int left  = curNode * 2 + 1;    int right = curNode * 2 + 2;    if(left < heapSize && arr[left] < arr[minNode]) //左孩子存在且較小        minNode = left;    if(right < heapSize && arr[right] < arr[minNode]) //右孩子存在且較小        minNode = right;    if(minNode != curNode)    //當前節點不是最小則需要交換    {           swap(arr, minNode, curNode);        minHeapify(arr, heapSize, minNode);  //子節點需重新調整    }}/*構建堆*/void createHeap(int *arr, int heapSize){    for(int i = heapSize/2 - 1; i >= 0; i--)  //從最後一個非分葉節點開始    {        minHeapify(arr, heapSize, i);    }}/*(最小)堆排序*思想:*1、構建最小堆*2、從最後一個元素開始只第二個元素將依次與首元素交換*3、全域調整堆
*上面步驟2和步驟3將所有元素都與首元素交換,然後進行全域範圍的堆調整,利用最小堆的性質實現將所有元素按從小到大的方式排序
*/void heapSort(int *arr, int length){ createHeap(arr, length); //構建堆 for(int i = length-1; i > 0; i--) { swap(arr, 0, i); //與首元素交換 minHeapify(arr, length, 0); //調整堆 }}

 方法2

利用最大堆性質實現堆排序

/*交換數組中兩個元素的值*/void swap(int *arr, int a, int b){    int temp = arr[a];    arr[a] = arr[b];    arr[b] = temp;}/*(大根)堆調整*/void maxHeapify(int *arr, int heapSize, int curNode){    /*找出當前節點和其左右節點三者的最小值*/    int maxNode = curNode;      int left  = curNode * 2 + 1;    int right = curNode * 2 + 2;    if(left < heapSize && arr[left] > arr[maxNode]) //左孩子存在且較小        maxNode = left;    if(right < heapSize && arr[right] > arr[maxNode]) //右孩子存在且較小        maxNode = right;    if(maxNode != curNode)    //當前節點不是最小則需要交換    {           swap(arr, maxNode, curNode);        maxHeapify(arr, heapSize, maxNode);  //子節點需重新調整    }}/*構建堆*/void createHeap(int *arr, int heapSize){    for(int i = heapSize/2 - 1; i >= 0; i--)  //從最後一個非分葉節點開始    {        maxHeapify(arr, heapSize, i);    }}/*(最大)堆排序*思想:*1、構建最大堆*2、從最後一個元素開始只第二個元素將依次與首元素交換*3、進行數組中當前元素前面的所有元素的局部調整堆*上面步驟2和步驟3將所有元素都與首元素交換,將局部範圍內的最大值沉到後面,然後進行當前元素前面所有元素的局部範圍內的堆調整*即在數組A中,當前元素索引為i,將A[i]與A[0]交換,將A[0,1,...,i]中最大的值放到A[i],然後進行A[0,1,...,i-1]堆調整,*將A[0,1,...,i-1]內的最大值放到A[0]中,待下一次交換使用,實現將局部的最大值依次沉到數組後面,完成排序*/void heapSort(int *arr, int length){    createHeap(arr, length);  //構建堆    for(int i = length-1; i > 0; i--)    {           swap(arr, 0, i);  //與首元素交換        maxHeapify(arr, i, 0);  //調整堆    }}

 

考研資料結構筆記—堆排序

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.