顺序存储二叉树的压缩算法

  摘要:顺序二叉树占用空间大而又插入删除不便,讨论二叉树压缩存储的文章并不多见。但顺序二叉树的查找非常方便。本文提供了一种基于叶结点的位置对二叉树的压缩存储,称为叶结点位置法。
  这种算法依据了二叉树的以下基本性质:

  1:在任意一棵二叉树中,若其终端结点数为N0,度为2的结点数为N2,则N0=N2+1。
  2、如果对一棵有N个结点的完全二叉树的结点按层序排列,从1开始编号,则对任一编号为i的结点,如果其左、右孩子结点,则它们的编号分别为2i,2i+1。


  这个方法的基本思路是:二叉树的任一结点都是叶结点或叶结点的的父结点/祖父结点。把一棵任意的二叉树补充为完全二叉树后并按层序从1开始编号,则原二叉树中任一结点的编号都可以根据叶子结点的编号计算出来。
  例如,下图是一棵简单二叉树。
一棵简单的二叉树
  其用叶结点位置法压缩的结果是:
  a[6]=[a,b,c,d,e,f];
        b[3]=[2,6,15]
  a[]为结点的data信息,b[]中的2,6,14分别为叶结点b,d,f在将该二叉树补充为完全二叉树时的层次遍历编号。结点a,c,e的编号可以通过其叶结点的编号计算出来。例如,结点e的编号为int (15/2)=7。
  下面的算法实现了将压缩存储的二叉树还原成出非空结点的序号。根据叶结点的位置信息a[]计算出二叉树中非空结点的位置信息,并按倒序存储在数组b[]中。
下面编码在TurboC2.0中测试通过。
#include <stdio.h>
void main()
 {
 int a[6]={0,4,5,13,24,60};
 int b[15]={0};
 int j=0;
 int left,middle,right,k;
 int n=5;
 
clrscr();
b[0]=a[n];
j++;
while(n>1)
{
   a[n]=a[n]/2;
   a[0]=a[n];
   left=1;right=n-1;
   while(left<=right)
      {
     middle=(left+right)/2;
      if (a[0]<a[middle])
     right=middle-1;
      else
     left=middle+1;
      }
   if (a[n]==a[left-1]&&left!=1)
      {
     n--;
      }
  else
      {
      for(k=n-1;k>=left;k--)
     a[k+1]=a[k];
    a[left]=a[0];
      }
      b[j]=a[n];
      j++;

}
for(j=0;j<15;j++)
printf("%d\n",b[j]);
}


范晨鹏
------------------
软件是一种态度
成功是一种习惯


原文地址:https://www.cnblogs.com/diylab/p/472556.html