一、二叉树的定义
二叉树(binary tree)是一个有限的节点集合,这个集合或者为空,或者由一个根节点和两棵互不相交的称为左子树(left subtree)和右子树(right subtree)的二叉树组成。
二、二叉树遍历的定义
- 二叉树的遍历是指按一定次序访问二叉树中的每个节点,且每个节点仅被访问一次。
- 在二叉树的遍历过程中不要将整棵树看成是由多个节点组成,而要看成是由根、左子树、右子树组成。
三、二叉树遍历的方法
- 前序遍历(根 -> 左子树 -> 右子树)
- 中序遍历(左子树 -> 根 -> 右子树)
- 后序遍历(左子树 -> 右子树 -> 根)
- 按层遍历:对二叉树按照从上至下,每层按照从左到右的顺序进行遍历。
四、二叉树的基本操作
- 创建一棵二叉树
- 查找二叉树中的某个值的节点
- 找二叉树中的孩子节点
- 求二叉树的高度
- 输出二叉树
- 统计二叉树中节点总数
五、二叉树的构造
- 同一棵二叉树具有唯一先序序列、中序序列、后序序列
- 任何 n(n >=0)个不同节点的二叉树,都可由它的中序序列和先序序列唯一地确定
- 任何 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);
}
二叉树进阶:二叉树反转