数据结构与算法简记:根据层次顺序存储结构构建二叉树

本文介绍了如何根据层次顺序存储结构构建二叉树,特别是针对满二叉树或近似满二叉树的情况。通过逐层扫描节点并用特殊符号表示空节点,可以简化存储并节省空间。在构建过程中,利用层次信息确定节点的父节点和子节点关系,通过遍历和创建节点对象完成树的构建。文章提供了JS、Java和C语言的实现代码。
摘要由CSDN通过智能技术生成

在存储满二叉树或近似满二叉树时,按节点层次顺序存储是个不错的主意,我们从根节点开始,逐层由左到右扫描各个节点,依次将节点数据存放到指定的数组中,如果偶尔遇到空的子节点,就用特殊符号来表示。

这个树结构已接近满二叉树了,如果使用按层次顺序存储,将会更简单,更节省空间。按照上面的方法,这棵树所对应的存储结构应该是:

['A', 'B', 'E', 'C', 'D', '#', 'F']

其中空的子节点,我们使用#号来占位。

根据这个存储结构,我们就可以构建出一棵二叉树,还原它本来的面目。

思路如下:

  1. 我们知道,根节点起始位置array[0],节点个数为1,第二层起始位置array[1],节点个数为2;依次类推,每一层起始位置的索引都是前面节点的总个数,我们需要记录父层起始位置和当前层的起始位置。
  2. 根据满二叉树的结构,可以得出当前层节点的个数:pow(2, level -1),即2的level - 1次方,其中level即为当前层数,从1开始。
  3. 遍历当前层的节点,规则是:每遍历两个节点(左右子节点),父层遍历一个,在遍历过程中,创建相应的节点对象,并与父节点进行关联。
  4. 遍历完成后,当前层将成为下一轮的父层,重新计算下一层的起始位置和节点个数。然后开始下一轮。

上面提到,这种存储顺序适用于满二叉树或接近满二叉树的情况,所以这里我们只考虑极少数的空叶子节点,对于最后一层空的叶子节点,如果它们是连续排在最后面的,则也可以省略,以节省存储空间。

下面是实现代码:

JS版:

//二叉树节点结构
function BinTreeNode(data) {
   
  this.data = data;
  this.leftChild = null;
  this.rightChild = null;
}

//根据顺序存储序列创建二叉树
function createBinTreeByArray(array) {
   

  //初始化树的层次,每层存储pow(2, currLevel - 1)个节点数据
  var currLevel = 1;

  //初始化当前节点层和父层起始位置
  var currLevelBegin = 0,
      parentLevelBegin = 0;

  //节点数组,用于放置新建的节点
  var nodeArray = [];

  //循环遍历每一层
  while (currLevelBegin < array.length) {

    //每一层的节点数量
    var levelNumber = Math.pow(2, currLevel - 1);

    //记录父层的step,初始值0
    var parentStep = 0;

    //遍历当前节点层每个节点数据
    for (var step = 0; step < levelNumber; step++) {
      //计算在数组中的索引
      var index = currLevelBegin + step;

      if (index >= array.length) break;

      var node = null;

      //创建节点对象,并放进节点数组中
      if (array[index] !== '#') {
        node = new BinTreeNode(array[index]);
        nodeArray.push(node);
      }

      //如果不是根节点层,则需要与父节点做关联
      if (currLevelBegin > 0) {

        //获取父节点
        var parentNode = nodeArray[parentLevelBegin + parentStep];

        //step是从0开始的,如果是偶数则成为左子节点,奇数则成为右子节点
        
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值