数据结构:堆

本文介绍了完全二叉树的概念及使用数组和链表两种方式实现堆的数据结构。详细讲解了堆元素插入(上滤)和删除(下滤)的过程,并提供了具体的实现代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

结构性和堆序性
堆:堆是一棵被完全填满的二叉树,只有底层从左到右填入,可能不满。
一棵高为h的二叉树,节点个数为2^h到2^(h+1);
用一个数组存储该完全二叉树,数组【0】空闲,从【1】开始存储该堆,则位置i上的节点A,其左儿子在位置(2i)处,右儿子在位置(2i+1)处;对应一节点A的父节点位置为【i/2】下取整。

数组实现的堆:
        数组【0】空闲,从【1】开始存储该堆,则位置i上的节点A,其左儿子在位置(2i)处,右儿子在位置(2i+1)处;对应一节点A的父节点位置为【i/2】下取整。
链表实现的堆:
        类似于二叉树,每个节点至少需要两个指针,指向他的左右子节点。
        利用这种结点结构所得的二叉树存储结构称之为二叉链表。在二叉链表中,如果想找到某个结点的双亲,需要从根节点开始遍历,所以有时为了便于找到结点的双亲,还可以在结点结构中增加一个指向其双亲结点的指针域,相应的二叉树存储结构称之为三叉链表。

堆元素插入——上
对元素删除——下
        上滤和下避免了为最后元素寻找合适位置时的多次交换赋值,一个元素上虑d层,交换赋值达到3d次,而我们的方法仅需要d+1次。
    上:新添加一个元素A,首先虚拟锁定hole——【hole(n)】,若A大于[n/2],则将【n/2】元素复制到【n】,更新n,继续迭代操作,直到A<=【n/2】时,将A放入【n】位置。
上滤代码:
 public void insert(AnyType x){
  if(currentSize==array.length-1){
   enlargeArray(array.length*2+1);
  }
  //上滤
  int hole=++currentSize;
  for(;hole>1&&x.compareTo(array[hole/2])<0;hole/=2){
   array[hole]=array[hole/2];
  }
  array[hole]=x;
 }
下滤代码:
在deleteMin中,调用下滤方法,出入的hole应该为1,即根节点的位置
前一步操作:array[1]=array[currentSize--];保证删除最小元素后,将最后位置的元素首先复制到根位置,保证堆的结构性,然后调用percolateDown(),调整保证堆序性。
 private void percolateDown(int hole){
  int child;
  AnyType tmp=array[hole];
  for(;hole*2<currentSize;hole=child){
   //注意这里,保证有两个子节点,就算只有一个子节点(child+1-->null)
   //找到两个子节点中的较小者,将其上移,即hole向下移动一层
   if(child!=currentSize&&array[child+1].compareTp(array[child])<0){
    child++;
   }
   if(array[child].compareTo(tmp)<0){
    array[hole]=array[child]
   }else
    break;    
  }
  array[hole]=tmp;
 }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值