【发布时间】:2021-12-31 02:26:48
【问题描述】:
我知道如何使用归并排序对链表进行排序。问题是,我们为什么不直接使用堆来创建排序的 LinkedList?
- 遍历链表并不断将项目添加到最小堆中。
- 继续从堆中取出项目并堆化堆并添加到新结果 LinkedList。
第一步将有 O(n) 用于遍历列表,O(nlogn) 用于将项目添加到堆中。总计O(nlogn)[有错请指正]。
从堆中取出一个项目是O(1) 添加一个项目作为LinkedList 中的下一个节点是O(1)。 [如有错误请指正]。
所以如果我的理解是正确的,可以在O(nlogn) 中进行排序。这与归并排序相同。在内存方面,我们使用了一个额外的堆,所以我假设总内存可以是O(nlogn)。合并排序也可以采用O(nlogn),但可以改进为O(logn)。
堆逻辑同“合并k个有序链表”。我假设每个链表都有 1 个项目。
对于堆版本的复杂性,我可能完全错了。如果有人知道为什么不应该[为什么合并排序更好]使用堆的确切原因,请解释。这不是堆排序,也不是就地算法。如果时间复杂度是O(n²logn),不知道怎么弄。
【问题讨论】:
-
我没有完全遵循,但我认为您所说的是“枚举链表元素并将每个元素插入二叉树。然后通过对树进行有序遍历来重建列表。这没什么问题。它只是不是合并排序。
-
@selbie 是的,就是这样。因为我有一个最小堆,所以我总是会得到最低的值。在书中,我看到我们无法使用快速排序或堆排序对单链表进行排序。所以很好奇为什么我们不只是用堆排序。如果我对复杂性的理解是正确的,不如堆排序有效,但不会比合并排序差。
-
您说的是为堆创建一个全新的、独立的结构?所以要设置一些额外的编程时间而不会提高性能?
-
“如果有人知道不应该使用堆的确切原因”:谁说不应该使用它?来源?
-
诸如“不要使用堆对链表进行排序”这样的分类语句是完全错误的。
标签: c# c++ c algorithm sorting