2017-03-08 89 views
-1

我會通過Cormen的算法書的堆排序章,但被困在理解下面的語句:Cormen的堆排序結構

enter image description here

enter image description here

在大多數計算機上,左程序可以通過簡單地將我離開的二進制表示移位 一位位置來在一個 指令中計算2i。

類似地,RIGHT過程可以通過將i的二進制表示向左移一位來快速計算2i + 1,然後 加1作爲低位。通過向右移動一個位位置,PARENT程序可以計算出 [i/2]。良好的堆排序實現通常將這些過程實現爲「宏」或「內聯」過程。

什麼是這裏的LEFT程序,以及如何完成計算。

同樣如何計算RIGHT程序&父母。

這是什麼意思,這些過程是使用宏或內聯過程實現的。

從很多人那裏我都知道這是學習算法的最好的書,但是我不能理解作者在這裏試圖解釋什麼。

+2

隨機放在一邊:我實際上會*不推薦從CLRS學習算法。這是關於算法的第二本書,但其中很多解釋都是技術性和數學性的。您可能想查看Kleinberg和Tardos的「算法設計」,這是我過去使用過的,並且認爲它能更好地激勵事物。 – templatetypedef

回答

1

parentleft,並right手續簡單計算得到parentleftright元素,給出當前元素(在i處)。

家長i/2

地板2i

2i + 1


考慮您提供的例子。 通常數組基於0,但您的示例似乎是基於1的。

我們有一個數組,稱之爲A,其中A = [16, 14, 10, 8, 7, 9, 3, 2, 4, 1]

比方說,我們正在尋找A[3]是10 使用上述計算,A[3]的母公司是A[1]這是16 A[3]的左孩子是A[6]這是9 A[3]的右孩子A[7]這是3.


在大多數計算機,則LEFT程序可以通過簡單地移動的二進制表示計算2I在一個指令i的左移一個位的位置。

類似地,RIGHT過程可以快速計算2i + 1,方法是將左邊的二進制表示移位一位,然後將1加爲低位。 PARENT程序可以通過向右移動一個位位置來計算[i/2]。 heapsort的良好實現經常將這些過程實現爲「宏」或「內聯」過程。

這是描述在處理器級別這些功能的複雜性。要點是parentleftright通常可以在處理器上的一個或兩個指令中執行。

關於inline procedures的評論正在描述編譯器優化。如果編譯器本身編寫彙編代碼,編譯器通常會生成比人類更多的彙編指令。所以這個評論只是說假設正確的編譯器優化可用,那麼(parentleftright)過程可以被編譯爲單個(或幾個)指令。

如果您想了解這些過程如何在處理器級別上實際運行,那麼您可以閱讀bit shifting(或閱讀其他答案)。

1

如果你看看節點#2的二進制表示,它是0000 0010(爲了可讀性我在4位之後分割)。左移意味着所有位代替它們左邊的位,並且每個沒有正確的neigbor的位將得到0.因此,例如0000 0001將得到0000 0010,並且您的節點# 2將是0000 0100.你是否看到最右邊的位現在是零?此外,二進制表示0000 0100是4,節點#2的左側子節點具有完全相同的數字。

如果你明白了,其餘的很容易。帶+1的左移將0000 0010(2)更改爲0000 0101(5)。所以這是正確的孩子的節點號碼。

有點棘手的是父母,因爲你會從表示中刪除一些東西。如果你想獲得節點#3 0000 0011的父節點,你將向右移動一次,所以它變成0000 0001,它是1.這對兩個孩子都適用,因爲最右邊的位將被切斷。

現在爲宏&內聯。 Inline是一些編程語言中的一種方法(例如,我通過C++學習它)告訴編譯器,他應該評估他是否可以加速執行任務。這對於經常發生的非常簡單的任務來說也是非常有用的(因爲你的左邊的&右移任務是)。這是有道理的,因爲這樣的基本算法必須非常有效,因爲你需要處理的節點越多,處理速度就越慢。 宏幾乎是相同的,只是一個任務將被執行多次保存。

一些短語,你可以谷歌更好地理解: 左移位運算 內聯方法C++

最良好的祝願,

ESSI