一、演算法介紹
堆排序(heapsort)是指利用堆積樹(堆)這種
資料結構
所設計的一種
排序演算法
,它是選擇排序的一種。可以利用
陣列的特點快速定位指定索引的元素。堆分為大根堆和小根堆,是
完全二叉樹
。大根堆的要求是每個節點的值都不大於其父節點的值,即
a[parent[i]] >= a[i]。
在陣列的非降序排序中,需要使用的就是大根堆,因為根據大根堆的要求可知,最大的值一定在堆頂
。二、演算法說明
本文以大根堆為例來說明,假設要排序的陣列為a,陣列大小為n
i的兒子節點為2*i+1 , 2*i+2
演算法主要分為兩個部分:
1.建立大根堆,然而建立的大根堆只能保證本身的特性(
每個節點的值都不大於其父節點的值
),並沒有辦法保證自身按照層次遍歷的元素是有序的。
從a[n/2-1](從結尾開始第乙個有兒子的節點)到根節點開始調節陣列(完全二叉樹),形成乙個大根堆
2.大根堆能保證根節點一定是整個樹當中最大的,因此排序就可以這麼來安排:
將a[0]與a[n-1]進行交換,然後將a[0]到a[n-2]重新進行關於大根堆的調整
將a[0]與a[n-2]進行交換,然後將a[0]到a[n-3]重新進行關於大根堆的調整
。。。重複這個過程
第一次交換的過程中,取出陣列第一大的數放在最後
第二次交換的過程中,取出陣列第二大的數放在最後
。。。迴圈之後就完成了排序的過程
三、複雜度
空間複雜度
因為堆排序是就地排序,空間複雜度為常數:o(1)
四、示例**
如果還是不怎麼懂的同學,**run一下 通過輸出的樹狀結構更容易理解
public class stacksort ;
sort(a);
}//堆排需方法
public static void sort(int a)
system.out.println("---------------------------------------");
for (int i = n - 2; i >= 0; i--)
display(a, "after sort : ");
}/**
* 調整堆的方法
* 每次呼叫的目的就是調節傳入的a[i]值 使得它在整個堆中處於正確的位置
* @param a 要調整的陣列,即堆
* @param i 調整的根節點,即起始位置
* @param n 要調整的終止位置
*/public static void adjust(int a, int i, int n)
a[(j - 1) / 2] = temp;//將根節點賦值給最後乙個空出來的節點
}//以圖形形式表現二叉樹
public static void display(int a, string str)
++count;
}system.out.printf("%3s",a[i]);
num = (int)math.pow(2,h-count+1);
for(int j = 0 ; j < num-1 ; j++)
}system.out.print("\n");
}}
**內容來自
整理而成
時間複雜度
演算法系列之一 堆排序
前序 二叉 堆資料結構是一種陣列物件,它可以被視為一棵完全二叉樹。樹中每個節點與陣列中存放該節點值的那個元素對應。樹的每一層都是填滿的,最後一層除外。樹的根為a 1 在這裡是從1開始的,也可以從0開始 給定了某個節點的下標i,其父節點為i 2,左二子為2 i,右兒子為2 i 1。二叉堆滿足二個特性 ...
常用排序演算法總結7一一堆排序
在了解堆排序之前,我們有必要清楚 什麼是堆呢?堆 英語 heap 是電腦科學中一類特殊的資料結構的統稱。堆通常是乙個可以被看做一棵樹的陣列物件。在佇列中,排程程式反覆提取佇列中第乙個作業並執行,因為實際情況中某些時間較短的任務將等待很長時間才能結束,或者某些不短小,但具有重要性的作業,同樣應當具有優...
演算法 堆排序(堆)
使用情形 插入乙個數 求集合當中的最小值 刪除最小值 刪除任意乙個元素 修改任意乙個元素 用一維陣列儲存二叉樹,左兒子在陣列中為根節點在陣列中的位置的2倍,右兒子在陣列中為根節點在陣列中的位置的二倍加一。求當前堆的最小值 void down int u 輸入乙個長度為n的整數數列,從小到大輸出前m小...