Algorithm Cormen&x27;s堆排序结构

Algorithm Cormen&x27;s堆排序结构,algorithm,Algorithm,我正在阅读《科曼算法》一书中的堆排序一章,但我一直在理解以下语句: 在大多数计算机上,左过程可以一次计算2i 只需将i的二进制表示形式左移 一位位置 类似地,正确的程序可以通过移位快速计算2i+1 i的二进制表示左移一位,然后 添加1作为低阶位。父过程可以计算 [i/2]通过将i向右移动一位位置。的良好实现 heapsort通常将这些过程实现为“宏”或“内联” 程序 这里剩下的步骤是什么,以及计算是如何完成的 类似地,它是如何为正确的程序和父级计算的 使用宏或内联过程实现过程意味着什么 从这

我正在阅读《科曼算法》一书中的堆排序一章,但我一直在理解以下语句:

在大多数计算机上,左过程可以一次计算2i 只需将i的二进制表示形式左移 一位位置

类似地,正确的程序可以通过移位快速计算2i+1 i的二进制表示左移一位,然后 添加1作为低阶位。父过程可以计算 [i/2]通过将i向右移动一位位置。的良好实现 heapsort通常将这些过程实现为“宏”或“内联” 程序

这里剩下的步骤是什么,以及计算是如何完成的

类似地,它是如何为正确的程序和父级计算的

使用宏或内联过程实现过程意味着什么


从这么多人那里,我知道这是学习算法最好的一本书,但我无法理解作者试图在这里解释的内容。

如果你看一下节点2的二进制表示形式,它是0000 0010(为了可读性,我在4位后拆分)。左移位意味着所有位都将取代它们左边的位,并且每个没有右邻位的位将得到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++

致以最良好的祝愿


ESI父元素
左元素
右元素
过程是一个简单的计算过程,在给定当前元素(在
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过程可以快速计算2i+1,方法是将i的二进制表示左移一位,然后加上1作为低阶位。父过程可以通过将i向右移动一位位置来计算[i/2]。heapsort的良好实现通常将这些过程实现为“宏”或“内联”过程

这是在处理器级别描述这些函数的复杂性。要点是,
parent
left
right
通常可以在处理器上的一条或两条指令中执行

上的注释描述了编译器优化。编译器通常会生成比人类自己编写汇编代码所生成的汇编指令更多的汇编指令。因此,该评论只是说(
父级
、和
)过程可以编译为单个(或多个)指令,前提是可以使用正确的编译器优化


如果您想了解这些过程实际上是如何在处理器级别运行的,您可以阅读(或阅读其他答案)。

Random旁白:我实际上不建议从CLR学习算法。这是一本关于算法的很棒的第二本书,但是它的很多解释都是技术和数学的。你可能想看看Kleinberg和Tardos的“算法设计”,我过去用过,认为它在激励方面做得更好。