2017-03-08 87 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