淺解前端必須掌握的演算法(五) 堆排序(上)

2021-09-11 09:31:20 字數 2311 閱讀 6194

另外,掌握了一些基本的演算法實現,對於我們日常開發來說,也是如虎添翼,能讓我們的 js 業務邏輯更趨高效和流暢。

今天這個演算法稍微比較複雜,牽扯到的概念也比較多,需要先了解基礎知識。我給每篇文章的定位是 10 分鐘內應該要掌握下來,所以我就擅作主張地將堆排序演算法講解分割為上、下兩篇文章了,希望能讓大家閱讀起來更清爽愉快。

要了解堆,必須先了解一下二叉樹,兩者關係在下一步闡述。

二叉樹(binary tree)是每乙個節點最多有兩個分支的樹結構,通常分支被稱作「左子樹」和「右子樹」,分支具有左右次序,不能隨意顛倒。

二叉樹第i層最多擁有2^(i-1)個節點,深度為k的二叉樹最多共有2^(k+1)-1個節點,且定義根節點所在的層級i=0,所在的深度k=0。注意該定義在全文起作用,後續不繼續提及。

二叉樹示意圖

假設某個二叉樹深度為k,第i層擁有2^(i-1)個節點,且總共擁有2^(k+1)-1個節點,這樣的二叉樹稱為「滿二叉樹」。

換句話說,二叉樹的每一層都是滿的,除了最後一層上的節點,每乙個節點都具有左節點和右節點。

滿二叉樹示意圖

假設某個二叉樹深度為k,共有n個節點,當且僅當其中的每乙個節點,都可以和同樣深度為k的滿二叉樹上的,按層序編號相同的節點,也就是序號為1n的節點,均一一對應時,這樣的二叉樹稱為「完全二叉樹」。

滿二叉樹一定是完全二叉樹,但是完全二叉樹不一定是滿二叉樹。

完全二叉樹示意圖

如下的就不是完全二叉樹,樹 1 中 10 號節點缺失,樹 2 中 6、7 號節點缺失,樹 3 中 10、11 號節點缺失。

不是完全二叉樹示意圖

堆(heap),一類特殊的資料結構的統稱,通常是乙個可以被看做一棵樹的陣列物件。

堆的實現通過構造二叉堆(binary heap),實為二叉樹的一種,由於其應用的普遍性,當不加限定時,均指該資料結構的這種實現。

堆,是完全二叉樹。

堆和陣列相互關係示意圖

對於給定的某個節點的下標idx,可以很容易地計算出這個節點的父節點與孩子節點的下標:

// 計算父節點的下標

var getparentpos = function(idx)

// 計算左子節點的下標

var getleftchildpos = function(idx);

// 計算右子節點的下標

var getrightchildpos = function(idx);

複製**

如下圖,取下標idx = 4的節點,則其父節點的下標就為math.floor(4/2) === 2,其左子節點的下標就為2*4 === 8,其右子節點的下標就為2*4 + 1 === 9

計算親屬節點位置示意圖

但將堆轉換為陣列時,由於陣列的初始化下標始終為0,所以我們的堆資料結構模型在此時要發生如下改變:

改變資料結構模型示意圖

同樣的,以上的演算法也需要做一下微調:

// 計算父節點的下標

var getparentpos = function(idx)

// 計算左子節點的下標

var getleftchildpos = function(idx);

// 計算右子節點的下標

var getrightchildpos = function(idx);

複製**

二叉堆一般分為兩種:「大頂堆」和「小頂堆」。

假設有乙個堆,其中每個節點的值都大於或等於其左右孩子節點的值,則該堆稱為「大頂堆」。「大頂堆」的最大元素值出現在根節點。

大頂堆示意圖

假設有乙個堆,其中每個節點的值都小於或等於其左右孩子節點的值,則該堆稱為「小頂堆」。「小頂堆」的最小元素值出現在根節點。

小頂堆示意圖

覺得本文不錯的話,分享一下給小夥伴吧~

淺解前端必須掌握的演算法(一) 氣泡排序

雖然前端面試中很少會考到演算法類的題目,但是你去大廠面試的時候就知道了,對基本演算法的掌握對於從事計算機科學技術的我們來說,還是必不可少的,每天花上 10 分鐘,了解一下基本演算法概念以及前端的實現方式。另外,掌握了一些基本的演算法實現,對於我們日常開發來說,也是如虎添翼,能讓我們的 js 業務邏輯...

整理排序演算法(五) 堆排序

堆排序 大頂堆 將記錄看成乙個順序儲存的二叉樹 先構建大頂堆,所有節點都比他的兒子大或者等於。第一步 從最後乙個非葉子節點開始比較,一直到根。構建大頂堆成功。第二步 根與最後的葉子節點交換位置 第三步 除去剛才的葉子節點,再次構建大頂堆,這個時候構建大頂堆只要從上往下層級遍歷就好。演算法效能 堆排序...

演算法導論之五堆排序

堆排序的時間複雜度是,與插入排序相似,堆也具有空間原址性,即任何時候都只需要常數個額外的元素空間儲存臨時資料。1.堆簡介 1 堆是乙個陣列,表示堆的陣列a包括兩個屬性 a.length表示陣列元素的個數,a.heap size表示有多少個堆元素儲存在該陣列中。給定一結點的下標i,可以得到其父結點 左...