<二叉树>补空法

补空法:若子树为空则使用#来补
          o A
        /   \
     B o      o C
      / \    / \
   D o  Eo  oF  #
    /\  /\  /\
   #  ##  ##  o G
             / \
            #   #

  输入ABCDEFG,转换为二叉树
  前序遍历:
    ABDECFG
  考虑#的前序遍历:
    ABD##E##CF#G###
  将考虑#的前序遍历的结果转换为二叉树:

          o A

     B o

   D o  Eo

          o A

     B o

   D o  Eo
    /\ 
   #  #
   
          o A

     B o
      /
   D o  Eo
    /\  /\
   #  ##  #

          o A
        /
     B o
      / \
   D o  Eo
    /\  /\
   #  ##  #

          o A
        /
     B o     o C
      / \
   D o  Eo oF
    /\  /\ /\
   #  ## ##  o G

          o A
        /
     B o     o C
      / \
   D o  Eo oF
    /\  /\ /\
   #  ## ##  o G
            / \
           #   #


          o A
        /
     B o     o C
      / \   /
   D o  Eo oF
    /\  /\ /\
   #  ## ##  o G
            / \
           #   #


          o A
        /
     B o     o C
      / \   / \
   D o  Eo oF  #
    /\  /\ /\
   #  ## ##  o G
            / \
           #   #
#include <iostream>
#include "fill_blank_bintree.h"

using namespace std;



int main(void)
{
    // 返回二叉树指针
    struct BinTree_node* mytree;
    cout << "请输入以前序遍历并补空后的二叉树,如ABD##E##CF#G###:";
    mytree = create_bintree();
    cout << "先序遍历结果:";
    pre_order(mytree);
    cout << endl;

    cout << "中序遍历结果:";
    mid_order(mytree);
    cout << endl;

    cout << "后序遍历结果:";
    back_order(mytree);
    cout << endl;

    cout << "层序遍历结果:";
    level_traverse(mytree);
    cout << endl;
    cout << "二叉树的深度 = " << depth(mytree) << endl;
    cout << "二叉树叶子的个数 = " << leaf_num(mytree) << endl;
    cout << "全部节点个数 = " << node_num(mytree) << endl;

    delete mytree;

    return 0;
}

fill_blank_bintree.cpp

#include <iostream>
#include "fill_blank_bintree.h"
#include "queue.h"
using namespace std;


struct BinTree_node* create_bintree()
{
    char ch;
    struct BinTree_node* tree;
    // 把输入的第一个字母放到ch
    cin >> ch;

    if(ch == '#')
        // 指针指向空
        tree = nullptr;
    else
    {
        // 指针指向开辟好的空间
        tree = new BinTree_node();
        // tree = (struct BinTree_node*)malloc(sizeof(struct BinTree_node));
        // 先访问根节点
        tree->elem = ch;
        tree->Ltree = create_bintree();
        tree->Rtree = create_bintree();
    }
    return tree;
}



// 前序遍历
void pre_order(struct BinTree_node* tree)
{
    // 如果存在根节点
    if(tree)
    {
        // 1.先访问根节点
        cout << tree->elem << " ";
        // 2.访问左子树的根节点,3.直到左子树没有后续节点(递归调用)
        pre_order(tree->Ltree);
        // 4.左子树访问完,相同方法访问右子树
        pre_order(tree->Rtree);
    }

}

// 中序遍历
void mid_order(struct BinTree_node* tree)
{
    // 如果存在根节点
    if(tree)
    {
        // 1.先找左子树,发现它还能分成左子树
        mid_order(tree->Ltree);
        // 2.访问没有没有左子树的节点,3.访问根节点,再访问右子树
        cout << tree->elem << " ";
        // 4.左子树访问完,相同方法访问右子树
        mid_order(tree->Rtree);
    }

}

// 后序遍历
void back_order(struct BinTree_node* tree)
{
    // 如果存在根节点
    if(tree)
    {
        // 1.先找左子树,发现它还能分成左子树
        back_order(tree->Ltree);
        // 2.访问没有没有左子树的节点,3.访问根节点,再访问右子树
        // 4.左子树访问完,相同方法访问右子树
        back_order(tree->Rtree);
        cout << tree->elem << " ";

    }

}

void level_traverse(struct BinTree_node* tree)
{
    // 1.创建队列,让根节点A先进入队列
    enqueue(*tree);
    // 结构体对象
    struct BinTree_node node;

    // 若队列不空
    while(!isempty())
    {
        // 队列的头出队列,「同时」队列头的左子树和右子树入队列
        node = dequeue();
        // 打印,表示访问过
        cout << node.elem << " ";
        // 若当前节点有左子树,同时队列头的左子树和右子树入队列
        if(node.Ltree)
            enqueue(*node.Ltree);
        if(node.Rtree)
            enqueue(*node.Rtree);
    }

}


unsigned int depth(struct BinTree_node* tree)
{
    unsigned int L_depth = 0;
    unsigned int R_depth = 0;
    // 二叉树为空:到达叶子节点
    if(tree == nullptr)
        return 0;
    else// 二叉树的深度 = 左右子树最大深度加1
    {
        // 条件表达式返回的值赋值
        // 返回左子树深度:2
        L_depth = depth(tree->Ltree);
        // 返回右子树深度:3
        R_depth = depth(tree->Rtree);
        // 条件表达式:如果左边的深度大于右边的深度,则左边的深度+1,否则右边的深度+1
        return (L_depth > R_depth) ? (L_depth + 1) : (R_depth + 1);// 3>2
    }


}


/*

叶子节点个数
  不再继续分左右子树的节点:DEG
          o A     →
        /   \
     B o    o C   →
      / \  /
   D o Eo oF      →
           \
            o G   →

*/
unsigned int leaf_num(struct BinTree_node* tree)
{
    // 情况1.二叉树为空,叶子节点个数 == 0
    if(tree == NULL)
        return 0;
        // 情况2.只有根节点,无左右子树,叶子节点个数 == 1
    else if(tree->Ltree == NULL && tree->Rtree == NULL)
        return 1;
    else
        // 情况3.整个二叉树的叶子节点个数 == 左子树的叶子个数 + 右子树的叶子个数
        return leaf_num(tree->Ltree) + leaf_num(tree->Rtree);// 2 + 1 = 3



}

unsigned int node_num(struct BinTree_node *tree)
{
    if(tree == nullptr)
        return 0;
    else
        // 左子树节点个数+右子树节点个数+根节点
        return node_num(tree->Ltree) + node_num(tree->Rtree) + 1;


}



fill_blank_bintree.h


#ifndef __GOTHROUGH_BINARY_TREE_H__
#define __GOTHROUGH_BINARY_TREE_H__


struct BinTree_node
{
  // 节点内容
  unsigned char elem;
  // 左子树
  struct BinTree_node* Ltree;
  // 右子树
  struct BinTree_node* Rtree;
};

struct BinTree_node* create_bintree();
void pre_order(struct BinTree_node* tree);
void level_traverse(struct BinTree_node* tree);
void mid_order(struct BinTree_node* tree);
void back_order(struct BinTree_node* tree);
unsigned int depth(struct BinTree_node* tree);
unsigned int leaf_num(struct BinTree_node* tree);
unsigned int node_num(struct BinTree_node *tree);



#endif

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值