按树状打印二叉树

程序说明

一、输入输出说明

  1. 输入:该程序输入分两行,第一行为对这棵二叉树(记为BinaryTree)进行前序遍历所得的序列,第二行为对BinaryTree进行中序遍历所得的序列。结点元素之间均用空格隔开。
    Sample Input

    A B D C E F
    B D A E F C 
    
  2. 输出:该程序输出按树状打印的BinaryTree
    Sample Output

                    C
                                    F
    
                            E
    
    
            A
                            D
    
                    B
    

二、程序实现思路

  1. 结点类型:结点用程序描述为一个结构体 TreeNode,其中包含该结点的键值 key,深度 depth及指向左、右孩子的指针 left_childright_child

    struct TreeNode {
      struct TreeNode* left_child;
      struct TreeNode* right_child;
      char key;
      int depth;
    };
    
  2. 函数及其功能

  • main:主函数,读入数据并构建二叉树,而后对其进行逆中序遍历并打印
  • ConstructBinTree:根据前序序列和中序序列构建二叉树,并返回该二叉树的根节点root。输入为该二叉树的前序序列preorder及中序序列inorder,返回值为指向根节点的指针TreeNode*
    实现思路即为练习7.11答案,即:在这里插入图片描述
  • PrintTreeWithRotation:打印该二叉树。输入为该二叉树的根节点,无返回值。
    实现思路即对其进行反向中序遍历(RightChild -> Root -> LeftChild)
    可利用递归实现或利用栈作为辅助数据结构进行非递归实现。此处采用编码难度较低但效率较低的递归实现。

三、代码实现

/*
 * @Description:
 * Input: the inorder and preorder traverse sequence of the binary tree
 * @Author: Fishermanykx
 * @Date: 2019-11-9 22:18:42
 * @LastEditors: Fishermanykx
 * @LastEditTime: 2019-11-13 12:58:37
 */

#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

struct TreeNode {
  struct TreeNode* left_child;
  struct TreeNode* right_child;
  char key;
  int depth;
};

typedef struct TreeNode* Node;

Node ConstructBinTree(char preorder[], char inorder[], int pre_lo, int pre_hi,
                      int in_lo, int in_hi, int depth);
void PrintTreeWithRotation(Node bin_tree);

int main() {
  // 数据读入
  char pre_order_tree[100];
  char in_order_tree[100];
  char tmp_str[100];
  char ch;

  // 读入前序序列
  gets(tmp_str);
  int tree_size = 0;
  for (int i = 0; i < strlen(tmp_str); ++i) {
    if (isalpha(tmp_str[i])) pre_order_tree[tree_size++] = tmp_str[i];
  }
  // 读入中序序列
  gets(tmp_str);
  tree_size = 0;
  for (int i = 0; i < strlen(tmp_str); ++i) {
    if (isalpha(tmp_str[i])) in_order_tree[tree_size++] = tmp_str[i];
  }

  // 构建二叉树
  Node root = ConstructBinTree(pre_order_tree, in_order_tree, 0, tree_size - 1,
                               0, tree_size - 1, 1);

  // 打印二叉树(逆中序遍历)
  PrintTreeWithRotation(root);

  return 0;
}

Node ConstructBinTree(char preorder[], char inorder[], int pre_lo, int pre_hi,
                      int in_lo, int in_hi, int depth) {
  Node root = (Node)malloc(sizeof(struct TreeNode));

  root->depth = depth;
  ++depth;
  root->key = preorder[pre_lo];
  // 在中序序列中找到root
  int root_index;
  for (root_index = in_lo; inorder[root_index] != root->key; ++root_index)
    ;
  int left_subtree_size = root_index - in_lo;
  int right_subtree_size = in_hi - root_index;

  if (left_subtree_size > 0) {
    root->left_child = ConstructBinTree(preorder, inorder, pre_lo + 1,
                                        pre_lo + left_subtree_size, in_lo,
                                        root_index - 1, depth);
  } else {
    root->left_child = NULL;
  }

  if (right_subtree_size > 0) {
    root->right_child = ConstructBinTree(
        preorder, inorder, pre_lo + left_subtree_size + 1,
        pre_hi - right_subtree_size + 1, root_index + 1, in_hi, depth);

  } else {
    root->right_child = NULL;
  }

  return root;
}

/**
 * @description: Anti-InOrderTraverse
 * @param {type}
 * @return:
 */
void PrintTreeWithRotation(Node bin_tree) {
  if (bin_tree) {
    if (bin_tree->right_child) {
      PrintTreeWithRotation(bin_tree->right_child);
      printf("\n");
    }

    for (int i = 0; i < bin_tree->depth; ++i) {
      printf("\t");
    }
    printf("%c\n", bin_tree->key);

    if (bin_tree->left_child) {
      PrintTreeWithRotation(bin_tree->left_child);
      printf("\n");
    }
  }
}

四、测试输入及输出

  • 测试输入1

    A B D C E F
    B D A E F C 
    

    输出1

                    C
                                    F
    
                            E
    
    
            A
                            D
    
                    B
    
  • 测试输入2

    A B D H I E J C F G
    H D I B E J A F C G
    

    输出2

                            G
    
                    C
                            F
    
    
            A
                                    J
    
                            E
    
                    B
                                    I
    
                            D
                                    H
    
  • 5
    点赞
  • 41
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值