【每日N题】大根堆、小根堆

起源:

很久很久以前,1991年计算机先驱奖获得者、斯坦福大学计算机科学系教授罗伯特·弗洛伊德(Robert W.Floyd)和威廉姆斯(J.Williams)在1964年共同发明了著名的堆排序算法( Heap Sort )。

堆定义:

   n个关键字序列Kl,K2,…,Kn称为大根堆,当且仅当该序列满足如下性质:(1)ki>=k(2i)且ki>=k(2i+1)(1≤i≤ n),(即父亲大约儿子)

堆排序:

1)将初始待排序关键字序列(R1,R2....Rn)构建成大顶堆,此堆为初始的无序区;

2)将堆顶元素R[1]与最后一个元素R[n]交换,此时得到新的无序区(R1,R2,......Rn-1)和新的有序区(Rn),且满足R[1,2...n-1]<=R[n]; 

3)由于交换后新的堆顶R[1]可能违反堆的性质,因此需要对当前无序区(R1,R2,......Rn-1)调整为新堆,然后再次将R[1]与无序区最后一个元素交换,得到新的无序区(R1,R2....Rn-2)和新的有序区(Rn-1,Rn)。不断重复此过程直到有序区的元素个数为n-1,则整个排序过程完成。

堆排序特点:

堆排序的时间,主要由建立初始堆和反复重建堆这两部分的时间开销构成,它们均是通过调用Heapify实现的。  

堆排序的最坏时间复杂度为O(nlogn)。堆序的平均性能较接近于最坏性能。  

由于建初始堆所需的比较次数较多,所以堆排序不适宜于记录数较少的文件。  

堆排序是就地排序,辅助空间为O(1)。   

它是不稳定的排序方法。

相关面试应用:

1.海量整数中选取最大的N个;

答:只需建一个具有N个节点的大根堆即可,不停地往里插入节点。

2.设计一个数据结构,其中包含两个函数,1.插入一个数字,2.获得中数。并估计时间复杂度。

答:使用大根堆和小根堆存储。
  使用大根堆存储较小的一半数字,使用小根堆存储较大的一半数字。
  插入数字时,在O(logn)时间内将该数字插入到对应的堆当中,并适当移动根节点以保持两个堆数字相等(或相差1)。

  获取中数时,在O(1)时间内找到中数。


引文:

http://sjjp.tjuci.edu.cn/sjjg/datastructure/ds/web/paixu/paixu8.4.2.2.htm

http://blog.163.com/haitao5782038@126/blog/static/5098692420123951148957/

http://baike.baidu.com/view/157305.htm

你可能感兴趣的:(面试题)