数据结构 ---- 二叉树的相关操作(1)

首先,什么是二叉树?
二叉树是一个根结点只有左右子树就叫二叉树;如下图就是一个普通的二叉树:
这里写图片描述
树有许多的表示方法,这里二叉树用孩子表示法。
之前关于链表我们知道,用头指针来表示单链表,这里用相同的思想:用根结点指针来表示一棵树;
这里先用递归的思想来完成二叉树的先序、中序、后序,层序这里需要借助之前的顺序队列来完成;
代码实现:
bin_tree.h

   #pragma once                                            
   #include <stdio.h>
   typedef char TreeNodeType;
   //使用孩子表示法来表示一棵树
   typedef struct TreeNode {
       TreeNodeType data;
       struct TreeNode* lchild;
       struct TreeNode* rchild;
   }TreeNode;

  //对于链表来说,使用链表的头节点指针来表示一个链表
  //对于二叉树来说,使用跟结点的指针来表示一棵树

  void TreeInit(TreeNode** pRoot);

  void TreePreOrder(TreeNode* root);

  void TreeInOrder(TreeNode* root);

  void TreePostOrder(TreeNode* root);

  void TreeLevelOrder(TreeNode* root);

  //输入一个数组(数组中的每个元素就是树上的结点),根据数组的内容
  //构建出一颗树,数组中元素的内容符合树的先序遍历结果(包含所有空结点)
  TreeNode* TreeCreate(TreeNodeType arry[],size_t size,char null_node);

  //求二叉树中结点的个数
  size_t TreeSize(TreeNode* root);
  //求二叉树中叶子结点的个数
  size_t TreeLeafSize(TreeNode* root);
  //求二叉树中第K层结点的个数                                                                        
  size_t TreeKLevelSize(TreeNode* root,int K);

  //求二叉树的高度/深度
  size_t TreeHeight(TreeNode* root);

  void TreeDestroy(TreeNode* root);

  //在二叉树中查找结点,给定一个数值,求出对应结点的指针
  //假设二叉树中的结点是不重复的
  TreeNode* TreeFind(TreeNode* root,TreeNodeType to_find);

  //求出child的父节点
  TreeNode* FindParent(TreeNode* root,TreeNode* child);

  //求出当前节点的左子树和右子树
  TreeNode* LChild(TreeNode* node);
  TreeNode* RChild(TreeNode* node);

bin_tree.c

   #include <stdio.h>                                                                                 
   #include <stdlib.h>
   #include <assert.h>
   #include "bin_tree.h"
   #include "seqqueue.h"
   #include "seqstack.h"

   TreeNode* CreateTreeNode(TreeNodeType value){ 
       TreeNode* new_node = (TreeNode*)malloc(sizeof(TreeNode));
      new_node->data = value;
      new_node->lchild = NULL;
      new_node->rchild = NULL;
      return new_node;
  }

  void DestroyTreeNode(TreeNode* node){
      free(node);
  }

  void TreeInit(TreeNode** pRoot){
      if(pRoot == NULL){
          //非法输入                                                                                 
          return;
      }
      *pRoot = NULL;
      return;
  }

  void TreePreOrder(TreeNode* root){
      if(root == NULL){
          //空树
          return;
      }
      //先访问根结点,访问即打印
      printf("%c ",root->data);
      //然后递归的遍历左子树
      TreePreOrder(root->lchild);
      //最后在递归的遍历右子树
      TreePreOrder(root->rchild);
      return;
   }

  void TreeInOrder(TreeNode* root){
      if(root == NULL){
          //空树
          return;
      }
      //先递归的遍历左子树
      TreeInOrder(root->lchild);
      //再访问根结点
      printf("%c ",root->data);
      //最后递归的遍历右子树
      TreeInOrder(root->rchild);
      return;
  }                                                                                                  

  void TreePostOrder(TreeNode* root){
      if(root == NULL){
          //空树
          return;
      }
      //先递归的遍历左子树
      TreePostOrder(root->lchild);
      //再递归的遍历右子树
      TreePostOrder(root->rchild);
      //最后访问根结点
      printf("%c ",root->data);
      return;
  }

  void TreeLevelOrder(TreeNode* root){
      if(root == NULL){
          //空树
          return;
      }
      SeqQueue queue;                                                                                
      SeqQueueInit(&queue);
      SeqQueuePush(&queue,root);
      while(1){                                                                                      
          SeqQueueType front;
          int ret = SeqQueueFront(&queue,&front);
          if(ret == 0){
              //如果队列取队首元素失败,说明队列为空
              //如果队列为空就说明遍历结束了
              break;
          }
          //访问树中的元素,打印当前值
          printf("%c ",front->data);
          //把当前队首元素出队列
          SeqQueuePop(&queue);
          //把当前元素的左右子树入队列

          if(front->lchild != NULL){
              SeqQueuePush(&queue,front->lchild);
          }
          if(front->rchild != NULL){
               SeqQueuePush(&queue,front->rchild);
          }
      }
     return;
 }

 TreeNode* _TreeCreate(TreeNodeType arry[],size_t size,size_t* index,TreeNodeType null_node){
     if(index == NULL){
         //非法输入
         return NULL;
     }
     if(*index >= size){
         return NULL;
     }
     if(arry[*index] == null_node){
         return NULL;                                                                               
     }
     TreeNode* new_node = CreateTreeNode(arry[*index]);
     ++(*index);
     new_node->lchild = _TreeCreate(arry,size,index,null_node);
     ++(*index);
     new_node->rchild = _TreeCreate(arry,size,index,null_node);
     return new_node;
 }

 TreeNode* TreeCreate(TreeNodeType arry[],size_t size,char null_node){
     //表示当前取数组中的那个元素
     size_t index = 0;
     return _TreeCreate(arry,size,&index,null_node);
 }

 TreeNode* TreeClone(TreeNode* root){
     if(root == NULL){
         //空树                                                                                     
         return NULL;
     }
     //按照先序方式来遍历
     TreeNode* new_node = CreateTreeNode(root->data);
     new_node->lchild = TreeClone(root->lchild);
     new_node->rchild = TreeClone(root->rchild);
     return new_node;
 }
 //销毁的过程中一定要保证左右子树能够被正确找到,所有按照后序的方式来销毁
 void TreeDestroy(TreeNode* root){
     if(root == NULL){
         //空树
         return;
     }
     //按照后序遍历的方式来销毁整个树
     TreeDestroy(root->lchild);
     TreeDestroy(root->rchild);
     DestroyTreeNode(root);                                                                         
     return;
 }
 //方法一
 void _TreeSize(TreeNode* root,size_t* size){
     if(root == NULL){
         //空树
         return;
     }
     //按照前序的方式遍历,这里的访问是++
     ++(*size);
     _TreeSize(root->lchild,size);
     _TreeSize(root->rchild,size);
 }
 size_t TreeSize(TreeNode* root){
     size_t size = 0;
     _TreeSize(root,&size);
     return size;                                                                                 
 }
 //方法二
 size_t TreeSize(TreeNode* root){                                                                   
     if(root == NULL){
         //空树
         return 0;
     }
     return 1 + TreeSize(root->lchild) + TreeSize(root->rchild);
 }

 size_t TreeLeafSize(TreeNode* root){
     if(root == NULL){
         //空树
         return 0;
     }
     if(root->lchild == NULL && root->rchild == NULL){
         //root是叶子结点
         return 1;
     }
     //root不是叶子结点
     return TreeLeafSize(root->lchild) + TreeLeafSize(root->rchild);
 }

 size_t TreeKLevelSize(TreeNode* root,int K){
     if(root == NULL || K < 1){
        //root等于空是空树,K<1是非法输入
        return 0;
     }
     if(K == 1){
          return 1;
     }
     return TreeKLevelSize(root->lchild ,K - 1) + TreeKLevelSize(root->rchild,K - 1);

 }

 size_t TreeHeight(TreeNode* root){                                                                 
     if(root == NULL){
         //空树
         return 0;
     }
     if(root->lchild == NULL && root->rchild == NULL){
         return 1;
     }
     size_t lheight = TreeHeight(root->lchild);
     size_t rheight = TreeHeight(root->rchild);

     return 1 + (lheight > rheight ? lheight : rheight);
 }

 TreeNode* TreeFind(TreeNode* root,TreeNodeType to_find){
     if(root == NULL){
         //空树
         return NULL;
     }
     if(root->data == to_find){
         return root;
     }                                                                                              
     TreeNode* lresult = TreeFind(root->lchild,to_find);
     TreeNode* rresult = TreeFind(root->rchild,to_find);
     //不等于空,说明找到了
     return lresult != NULL ? lresult : rresult;
 }

 TreeNode* FindParent(TreeNode* root,TreeNode* child){
     if(root == NULL || child == NULL){
         return NULL;                                                                               
     }
     if(root->lchild == child || root->rchild == child){
         return root;
     }
     TreeNode* lresult = FindParent(root->lchild,child);
     TreeNode* rresult = FindParent(root->rchild,child);
     return lresult != NULL ? lresult : rresult;
 }

 TreeNode* LChild(TreeNode* node){
     if(node == NULL){
         return NULL;
     }
     return node->lchild;
 }

 TreeNode* RChild(TreeNode* node){
     if(node == NULL){
         return NULL;
     }
     return node->rchild;
 }

猜你喜欢

转载自blog.csdn.net/liru_1996/article/details/80351050