数据结构与算法8(二叉树构造、遍历)

一、二叉树的定义

二叉树(binary tree)是一个有限的节点集合,这个集合或者为空,或者由一个根节点和两棵互不相交的称为左子树(left subtree)和右子树(right subtree)的二叉树组成。

二、二叉树遍历的定义
  1. 二叉树的遍历是指按一定次序访问二叉树中的每个节点,且每个节点仅被访问一次。
  2. 在二叉树的遍历过程中不要将整棵树看成是由多个节点组成,而要看成是由根、左子树、右子树组成。
三、二叉树遍历的方法
  1. 前序遍历(根 -> 左子树 -> 右子树)
  2. 中序遍历(左子树 -> 根 -> 右子树)
  3. 后序遍历(左子树 -> 右子树 -> 根)
  4. 按层遍历:对二叉树按照从上至下,每层按照从左到右的顺序进行遍历。
四、二叉树的基本操作
  1. 创建一棵二叉树
  2. 查找二叉树中的某个值的节点
  3. 找二叉树中的孩子节点
  4. 求二叉树的高度
  5. 输出二叉树
  6. 统计二叉树中节点总数
五、二叉树的构造
  1. 同一棵二叉树具有唯一先序序列、中序序列、后序序列
  2. 任何 n(n >=0)个不同节点的二叉树,都可由它的中序序列和先序序列唯一地确定
  3. 任何 n(n>=0)个不同节点的二叉树,都可由它的中序序列和后序序列唯一地确定
六、实验

现有头文件BiTree.h

#include <iostream>
using namespace std;

typedef char ElemType;

typedef struct node {
	ElemType data; //数据域
	struct node* left;
	struct node* right; //结点的左右子树指针
} BTNode; //二叉树结点类型

//初始化空二叉树
void InitBTree(BTNode*& root);

//按照前序遍历序列建立二叉树
void CreateBTree_Pre(BTNode*& root, ElemType Array[]);

//前序遍历二叉树
void PreOrder(BTNode* root);

//计算二叉树深度
int BTreeDepth(BTNode* root);

//释放二叉树中所有结点
void ClearBTree(BTNode*& root);

//按照中序遍历序列建立二叉树
void InOrder(BTNode* root);

//按照后序遍历序列建立二叉树
void PostOrder(BTNode* root);

//统计二叉树中结点总数
int BTreeCount(BTNode* root);

//查找二叉树中值为item的结点
BTNode* FindBTree(BTNode* root, ElemType item);

接口实现源文件BiTree.cpp

#include "BiTree.h"

//初始化空二叉树
void InitBTree(BTNode*& root)
{
	root = NULL;
}

//计算二叉树深度
int BTreeDepth(BTNode* root)
{
	static int CALL = 0; //记录调用次数
	static int RETURN = 0; //记录返回次数

	CALL++; //调用次数加一

	if (root == NULL) {
		RETURN++; //返回次数加一
		return 0;
	}
	else {
		int depl = BTreeDepth(root->left);
		int depr = BTreeDepth(root->right);
		if (depl > depr) {
			RETURN++; //返回次数加一
			return depl + 1;
		}
		else {
			RETURN++; //返回次数加一
			return depr + 1;
		}
	}
}

//释放二叉树中所有结点
void ClearBTree(BTNode*& root)
{
	if (root != NULL) {
		ClearBTree(root->left);
		ClearBTree(root->right);
		delete root;
		root = NULL;
	}
}

源文件content.cpp

#include "BiTree.h"

int main()
{
	BTNode* root;
	ElemType A[] = "ABD##E##CF#G###"; //以"#"补全空分支后的前序遍历序列


	InitBTree(root); //初始化空二叉树
	CreateBTree_Pre(root, A); //以前序遍历序列建立二叉树

	cout << "前序遍历序列:";
	PreOrder(root); //输出前序遍历序列
	cout << endl;

	
	//cout << "中序遍历序列:";
	//InOrder(root); //输出中序遍历序列
	//cout << endl;

	//cout << "后序遍历序列:";
	//PostOrder(root); //输出后序遍历序列
	//cout << endl;
	
	cout << "深度:" << BTreeDepth(root) << endl; //计算二叉树深度

	ClearBTree(root);
	return 0;
}

在这里插入图片描述
如上图所示:
1)写出前序、中序和后序遍历序列
前序:ABDECFG
中序:DBEAFGC
后序:DEBGFCA

2)分别写出单分支结点和叶子结点
单分支:C、F
叶子:D、E、G

3)以(#号)补全单分支结点和叶子结点的空分支

4)写出补全空分支(#号)后二叉树的前序遍历序列

	ABD##E##CF#G###

5)在BiTree项目的main()函数中,将第4)小题的带#号的前序遍历序列作为数组A[ ]的值,并执行程序,以理解CreateBTree_Pre( )函数的递归建树的过程。

//按照前序遍历序列建立二叉树
void CreateBTree_Pre(BTNode*& root, ElemType Array[])
{
	static int count = 0; //静态变量count
	char item = Array[count]; //读取Array[]数组中的第count个元素
	count++;
	if (item == '#') { //如果读入#字符,创建空树
		root = NULL;
	}
	else {
		root = new BTNode; //建根结点
		root->data = item;
		CreateBTree_Pre(root->left, Array); //建左子树
		CreateBTree_Pre(root->right, Array); //建右子树
	}
}

6)在BiTree项目中添加二叉树的前序、中序、后序遍历接口,并在主函数中进行验证。
前序遍历:PreOrder(BTNode* root)

//前序遍历二叉树
void PreOrder(BTNode* root)
{
	if (root != NULL) {
		cout << root->data; //访问根
		PreOrder(root->left); //前序遍历左子树
		PreOrder(root->right); //前序遍历右子树
	}
}

中序遍历:void InOrder (BTNode *root)

//按照中序遍历序列建立二叉树
void InOrder(BTNode* root) {
	if (root != NULL) {
		InOrder(root->left);
		cout << root->data;
		InOrder(root->right);
	}
}

后序遍历:void PostOrder (BTNode *root)

//按照后序遍历序列建立二叉树
void PostOrder(BTNode* root) {
	if (root != NULL) {
		PostOrder(root->left);
		PostOrder(root->right);
		cout << root->data;
	}
}

7)关于二叉树遍历的另外两个应用:
A)统计二叉树中结点总数
int BTreeCount(BTNode* root)

//统计二叉树中结点总数
int BTreeCount(BTNode* root) {
	if (root == NULL)
		return 0; //空树的结点数为0
	else
		return BTreeCount(root->left) +
		BTreeCount(root->right) + 1;
}

B)查找二叉树中值为item的结点
BTNode* FindBTree(BTNode* root, ElemType item)

//查找二叉树中值为item的结点
BTNode* FindBTree(BTNode* root, ElemType item) {
	if (root == NULL)  return NULL;

	if (root->data == item)  return root;
	BTNode* p = FindBTree(root->left, item);
	if (p != NULL)
		return p;
	else
		return FindBTree(root->right, item);
}

二叉树进阶:二叉树反转

  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值