我正在阅读Cormen的算法书中的堆排序章节,但却不理解下面的陈述:
在大多数计算机上,LEFT过程可以计算2i 通过简单地移动i左边的二进制表示来进行指令 一位的位置。
类似地,RIGHT程序可以通过移位快速计算2i + 1 i的二进制表示由一位位置然后离开 添加1作为低位。 PARENT程序可以计算 [i / 2]通过向右移动一位位置。良好的实施 heapsort经常将这些过程实现为“宏”或“内联” 程序
这里的LEFT程序是什么,以及如何进行计算。
同样如何计算RIGHT程序& PARENT。
使用宏或内联过程实现过程意味着什么。
从很多人那里我开始知道这是学习算法的最佳书籍,但我无法理解作者在这里要解释的内容。
答案 0 :(得分: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.这适用于两个孩子,因为最右边的位将被切断。
现在到宏和&排队。内联是一些编程语言中的一种方法(例如我在c ++中学习它),它告诉编译器他应该评估是否可以加速给定的任务。这对于非常简单的任务非常有用,这种任务也经常发生(因为你的左右移动任务是)。这是有道理的,因为这样的基本算法必须非常高效,因为你必须处理的节点越多,它就越慢。 宏几乎是相同的,只是保存了一个将被执行多次的任务。
您可以谷歌更好地理解的一些短语: 左移位操作 内联方法c ++
祝福,
ESSI
答案 1 :(得分:1)
parent
,left
和right
程序是获取parent
,left
和right
元素的简单计算当前元素(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过程只需将i左边的二进制表示移位一位,即可在一条指令中计算2i。
类似地,RIGHT过程可以通过将i左边的二进制表示移位一位位置然后加1作为低位来快速计算2i + 1。 PARENT过程可以通过向右移位一位位置来计算[i / 2]。良好的heapsort实现通常将这些过程实现为“宏”或“内联”过程。
这描述了处理器级别这些功能的复杂性。要点是parent
,left
和right
通常可以在处理器上的一个或两个指令中执行。
inline procedures上的评论描述了编译器优化。如果编译器自己编写汇编代码,编译器通常会产生比人类更多的汇编指令。所以这个评论只是说(parent
,left
和right
)过程可以编译成单个(或几个)指令,假设正确的编译器优化可用。< / p>
如果您试图了解这些程序在处理器级别实际运行的方式,您可以阅读bit shifting(或阅读其他答案)。