数据结构 ||二叉树实现(C++版)

二叉树中需要实现的操作
1.【二叉树的结点定义】
template <class T>
struct TreeNode{

  TreeNode(T data=T())
    :_left(nullptr)
     ,_right(nullptr)
     ,_data(data)
  {}
 TreeNode* _left;
 TreeNode* _right;
 T _data;
};
  • 二叉树结点结构图
    在这里插入图片描述
2.【二叉树构造】
  • 假如输入的值为’#’ 则将其结点置为空
public:
  void CreateTree(Bitree<T>* tree){
    _CreateTree(&(tree->_root));  
  }
  private:
  void _CreateTree(pNode* root){
    T _val;
    cin>>_val;
    if(_val=='#'){
      *root=nullptr;
    }else{
      if(*root==nullptr){
        (*root)=new Node(_val);
      }

      (*root)->_data=_val;
      _CreateTree(&( (*root)->_left ));
      _CreateTree(&( (*root)->_right ));
    }
  }
3.【输出叶子结点】
  • 叶子结点特点
  • 左右孩子都为空
  void PreOrder(pNode root){
    if(root!=nullptr){
      if(root->_left==nullptr && root->_right==nullptr){
        cout<<root->_data<<" ";
      }
      PreOrder(root->_left);
      PreOrder(root->_right);
    }
  }
4.【层序遍历】
  • 思路
  • 1.先处理根结点的情况
  • 2.设计一个队列,向其中push每层的结点
  • 3.在取出结点的同时判断结点左右孩子的情况再进行队列的插入与弹出
  void LevelTravel(pNode root){

    if(root==NULL){
      return;
    }
  
    if(root->_left==nullptr&&root->_right==nullptr){
      cout<<root->_data<<" ";
      return;  
    }
    queue<pNode> qu;
    qu.push(root);

    while(!qu.empty()){
      
      pNode node=qu.front();
      qu.pop();
      cout<<node->_data<<" ";

      if(node->_left){
        qu.push(node->_left);
      }
      if(node->_right){
        qu.push(node->_right);
      }
    }
  }

5.【差找某个值是否与该二叉树中某个结点值相同】
  • 思路(递归处理)
  • 1.先根据根结点的情况处理根结点
  • 2.在往左孩子中去查找该值
  • 3.在往右孩子中去差找该值
 pNode Tree_Value_Find(pNode root,T value){
    if(root==nullptr){
      return nullptr;
    }
    if(root->_data==value){
      return root;
    }

    //往其左右孩子中去寻找该值
    pNode left=Tree_Value_Find(root->_left,value);
    if(left){
      return left;
    }
    pNode right=Tree_Value_Find(root->_right,value);
    if(right){
      return right;
    }
    return nullptr;
  }

6.【计算叶子结点个数】
  • 思路(递归)
  • 1.递归终止条件:结点为空,或者结点为叶子结点
  • 2.计算根结点左孩子的叶子结点个数
  • 3.计算根结点右孩子的叶子结点个数
  • 4.将根结点左右孩子结点个数相加,即为整个二叉树叶子结点的个数
  //计算叶子结点个数
  int Tree_Leaf_Num(pNode root){
    if(root==nullptr){
      return 0;
    }

    if(root->_left==nullptr && root->_right==nullptr){
      return 1;
    }
    int left=Tree_Leaf_Num(root->_left);
    int right=Tree_Leaf_Num(root->_right);

    return left+right;
  }
7.【输出二叉树中第K层的结点值】
  • 思路(递归)
  • 1.递归终止条件:根结点为空,或者当K ==1的时候
    注意进行递归的时候,要保证同一个结点的左右子树的K值相同
  void K_Node(pNode root,int K){
    if(root==nullptr)
     return ;
    if(K==1){
      cout<<root->_data<<" ";
    }
    
    K--;
    K_Node(root->_left,K);
    K_Node(root->_right,K);
  }

8.【求二叉树的高度】
  • 思路(递归)
  • 1.递归终止条件:根结点为空
  • 2.计算左右子树的高度
  • 3.判断左右子树高度的大小,二叉树的高度是左右子树中高度较大的那个+1
//求二叉树的高度或者深度
  int Tree_Height(pNode root){
    if(root==nullptr){
      return 0;
    }

    int left=Tree_Height(root->_left);
    int right=Tree_Height(root->_right);

    if(left>right){
      return 1+left;
    }else{
      return 1+right;
    }
  }
9.【计算第K层的结点个数】
  • 思路(递归)
  • 1.递归终止条件:根结点为空,或者达到第K层
  • 2.需要保证根结点的左右子树在进行递归时的参数K是相同的
  int K_Node_Num(pNode root,int K){
    if(root==nullptr)
      return 0;
    if(K==1){
      return 1;
    }

    K--;//此处先进行K--,是为了避免发生在执行递归过程中出现层数的错误
    return K_Node_Num(root->_left,K)+K_Node_Num(root->_right,K);
  }

二叉树的整体实现和测试
#include<iostream>
#include<stdlib.h>
#include<vector>
#include<queue>

using namespace std;

template <class T>
struct TreeNode{

  TreeNode(T data=T())
    :_left(nullptr)
     ,_right(nullptr)
     ,_data(data)
  {}
 TreeNode* _left;
 TreeNode* _right;
 T _data;
};

template <class T>

class Bitree{
  public:
  typedef TreeNode<T> Node;
  typedef Node* pNode;
  public:
  Bitree()
    :_root(nullptr)
  {}

  pNode getroot(){
    return _root;
    //获取二叉树的根结点
  }
  void CreateTree(Bitree<T>* tree){
    _CreateTree(&(tree->_root));  
  }

  void PreOrderTravel(pNode root){
    if(root==nullptr){
      return;
    }
   cout<<root->_data;
   PreOrderTravel(root->_left);
   PreOrderTravel(root->_right);
  }


  //输出叶子结点
  void PreOrder(pNode root){
    if(root!=nullptr){
      if(root->_left==nullptr && root->_right==nullptr){
        cout<<root->_data<<" ";
      }
      PreOrder(root->_left);
      PreOrder(root->_right);
    }
  }


  //层序遍历
 
  void LevelTravel(pNode root){

    if(root==NULL){
      return;
    }
  
    if(root->_left==nullptr&&root->_right==nullptr){
      cout<<root->_data<<" ";
      return;  
    }
    queue<pNode> qu;
    qu.push(root);

    while(!qu.empty()){
      
      pNode node=qu.front();
      qu.pop();
      cout<<node->_data<<" ";

      if(node->_left){
        qu.push(node->_left);
      }
      if(node->_right){
        qu.push(node->_right);
      }
    }
  }

 //在二叉树中差找指定的值
  pNode Tree_Value_Find(pNode root,T value){
    if(root==nullptr){
      return nullptr;
    }
    if(root->_data==value){
      return root;
    }

    //往其左右孩子中去寻找该值
    pNode left=Tree_Value_Find(root->_left,value);
    if(left){
      return left;
    }
    pNode right=Tree_Value_Find(root->_right,value);
    if(right){
      return right;
    }
    return nullptr;
  }

  //计算叶子结点个数
  int Tree_Leaf_Num(pNode root){
    if(root==nullptr){
      return 0;
    }

    if(root->_left==nullptr && root->_right==nullptr){
      return 1;
    }
    int left=Tree_Leaf_Num(root->_left);
    int right=Tree_Leaf_Num(root->_right);

    return left+right;
  }

  //输出第K层的结点
  void K_Node(pNode root,int K){
    if(root==nullptr)
     return ;
    if(K==1){
      cout<<root->_data<<" ";
    }
    
    K--;
    K_Node(root->_left,K);
    K_Node(root->_right,K);
  }


  int K_Node_Num(pNode root,int K){
    if(root==nullptr)
      return 0;
    if(K==1){
      return 1;
    }

    K--;//此处先进行K--,是为了避免发生在执行递归过程中出现层数的错误
    return K_Node_Num(root->_left,K)+K_Node_Num(root->_right,K);
  }


  //求二叉树的高度或者深度
  int Tree_Height(pNode root){
    if(root==nullptr){
      return 0;
    }

    int left=Tree_Height(root->_left);
    int right=Tree_Height(root->_right);

    if(left>right){
      return 1+left;
    }else{
      return 1+right;
    }
  }

  private:
  pNode _root;

  void _CreateTree(pNode* root){
    T _val;
    cin>>_val;
    if(_val=='#'){
      *root=nullptr;
    }else{
      if(*root==nullptr){
        (*root)=new Node(_val);
      }

      (*root)->_data=_val;
      _CreateTree(&( (*root)->_left ));
      _CreateTree(&( (*root)->_right ));
    }
  }
};


int main(){
  Bitree<char> tree;

  tree.CreateTree(&tree);
  TreeNode<char>*  root=tree.getroot();
  cout<<"前序遍历:";
  tree.PreOrderTravel(root);
  cout<<endl;
  
  //输出叶子结点
  cout<<"输出叶子结点:";
  tree.PreOrder(root);
  cout<<endl;

  //层序遍历
  cout<<"层序遍历结果:";
  tree.LevelTravel(root);
  cout<<endl;

  cout<<"请输入要查询的值";
  char find;
  cin>>find;
  TreeNode<char>* node=tree.Tree_Value_Find(root,find);
  if(node){
    cout<<"您要差找的值已经找到!"<<endl;
  }else{
    cout<<"您所差找的值不存在!"<<endl;
  }

  int num=tree.Tree_Leaf_Num(root);
  cout<<"叶子结点个数:"<<num<<endl;
 cout<<"请输出该二叉树那层上的结点:";
  int K;
  cin>>K;
 
  tree.K_Node(root,K);
  cout<<endl;

  cout<<"请输入您要求那一层的结点个数:";
  int num1;
  cin>>num1;

  int size=tree.K_Node_Num(root,num1);
  cout<<"第"<<num1<<"层共有"<<size<<"个结点!"<<endl;

  cout<<"该树的高度是:"<<tree.Tree_Height(root)<<endl;
  return 0;
}
测试结果

在这里插入图片描述

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值