美文网首页
二叉树的存储方式

二叉树的存储方式

作者: _涼城 | 来源:发表于2020-04-25 21:44 被阅读0次

    二叉树

    二叉树是每个结点最多有两个子树的树结构。通常子树被称作“左子树”和“右子树”。

    相关术语
    1. 一棵深度为k,且有2^k-1 个结点的二叉树,称为满二叉树
    2. 在一棵二叉树中,除最后一层外,若其余层都是满的,并且或者最后一层是满的,或者是在右边缺少连续若干结点,则此二叉树为完全二叉树
    3. 所有节点都只有左子树,称为左斜树
    4. 所有节点都只有右子树,称为右斜树
    性质
    1. 在二叉树的第i层上最多有2^i-1 个结点
    2. 深度为K的二叉树最多有2^k -1 个结点(K>=1)
    3. 对于任何一颗二叉树T,如果其终端结点数为n0,度为2的结 点数为n2,则n0 = n2 + 1;
    4. 具有n个结点的完全二叉树的深度为[log2n] + 1
    顺序结构
    1. 初始化

      
          BOOL InitBiTree(SqBiTree T){
           for (int i = 0; i < MAXSIZE;i++)
           {   
               T[i] = Nil;
           }
           return true;
       }
      
    2. 创建二叉树

      BOOL createBiTree(SqBiTree T) {
       int i = 0;
        while (i < 10) {
           T[i] = i+1;
           printf("%d ",T[i]);
           //结点不为空,且无双亲结点
           if (i != 0 && T[(i+1)/2-1] == Nil && T[i] != Nil) {
               printf("出现无双亲的非根结点%d\n",T[i]);
               exit(0);
           }
           
           i++;
           
       }
       //将空赋值给T的后面的结点
       while (i < MAXSIZE) {
           T[i] = Nil;
           i++;
       }
       return true;
       }
      
    3. 是否空树

       //是否空树
       BOOL isEmpty(SqBiTree T){
           return T[0] == Nil;
       }
      
    4. 获取深度

      int BiTreeDepth(SqBiTree T){
      int j = -1;
      int i;
      for (i = MAXSIZE - 1; i >= 0; i--)
      {
          if (T[i] != Nil)
          {
        
              break;
          }
      }
      
      do{
          j++;
      }while(pow(2,j) <= i);
      
      return j;
      }
      
    5. 获取E点的值

       //获取E点的结点值
       CElemType getValue(SqBiTree T,Position e){
            return T[pow(2,e.level - 1) + e.order - 2];
       }
       
       //插入值至位置e
       BOOL Assign(SqBiTree T,Position e  ,CElemType value){
           int i = pow(2,e.level - 1) + e.order - 2;
           if (T[(i + 1) / 2 - 1] == Nil ){
              return false;
           }
           T[i] = value;
           return true;
       }
      
    6. 插入结点

          //插入值至位置e
       BOOL Assign(SqBiTree T,Position e  ,CElemType value){
           int i = pow(2,e.level - 1) + e.order - 2;
           if (T[(i + 1) / 2 - 1] == Nil ){
              return false;
           }
           T[i] = value;
           return true;
       }
      
    7. 左子结点

      int leftChild(SqBiTree T,Position e){
       return T[(int)(pow(2, e.level-1)+e.order-2) * 2 + 1 ];
      }
      
    8. 右子结点

         int rightChild(SqBiTree T,Position e){
           return T[(int)(pow(2, e.level-1)+e.order-2) * 2 + 2 ];
       }
      
    9. 双亲结点

        int fatherNode(SqBiTree T,Position e){
       if (e.level != 1)
       {
           return T[(int)(pow(2, e.level-1)+e.order-2) / 2 - 1];
       }
       return -1;
      }
      
    10. 前序遍历(中左右)

      
      void PreTraverse(SqBiTree T,int e){
       
       //打印结点数据
      
       printf("%d ",T[e]);
       
       //先序遍历左子树
       if (T[2 * e + 1] != Nil) {
           PreTraverse(T, 2*e+1);
       }
       //最后先序遍历右子树
       if (T[2 * e + 2] != Nil) {
           PreTraverse(T, 2*e+2);
       }
      }
      
      BOOL PreOrderTraverse(SqBiTree T){
       
       //树不为空
       if (!isEmpty(T)) {
           PreTraverse(T, 0);
       }
       printf("\n");
       return  true;
      }
      
    11. 中序遍历(左中右)

       void InTraverse(SqBiTree T, int e){
           /* 左子树不空 */
           if (T[2*e+1] != Nil)
               InTraverse(T, 2*e+1);
           
            printf("%d ",T[e]);
           
           /* 右子树不空 */
           if (T[2*e+2] != Nil)
               InTraverse(T, 2*e+2);
       }
       
       BOOL InOrderTraverse(SqBiTree T){
           
           /* 树不空 */
           if (!isEmpty(T)) {
               InTraverse(T, 0);
           }
           printf("\n");
           return true;
       }
      
    12. 后序遍历

        void PostTraverse(SqBiTree T,int e)
      {   /* 左子树不空 */
       if(T[2*e+1]!=Nil)
           PostTraverse(T,2*e+1);
       /* 右子树不空 */
       if(T[2*e+2]!=Nil)
           PostTraverse(T,2*e+2);
       printf("%d ",T[e]);
      
      }
      BOOL PostOrderTraverse(SqBiTree T)
      {
       if(!isEmpty(T)) /* 树不空 */
           PostTraverse(T,0);
       printf("\n");
       return true;
      }
      
    链式存储
    1. 结构

      typedef char CElemType;
      CElemType Nil=' '; /* 字符型以空格符为空 */
      typedef struct BiTNode  /* 结点结构 */
      {
          CElemType data;        /* 结点数据 */
          struct BiTNode *lchild,*rchild; /* 左右孩子指针 */
      }BiTNode,*BiTree;
      
    2. 初始化

      BOOL InitBiTree(BiTree *T)
      {
          *T=NULL;
          return true;
      }
      
    3. 销毁二叉树

      void DestroyBiTree(BiTree *T)
      {
          if(*T)
          {
              /* 有左孩子 */
              if((*T)->lchild)
                  DestroyBiTree(&(*T)->lchild); /* 销毁左孩子子树 */
              
              /* 有右孩子 */
              if((*T)->rchild)
                  DestroyBiTree(&(*T)->rchild); /* 销毁右孩子子树 */
              
              free(*T); /* 释放根结点 */
              
              *T=NULL; /* 空指针赋0 */
          }
      }
      
    4. 创建二叉树,#表示空树

      void CreateBiTree(BiTree *T){
          
          CElemType ch;
          
          //获取字符
          ch = str[indexs++];
          
          //判断当前字符是否为'#'
          if (ch == '#') {
              *T = NULL;
          }else
          {
              //创建新的结点
              *T = (BiTree)malloc(sizeof(BiTNode));
              //是否创建成功
              if (!*T) {
                  exit(OVERFLOW);
              }
              
              /* 生成根结点 */
              (*T)->data = ch;
              /* 构造左子树 */
              CreateBiTree(&(*T)->lchild);
              /* 构造右子树 */
              CreateBiTree(&(*T)->rchild);
          }
          
      }
      
    5. 判断二叉树是否为空

      BOOL BiTreeEmpty(BiTree T)
      {
          if(T)
              return false;
          else
              return true;
      }
      
      
    6. 二叉树的深度

      int BiTreeDepth(BiTree T){
          
          int i,j;
          if(!T)
              return 0;
          
          //计算左孩子的深度
          if(T->lchild)
              i=BiTreeDepth(T->lchild);
          else
              i=0;
          
          //计算右孩子的深度
          if(T->rchild)
              j=BiTreeDepth(T->rchild);
          else
              j=0;
          
          //比较i和j
          return i>j?i+1:j+1;
      }
      
      
    7. 根结点

      CElemType getRoot(BiTree T){
          if (BiTreeEmpty(T))
              return Nil;
          
          return T->data;
      }
      
    8. 获取结点的值

      CElemType getValue(BiTree p){
          return p->data;
      }
      
      
    9. 给结点赋值

      void Assign(BiTree p,CElemType value)
      {
          p->data=value;
      }
      
    10. 前序遍历

      void PreOrderTraverse(BiTree T)
      {
          if(T==NULL)
              return;
          printf("%c",T->data);/* 显示结点数据,可以更改为其它对结点操作 */
          PreOrderTraverse(T->lchild); /* 再先序遍历左子树 */
          PreOrderTraverse(T->rchild); /* 最后先序遍历右子树 */
      }
      
    1. 中序遍历

      void InOrderTraverse(BiTree T)
      {
          if(T==NULL)
              return ;
          InOrderTraverse(T->lchild); /* 中序遍历左子树 */
          printf("%c",T->data);/* 显示结点数据,可以更改为其它对结点操作 */
          InOrderTraverse(T->rchild); /* 最后中序遍历右子树 */
      }
      
    1. 后序遍历

      void PostOrderTraverse(BiTree T)
      {
          if(T==NULL)
              return;
          PostOrderTraverse(T->lchild); /* 先后序遍历左子树  */
          PostOrderTraverse(T->rchild); /* 再后序遍历右子树  */
          printf("%c",T->data);/* 显示结点数据,可以更改为其它对结点操作 */
      }
      
      

    相关文章

      网友评论

          本文标题:二叉树的存储方式

          本文链接:https://www.haomeiwen.com/subject/wdylwhtx.html