本站消息

  出租广告位,需要合作请联系站长

  今日名言-想象你自己对困难作出的反应,不是逃避或绕开它们,而是面对它们,同它们打交道,以一种进取的和明智的方式同它们奋斗 。——马克斯威尔·马尔兹

  今日名言-用谅解、宽恕的目光和心理看人、待人。人就会觉得葱笼的世界里,春意盎然,到处充满温暖。——蔡文甫


+关注
已关注

分类  

暂无分类

标签  

暂无标签

日期归档  

暂无数据

《黑马程序员》—堆的定义

发布于2021-07-24 21:15     阅读(1180)     评论(0)     点赞(2)     收藏(4)


堆的定义

堆可以被看做是一颗完全二叉树的数组对象

完全二叉树:往左边填结点,只有左边不满的时候才往右边填。

堆的具体实现方法:将二叉树的结点按照层级顺序放入数组中,根结点在位置1,它的子结点在位置23,而子结点的子结点则分别在位置4,5,67

如果一个结点的位置为 k ,则它的父结点的位置为 [k/2](向下取整), 而它的两个子结点的位置则分别为 2k2k+1
规定: 每个结点都大于等于它的两个子结点。这里要注意堆中仅仅规定了每个结点大于等于它的两个子结点,但这两个 子结点的顺序并没有做规定,跟二叉查找树是有区别的。

堆的API实现

注:
(1)如果 往堆中新插入元素,只需要不断的比较新结点a[k]和它的父结点a[k/2]的大小,然后根据结果完成数据元素的交换 ,就可以完成堆的有序调整。(如果父节点的值比当前结点的值小,则交换位置
(2)如果 往堆中删除最大元素 ,第一个元素就是最大元素,删除掉后。将最后一个元素放到索引1处,然后不断的拿 当前节点a[k]和它的子节点a[2k]和a[2k+1]中较大者交换位置
  1. public class Heap<T extends Comparable<T>>{
  2. //存储堆中的元素
  3. private T[] items;
  4. private int N;
  5. public Heap(int capacity){
  6. this.items = (T[]) new Comparable[capacity+1]; //因为数组下标0没有使用
  7. this.N = 0;
  8. }
  9. //判断堆中索引i处的元素是否小于索引j处的元素
  10. private boolean less(int i, int j){
  11. return items[i].compareTo(items[j])<0;
  12. }
  13. // 交换堆中i索引和j索引处的值
  14. private void exch(int i, int j){
  15. T temp = items[i];
  16. items[i] = items[j];
  17. items[j] = temp;
  18. }
  19. // 往堆中插入一个元素
  20. public void insert(T t){
  21. //因为一开始N=0,这样第一个插入的元素就在items[1],
  22. items[++N]=t;
  23. //需要调整元素位置,让堆有序(每个结点都大于其两个子结点)
  24. swim(N);
  25. }
  26. // 使用上浮算法,使索引k处的元素能在堆中处于一个正确的位置
  27. // 不断和父节点比较
  28. private void swim(int k){
  29. //如果父节点的值比当前结点的值小,则交换位置
  30. while(k>1){
  31. if(less(k/2,k)){
  32. exch(k/2,k);
  33. }else{
  34. break;
  35. }
  36. k = k/2;
  37. }
  38. }
  39. // 删除堆中最大的元素,并返回这个最大元素
  40. public T delMax(){
  41. //删除最大元素,其实就是删除根结点
  42. T max = items[1];
  43. //交换到索引结尾处
  44. exch(1, N);
  45. items[N]=null;
  46. N--;
  47. sink(1);
  48. return max;
  49. }
  50. // 使用下沉算法,使索引k处的元素能在堆中处于一个正确的位置
  51. // 当前节点a[k]和它的子节点a[2k]和a[2k+1]中较大者交换位置
  52. private void sink(int k){
  53. //循环条件:有子节点
  54. while(2*k<=N){
  55. int max; //暂存较大的子节点
  56. //<=N 说明存在叶子节点
  57. if (2*k+1<=N){
  58. if(less(2*k,2*k+1)){
  59. max = 2*k + 1;
  60. }else{
  61. max = 2*k;
  62. }
  63. }else{
  64. max = 2*k;
  65. }
  66. if(!less(k,max)){
  67. break;
  68. }
  69. exch(k,max);
  70. //变化k的值
  71. k = max; //下一次循环
  72. }
  73. }
  74. }

原文链接:https://blog.csdn.net/Amigo_1997/article/details/118441974



所属网站分类: 程序员的那点事

作者:想要飞翔的天使

链接:http://www.pythonpdf.com/blog/article/376/21e5171b3c6c8102e755/

来源:编程知识网

任何形式的转载都请注明出处,如有侵权 一经发现 必将追究其法律责任

2 0
收藏该文
已收藏

评论内容:(最多支持255个字符)