十七、二叉树的建立与基本操作
十七、二叉树的建立与基本操作
文章目录
- 十七、二叉树的建立与基本操作
- 题目描述
- 解题思路
- 上机代码
- 一点建议
题目描述
编写程序实现二叉树的如下操作:
- 建立二叉链表
- 二叉树的先序、中序、后序遍历
- 求二叉树的叶子结点个数
- 将二叉树中所有结点的左、右子树相互交换
输入:
按完全二叉树的层次关系给出二叉树的遍历序列(#表示虚结点,数据结点为单一字符)。
输出:
二叉树的凹入表示
二叉树的先序序列、中序序列、后序序列
二叉树叶子结点个数
左、右子树相互交换后的二叉树的凹入表示
左、右子树相互交换后的二叉树的先序序列、中序序列、后序序列。
说明:
在输出凹入表示的二叉树时,先输出根结点,然后依次输出左右子树,上下层结点之间相隔 3 个空格。
测试输入 | 期待的输出 | 时间限制 | 内存限制 | 额外进程 | |
---|---|---|---|---|---|
测试用例 1 | abc#de |
BiTree a b d c e pre_sequence : abdce in_sequence : bdaec post_sequence : dbeca Number of leaf: 2 BiTree swapped a c e b d pre_sequence : acebd in_sequence : ceadb post_sequence : ecdba |
1秒 | 64M | 0 |
测试用例 2 | abcdefg |
BiTree a b d e c f g pre_sequence : abdecfg in_sequence : dbeafcg post_sequence : debfgca Number of leaf: 4 BiTree swapped a c g f b e d pre_sequence : acgfbed in_sequence : gcfaebd post_sequence : gfcedba |
1秒 | 64M | 0 |
解题思路
二叉链表的存储表示在教材的 127 页进行了介绍
typedef struct BiTNode
{char data; //结点数据struct BiTNode *lchild, *rchild; //左右孩子指针
}BiTNode, *BiTree;
仔细阅读并理解题目,我们重点需要完成四个步骤:
- 建立一颗二叉树
- 进行二叉树的凹入表示
- 找到二叉树的前、中、后序遍历的结果
- 统计二叉树中叶子结点的个数
1、按完全二叉树的层次关系建立一颗二叉树。给出二叉树的层次序列,那么我们需要借助队列来建立这颗二叉树。(层次序列都适合用队列处理,类似于 BFS 的思想)
2、二叉树的凹入表示,按照层次关系进行输出。第一层没有空格,第二层一个 tab
(四个空格),第二层两个 tab
······
3、二叉树的三种遍历序列很适合用递归的方式来遍历求解
- 先序遍历,也叫前序遍历
- 访问根结点
- 先序遍历左子树
- 先序遍历右子树
- 中序遍历
- 中序遍历左子树
- 访问根结点
- 中序遍历右子树
- 后序遍历
- 后序遍历左子树
- 后序遍历右子树
- 访问根结点
4、统计二叉树中叶子结点个数。叶子结点的左右指针域不指向任何结点,要么是 \0
,要么是 #
,根据这个条件可以找出叶子结点。然后统计叶子结点又得遍历一遍二叉树,所以将叶子结点的统计和二叉树的其中一个遍历结合操作起来更省事。
至于左右子树交换后的各种表示,对二叉树表示的顺序进行简单的翻转就可以实现,代码的编写就是左右次序交换的问题。
例如,对二叉树的中序遍历,应该先输出左子树,接着输出该结点的值,最后输出右子树。左右子树交换后的二叉树的中序遍历,应该先输出右子树,接着输出该结点的值,最后输出左子树。
上机代码
#include<cstdio>
#include<iostream>
#include<queue>
#include<cstring>
#include<cstdlib>
#include<algorithm>
using namespace std;//二叉树的存储表示
typedef struct BiTNode
{char data;struct BiTNode *lchild;struct BiTNode *rchild;
}BiTNode, *BiTree;queue<BiTree>q; //辅助队列
int counts = 0; //统计叶子结点数目void createBiTree(); //建立二叉树
void visit(BiTree R); //访问结点
void print(BiTree R, int n); //输出二叉树
void pre_sequence(BiTree R); //先序遍历
void in_sequence(BiTree R); //中序遍历
void post_sequence(BiTree R); //后序遍历
/* 左右子树交换后的各种表示 */
void swap_print(BiTree R, int n);
void swap_pre_sequence(BiTree R);
void swap_in_sequence(BiTree R);
void swap_post_sequence(BiTree R);int main()
{BiTree bit;bit = (BiTree)malloc(sizeof(BiTNode));q.push(bit);//建树 createBiTree();//打印二叉树printf("BiTree\n");print(bit, 0);//先序 printf("pre_sequence : ");pre_sequence(bit);printf("\n");//中序 printf("in_sequence : ");in_sequence(bit);printf("\n");//后序 printf("post_sequence : ");post_sequence(bit);printf("\n");//叶子结点数目printf("Number of leaf: %d\n", counts);/* 翻转 */ printf("BiTree swapped\n");swap_print(bit, 0);printf("pre_sequence : ");swap_pre_sequence(bit);printf("\n");printf("in_sequence : ");swap_in_sequence(bit);printf("\n");printf("post_sequence : ");swap_post_sequence(bit);printf("\n");return 0;
}void createBiTree()
{char c;BiTree T, N;while (!q.empty()){scanf("%c", &c);if (c == '\n') //换行符结束读取break;T = q.front();q.pop();T->data = c; //结点赋值//左子树表示N = (BiTree)malloc(sizeof(BiTNode));N->data = '\0';T->lchild = N;q.push(N);//右子树表示N = (BiTree)malloc(sizeof(BiTNode));N->data = '\0';T->rchild = N;q.push(N);}
}
void visit(BiTree R)
{//结点不为空则输出if (R->data != '#'&&R->data != '\0')cout << R->data;
}
void print(BiTree R, int n)
{if (R->data != '#'&&R->data != '\0'){int i = 1;while (i <= n) //第几层就输几个tab{cout << " ";i++;}visit(R);cout << endl;//一层一层往下找n++;print(R->lchild, n);print(R->rchild, n);}
}
void pre_sequence(BiTree R)
{if (R->data != '#'&&R->data != '\0'){visit(R);pre_sequence(R->lchild);pre_sequence(R->rchild);}
}
void in_sequence(BiTree R)
{if (R->data != '#'&&R->data != '\0'){in_sequence(R->lchild);/* 统计叶子结点和中序遍历结合 */if ((R->lchild->data == '#' || R->lchild->data == '\0') && (R->rchild->data == '#' || R->rchild->data == '\0'))counts++;visit(R);in_sequence(R->rchild);}
}
void post_sequence(BiTree R)
{if (R->data != '#'&&R->data != '\0'){post_sequence(R->lchild);post_sequence(R->rchild);visit(R);}
}
void swap_print(BiTree R, int n)
{//翻转后的写法与原来一模一样,只是换了顺序而已if (R->data != '#'&&R->data != '\0'){int i = 1;while (i <= n){cout << " ";i++;}visit(R);cout << endl;n++;swap_print(R->rchild, n);swap_print(R->lchild, n);}
}
void swap_pre_sequence(BiTree R)
{if (R->data != '#'&&R->data != '\0'){visit(R);swap_pre_sequence(R->rchild);swap_pre_sequence(R->lchild);}
}
void swap_in_sequence(BiTree R)
{if (R->data != '#'&&R->data != '\0'){swap_in_sequence(R->rchild);visit(R);swap_in_sequence(R->lchild);}
}
void swap_post_sequence(BiTree R)
{if (R->data != '#'&&R->data != '\0'){swap_post_sequence(R->rchild);swap_post_sequence(R->lchild);visit(R);}
}
一点建议
二叉树的建立和遍历序列,在之后的学习中还会继续遇到,建议大家一定要自己总结出一个自己认为好用的模板。
比如编写一个利用层次序列建立二叉树的模板,下次又遇到的时候可以直接使用模板而不是再编写一遍。同样地,三种遍历序列的模板也是很需要的,递归方式和非递归方式都要掌握。
十七、二叉树的建立与基本操作相关推荐
- 二叉树和栈的基本操作
二叉树和栈的基本操作 Tree.h: #pragma once#define _CRT_SECURE_NO_WARNINGS#include <stdio.h> #include < ...
- C语言二叉树实验报告流程图,二叉树的建立与遍历实验报告(c语言编写,附源代码).doc...
二叉树的建立与遍历实验报告(c语言编写,附源代码).doc 第 1 页,共 9 页二叉树的建立与遍历实验报告级 班 年 月 日 姓名 学号_ 1实验题目建立一棵二叉树,并对其进行遍历(先序.中序.后序 ...
- python数据结构 树_python数据结构之二叉树的建立实例
先建立二叉树节点,有一个data数据域,left,right 两个指针域 复制代码 代码如下: # -*- coding: utf - 8 - *- class TreeNode(object): d ...
- 二叉树的建立和遍历的各种问题
链表声明: //基本结构声明 #include<iostream> #include<queue> #include<stack> #include<cstd ...
- 十六、广义表的建立与基本操作
十六.广义表的建立与基本操作 文章目录 十六.广义表的建立与基本操作 题目描述 解题思路 上机代码 补充说明 题目描述 采用"头尾法存储广义表,实现以下广义表的操作: 1.Status Cr ...
- 二叉树的建立与遍历(先中后层序)
在做一些算法题时,我会经常用到VS2017去测试,每次去找一个合适的二叉树觉得很麻烦,今天就自己写了一个放在博客上,下次就直接复制了 包含二叉树的建立,以及二叉树的前序遍历.中序遍历.后序遍历和层序遍 ...
- 二叉树的建立以及先序、中序、后序遍历C语言实现---【递归方式】
下图的二叉树作为测试例,输出前中后三种遍历方式下的结果. 先序遍历: A B D C 中序遍历: B D A C 后序遍历: D B C A #include "stdio.h" ...
- 数据结构树的基本操作_[数据结构]树的建立与基本操作 解题报告
Problem Description 在本实验中,程序的输入是一个表示树结构的广义表.假设树的根为 root ,其子树森林 F = ( T1 , T2 , ... , Tn ),设与该树对应的广义表 ...
- java 二叉树的高度_Java实现二叉树的建立、计算高度与递归输出操作示例
本文实例讲述了java实现二叉树的建立.计算高度与递归输出操作.分享给大家供大家参考,具体如下: 1. 建立 递归输出 计算高度 前中后三种非递归输出 public class Tree_Link { ...
最新文章
- c语言实验七实验报告,C语言实验七 数 实验报告.doc
- Nature综述:噬菌体的百年研究
- iOS高效开发必备的10款Objective-C类库
- mui实现手机web拍照_WEB前端开发与后端开发比较
- FileReader (三) - 网页拖拽并预显示图片简单实现
- 如何让网站用上HTML5 Manifest
- Mysql导入zabbix的sql语句时报错:ERROR 1045 (28000)
- 源代码管理的新15条建议
- 阿里云ECS上LVM磁盘配置
- 安卓百度地图附近poi搜索以及到指定poi的换乘方案
- 如何修改SharePoint服务器场管理员帐户和密码
- 信息安全系统设计基础第四周学习总结—20135227黄晓妍
- cnn训练出现的问题
- HttpClient配置
- sas9.3软件java_SAS9.3 64位版Win7安装指引
- web前端工程师岗位职责、岗位要求
- 如何快速更换证件照背景颜色
- 清朝12位皇帝简介【顺康雍乾嘉道咸同光宣】
- java的8年来工作汇总
- 计算机桌面备份在哪里,电脑备份文件在哪里
热门文章
- RESTful Web 服务 - 资源
- 主机到中继地址的发包路径
- Andriod --- JetPack (一):初识 JetPack
- Java 洛谷 提交完题目的代码之后一直停留在 ( 正在等待编译……),刷新页面之后 ,显示 Unaccepted 0分
- 【阿里云 Linux 服务器】在阿里云购买的 Linux 或者 Windows 服务器,在用 putty 访问的时候不知道用户名密码怎么办?
- linux设置脚本开机启动centos7,centos7设置开机启动
- java 循环依赖_java – 如何在Gradle中解决循环依赖
- 特斯拉:已在中国建立数据中心,以实现数据存储本地化
- 通过options探测服务器信息,OPTIONS 方法在跨域请求(CORS)中的应用
- radio按扭设置只读_disabled属性样式问题