Sorting heapsort的速度和内存分析

Sorting heapsort的速度和内存分析,sorting,big-o,heapsort,Sorting,Big O,Heapsort,我试着用谷歌和维基搜索这些问题,但似乎找不到具体的答案。我发现的大部分内容都涉及到使用主定理的证明,但我希望用简单的英语能更直观地记住一些东西。此外,我不在学校,这些问题是为了面试 内存: 根据内存使用情况确定big-o到底意味着什么?例如,当您必须存储所有n个项目时,为什么认为heapsort使用O(1)内存运行?是否因为您只为堆创建了一个结构?或者是因为您知道它的大小,所以可以在堆栈上创建它,这始终是恒定的内存使用 速度: 如果添加元素是在O(1)中完成的,而渗透是在O(logn)中完成的,

我试着用谷歌和维基搜索这些问题,但似乎找不到具体的答案。我发现的大部分内容都涉及到使用主定理的证明,但我希望用简单的英语能更直观地记住一些东西。此外,我不在学校,这些问题是为了面试

内存:

根据内存使用情况确定big-o到底意味着什么?例如,当您必须存储所有n个项目时,为什么认为heapsort使用O(1)内存运行?是否因为您只为堆创建了一个结构?或者是因为您知道它的大小,所以可以在堆栈上创建它,这始终是恒定的内存使用

速度:

如果添加元素是在O(1)中完成的,而渗透是在O(logn)中完成的,那么堆的创建是如何在O(n)时间内完成的?这难道不意味着在O(1)处插入n个元素,使其成为O(n),并在每次插入后渗透为O(logn)。所以O(n)*O(logn)=O(nlogn)总计。我还注意到,大多数堆排序的实现都使用heapify函数而不是渗透来创建堆?由于heapify不在O(logn)处进行n次比较,这将是O(nlogn),并且在O(1)处插入n次,我们将得到O(n)+O(nlogn)=O(nlogn)?对于较小的n,第一种方法不会比第二种方法产生更好的性能吗


我在上面假设了这一点,但是做一个O(1)运算n次会导致O(n)时间是真的吗?或者n*O(1)=O(1)?

所以我从维基百科中找到了一些关于构建二进制堆的有用信息:

我认为我的主要困惑源于如何将O(1)和O(logn)同时“插入”到堆中,尽管第一个不应该称为插入,可能只是构建步骤或其他什么。因此,在创建堆之后,不再使用heapify,而是使用O(logn)插入方法

在维护heap属性的同时迭代添加项的方法在O(nlogn)中运行,在不考虑heap属性的情况下创建heap,然后heapizing,实际上在O(n)中运行,原因不是很直观,需要证明,所以我错了

在每个方法都有一个尊重heap属性的堆之后,获取有序项的删除步骤的成本是相同的O(nlogn)


因此,对于构建堆方法,最终将有一个O(1)+O(n)+O(nlogn)=O(nlogn),对于插入方法,将有一个O(nlogn)+O(nlogn)=O(nlogn)。显然,第一种更可取,尤其是对于小n.

存储器通常被表示为O(1)额外存储器。也就是说,恒定内存不计算正在排序的对象本身。第二个问题,为什么是O(1)?您需要为堆中的所有n项分配内存,这不应该是O(n)吗?请注意“附加”一词。项目本身的内存不作为“附加”的一部分计算。想象一下,有人说“这辆车的价格是20000美元,再加上1000美元,我们就可以加上GPS导航。”然后你说“怎么可能只有2000美元?就汽车本身的价格是20000美元!”2000美元是额外的费用;这还不包括汽车本身的基本费用20000美元。类似地,O(1)是附加内存使用,不计算项目本身的内存。哦,好的,如果我们在C++中考虑,堆不会重新分配n个指针,并将数据从原始项目复制到它们。相反,它只是将堆使用的指针设置为已经存在的指针?这就是他们所说的“就地”的意思。我认为在深入研究算法细节之前,你应该先熟悉术语。