前言
本文主要内容:
1.对于二叉树的基本操作,创建 、遍历 、前序、中序、后序输出等
2.关于二叉树的自己的体会
提示:以下是本篇文章正文内容,下面案例可供参考
一、二叉树是什么?
二叉树是数据结构中的一种,可以通过顺序表或者链表的形式实现,接下来让我们一起来看看如何通过顺序表或者链表的形式来实现二叉树
二叉树图:
二、二叉树的创建(以顺序表的形式)
1.先创建数组(为了顺序表做准备)
代码如下(示例):
#define MAX_SIZE 100 typedef char TElemType; typedef TElemType SqBiTree[MAX_SIZE]; TElemType Nil = '#'; 我们规定当元素数值为 ‘#’ 的时候表示该节点为NULL
2.输入数值
代码如下(示例):
void input(TElemType* x) { scanf("%c", &x); } 简单明了的传参 TElemType也就是char类型的变量 x
3.输出数值
void visit(TElemType x) { printf("%c", x); }
4.创建空二叉树并在二叉树中输入数值
void InitBiTree(SqBiTree T) { //构造空二叉树 for (int i = 0; i < MAX_SIZE; i++) { T[i] = Nil;//初始值为空 #表示为空 } } void CreateBiTree(SqBiTree T) { int i = 1;//按照层次次序输入二叉树中结点的值 scanf("%s", T + 1); while (T[i]!='\0') { i++; } T[i] = '#'; }
5.判断是否为空二叉树
int BiTreeEmpty(SqBiTree T) { //初始条件:二叉树T存在。操作结果为:若T为空二叉树,则返回true 否则false if (T[1] == Nil) { return 1;//空 } else { return 0; } }
6.返回二叉树的深度
//返回二叉树的深度 int BiTreeDepth(SqBiTree T) { int i = MAX_SIZE - 1; while (T[i] == '#') { i--; } //现在得到的i是存储元素的最后一位 int j = i; int dep = 0; while (j >= 1) { dep++; j = j / 2;//根据的是树的深度为 【log2n】+1 } return dep; }
7.先序遍历输出二叉树
这里的先序遍历是通过二叉树的一个性质来输出的,二叉树的性质之一:把完全二叉树的节点按照顺序写好对应坐标之后,i 节点的左右孩子的坐标位置分别为 2 * i 和 2 * i + 1;
void PreTraverse(SqBiTree T, int e) { if (T[e] != '#') { visit(T[e]); PreTraverse(T, 2 * e); PreTraverse(T, 2 * e + 1);//遍历输出结点 左子树 右子树 } } 这个函数就涉及到二叉树的一个性质 通过2*e和2*e+1来进行遍历 void PreOrderTraverse(SqBiTree T) { //先序遍历 if (!BiTreeEmpty(T)) { //非空就调用PreTraverse PreTraverse(T, 1);//从第一个元素就开始 } printf("\n"); }
8.中序遍历输出二叉树
void InTraverse(SqBiTree T, int e) { //中序遍历使用 if (T[e] != '#') { InTraverse(T, 2 * e); visit(T[e]); InTraverse(T, 2 * e + 1);//中序遍历,先左后中再右 } } void InOrderTreaverse(SqBiTree T) { if (!BiTreeEmpty(T)) { InTraverse(T, 1); } printf("\n"); }
9.后序遍历输出二叉树
//后序遍历 void PostTreaverse(SqBiTree T, int e) { if (T[e] != '#') { PostTreaverse(T, e * 2); PostTreaverse(T, e * 2 + 1); visit(T[e]); } } void PostOrderTraverse(SqBiTree T) { if (!BiTreeEmpty(T)){ PostTreaverse(T, 1); } printf("\n"); }
10.层序遍历输出二叉树
//层序遍历二叉树 void LevelOrderTraverse(SqBiTree T) { int dep = BiTreeDepth(T); int tree_max = pow(dep, 2) - 1;//得到当前深度下完全二叉树应该有多少结点 for (int i = 1; i < tree_max; i++) { if (T[i] == '#') { continue; }//不用输出‘#’ 而且获得的深度来看,不需要for很多没有价值的 下标 牛逼 visit(T[i]); } }
11.总结:(全部代码实现)
#define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #include<stdlib.h> #include<string.h> #include<math.h> //使用顺序结构完成二叉树的基本操作 //编写前序、中序、后序以及层次顺序遍历二叉树的算法,并计算二叉树的深度、所有的结点数 #define MAX_SIZE 100 typedef char TElemType; typedef TElemType SqBiTree[MAX_SIZE]; TElemType Nil = '#'; void input(TElemType* x) { scanf("%c", &x); } void visit(TElemType x) { printf("%c", x); } void InitBiTree(SqBiTree T) { //构造空二叉树 for (int i = 0; i < MAX_SIZE; i++) { T[i] = Nil;//初始值为空 #表示为空 } } void CreateBiTree(SqBiTree T) { int i = 1;//按照层次次序输入二叉树中结点的值 scanf("%s", T + 1); while (T[i]!='\0') { i++; } T[i] = '#'; } int BiTreeEmpty(SqBiTree T) { //初始条件:二叉树T存在。操作结果为:若T为空二叉树,则返回true 否则false if (T[1] == Nil) { return 1;//空 } else { return 0; } } //返回二叉树的深度 int BiTreeDepth(SqBiTree T) { int i = MAX_SIZE - 1; while (T[i] == '#') { i--; } //现在得到的i是存储元素的最后一位 int j = i; int dep = 0; while (j >= 1) { dep++; j = j / 2;//根据的是树的深度为 【log2n】+1 } return dep; } void PreTraverse(SqBiTree T, int e) { if (T[e] != '#') { visit(T[e]); PreTraverse(T, 2 * e); PreTraverse(T, 2 * e + 1);//遍历输出结点 左子树 右子树 } } void PreOrderTraverse(SqBiTree T) { //先序遍历 if (!BiTreeEmpty(T)) { //非空就调用PreTraverse PreTraverse(T, 1);//从第一个元素就开始 } printf("\n"); } void InTraverse(SqBiTree T, int e) { //中序遍历使用 if (T[e] != '#') { InTraverse(T, 2 * e); visit(T[e]); InTraverse(T, 2 * e + 1);//中序遍历,先左后中再右 } } void InOrderTreaverse(SqBiTree T) { if (!BiTreeEmpty(T)) { InTraverse(T, 1); } printf("\n"); } //后序遍历 void PostTreaverse(SqBiTree T, int e) { if (T[e] != '#') { PostTreaverse(T, e * 2); PostTreaverse(T, e * 2 + 1); visit(T[e]); } } void PostOrderTraverse(SqBiTree T) { if (!BiTreeEmpty(T)){ PostTreaverse(T, 1); } printf("\n"); } //层序遍历二叉树 void LevelOrderTraverse(SqBiTree T) { int dep = BiTreeDepth(T); int tree_max = pow(dep, 2) - 1;//得到当前深度下完全二叉树应该有多少结点 for (int i = 1; i < tree_max; i++) { if (T[i] == '#') { continue; }//不用输出‘#’ 而且获得的深度来看,不需要for很多没有价值的 下标 牛逼 visit(T[i]); } } int main() { TElemType e; SqBiTree Bt; InitBiTree(Bt); CreateBiTree(Bt); printf("先序遍历结果为:"); PreOrderTraverse(Bt); printf("中序遍历结果为:"); InOrderTreaverse(Bt); printf("后序遍历结果为:"); PostOrderTraverse(Bt); LevelOrderTraverse(Bt); return 0; }