二叉树(Binary Tree)是n(n不小于0)个节点组成的有限集合,且满足以下条件之一
(1)n=0时,为空二叉树(无节点)
(2)n>0时,为非空二叉树,由一个根节点和两颗互不相交的子树(左子树,右子树)的二叉树构成
所有节点只有左子树或者右子树的二叉树
深度为k,具有2^k-1个节点的二叉树
具有n个节点,深度为k的二叉树,并且层次编号为i的节点与同样深度的满二叉树的编号为i的节点位置完全相同
struct Bt_Node
{
T Data;//节点数据,T为数据类型
Bt_Node* Left_Child;//左孩子节点
Bt_Node* Right_Child;//右孩子节点
};
采用先序遍历的方法构造二叉树
int Binary_tree::Create_BTree(Bt_Node* &Tree) //为了递归实现构造,将私有数据Tree作为该创建递归函数的引用参数
{
T data;
cin >> data;
if (data == -1) //-1代表空树
Tree = NULL;
else
{
Tree = new Bt_Node;
Tree->Data = data;
Create_BTree(Tree->Left_Child);//创建左子树
Create_BTree(Tree->Right_Child);//创建右子树
}
return 0;
}
和链表一样,从上的节点开始释放节点空间,注意保存该节点左右子树的节点地址
int Binary_tree::Distory_BTree(Bt_Node* &Tree)
{
if (Tree) //该根节点非空
{
//cout << Tree->Data << endl;
Bt_Node* Left_Tree = Tree->Left_Child;
Bt_Node* Right_Tree = Tree->Right_Child;
delete Tree;
if (Left_Tree) //左子树非空则释放
Distory_BTree(Left_Tree);
if (Right_Tree) //同
Distory_BTree(Right_Tree);
}
return 0;
}
(1)访问根节点 (2)先序遍历左子树 (3)先序遍历右子树
上图的先序遍历结果:1 2 3 4 5 6
template
void Binary_tree::PreOrder_Op(Bt_Node* &Tree)
{
if (Tree)
{
cout << Tree->Data << endl; //先访问根节点
PreOrder_Op(Tree->Left_Child); //访问左子树
PreOrder_Op(Tree->Right_Child); //访问右子树
}
}
(1)中序遍历左子树 (2)访问根节点 (3)中序遍历右子树
上图的先序遍历结果:3 2 4 1 6 5
template
void Binary_tree::InOrder_Op(Bt_Node* &Tree)
{
if (Tree)
{
InOrder_Op(Tree->Left_Child); //访问左子树
cout << Tree->Data << endl; //访问根节点
InOrder_Op(Tree->Right_Child); //访问右子树
}
}
(1)后序遍历左子树 (2)后序遍历右子树 (3)访问根节点
上图的先序遍历结果:3 4 2 6 5 1
template
void Binary_tree::PostOrder_Op(Bt_Node* &Tree)
{
if (Tree)
{
PostOrder_Op(Tree->Left_Child); //访问左子树
PostOrder_Op(Tree->Right_Child); //访问右子树
cout << Tree->Data << endl; //访问根节点
}
}
从上到下逐层遍历根节点
上图的先序遍历结果:1,2 5, 3 4 6
层次遍历采用的方法是穷举加递归,先行用i代表所要寻找的层数(从0开始),利用放回值判断该层是否存在
template
int Binary_tree::LevelOrder_Op(Bt_Node* &Tree, int Level)
{
if (Level < 0 || !Tree)//该层的根节点为空或者没有找到该层,返回0
return 0;
if (Level == 0)//该层根节点不空
{
cout << Tree->Data << " ";
return 1; //访问该节点并返回
}
return LevelOrder_Op(Tree->Left_Child, Level - 1), LevelOrder_Op(Tree->Right_Child, Level - 1);
//还没有到所要访问的层次,从左子树开始往下一层开始检测节点
}
template
void Binary_tree::LevelOrder()
{
for (int i = 0;; i++) //穷举树的度数(从0开始算)
{
if (!LevelOrder_Op(Tree, i)) //递归结果为0表示第i层不存在,即树的深度为i,树的根节点为0
break;
cout << endl;
}
cout << endl;
}
个人觉得递归遍历二叉树在实现上或者脑补上都是挺简单的,递归是一个从宏逐步细化的过程!
以中序遍历举个荔枝,每次递归都是重复:左树,根节点,右树。那从整棵树去看,就是先遍历左数(3,2,4),然后访问根节点(1),再而是右树(5,6);然后细化,进入左树(3,2,4),那么从左,中,右遍历就是 3, 2 , 4,左树(3,2,4)遍历完了,回到根节点(1),然后右树(5,6),访问该右树的左(6),根(5),右(空),至此完成整个遍历。总之递归就是一个从宏到一个方向的细分然后再回到宏的过程。
(1)采用类模板,为了增加程序数据的兼容性
(2)将创建,删除,遍历的递归操作全部私有化,因为递归函数传参肯定用到根节点,私有操作加接口防止树节点被类外读取。
#include
using namespace std;
template
struct Bt_Node
{
T Data;
Bt_Node* Left_Child;
Bt_Node* Right_Child;
};
template
class Binary_tree
{
private:
Bt_Node *Tree;
/*内部实现函数*/
int Create_BTree(Bt_Node* &Tree); //创建二叉树(构造内调用)
int Distory_BTree(Bt_Node* &Tree); //析构二叉树的递归子函数(在析构内调用)
int LevelOrder_Op(Bt_Node* &Tree,int Level); //层次遍历的递归子函数
void PreOrder_Op(Bt_Node* &Tree); //先序遍历(递归实现函数)
void InOrder_Op(Bt_Node* &Tree); //中序遍历(递归实现函数)
void PostOrder_Op(Bt_Node* &Tree); //后序遍历(递归实现函数)
public:
/*接口函数*/
Binary_tree(); //类构造
~Binary_tree(); //析构
void PreOrder(); //先序遍历
void InOrder(); //中序遍历
void PostOrder();
void LevelOrder(); //层次遍历
};
#include
using namespace std;
template
struct Bt_Node
{
T Data;
Bt_Node* Left_Child;
Bt_Node* Right_Child;
};
template
class Binary_tree
{
private:
Bt_Node *Tree;
/*内部实现函数*/
int Create_BTree(Bt_Node* &Tree); //创建二叉树(构造内调用)
int Distory_BTree(Bt_Node* &Tree); //析构二叉树的递归子函数(在析构内调用)
int LevelOrder_Op(Bt_Node* &Tree,int Level); //层次遍历的递归子函数
void PreOrder_Op(Bt_Node* &Tree); //先序遍历(递归实现函数)
void InOrder_Op(Bt_Node* &Tree); //中序遍历(递归实现函数)
void PostOrder_Op(Bt_Node* &Tree); //后序遍历(递归实现函数)
public:
/*接口函数*/
Binary_tree(); //类构造
~Binary_tree(); //析构
void PreOrder(); //先序遍历
void InOrder(); //中序遍历
void PostOrder();
void LevelOrder(); //层次遍历
};
/******************* * * * * * * * * * * * * * * * * * * ********************/
/*
二叉树创建,遍历,删除的内部递归函数
后缀为 _Op
*/
// /**********/
/*
1.Create_Btree :先序遍历构造二叉树
2.Distory_BTree :二叉树的析构
*/
template
int Binary_tree::Create_BTree(Bt_Node* &Tree) //为了递归实现构造,将私有数据Tree作为该创建递归函数的引用参数
{
T data;
cin >> data;
if (data == -1) //"#"代表空树
Tree = NULL;
else
{
Tree = new Bt_Node;
Tree->Data = data;
Create_BTree(Tree->Left_Child);//创建左子树
Create_BTree(Tree->Right_Child);//创建右子树
}
return 0;
}
template
int Binary_tree::Distory_BTree(Bt_Node* &Tree)
{
if (Tree) //该根节点非空
{
//cout << Tree->Data << endl;
Bt_Node* Left_Tree = Tree->Left_Child;
Bt_Node* Right_Tree = Tree->Right_Child;
delete Tree;
if (Left_Tree) //左子树非空则释放
Distory_BTree(Left_Tree);
if (Right_Tree) //同
Distory_BTree(Right_Tree);
}
return 0;
}
/*
***********End******
*/
// /* 遍历实现 */
/*
1.PreOrder_Op : 先序遍历
2.InOrder_Op :中序遍历
3.PostOrder_Op :后序遍历
4.LevelOrder_Op:层次遍历
*/
template
void Binary_tree::PreOrder_Op(Bt_Node* &Tree)
{
if (Tree)
{
cout << Tree->Data << endl; //先访问根节点
PreOrder_Op(Tree->Left_Child); //访问左子树
PreOrder_Op(Tree->Right_Child); //访问右子树
}
}
template
void Binary_tree::InOrder_Op(Bt_Node* &Tree)
{
if (Tree)
{
InOrder_Op(Tree->Left_Child); //访问左子树
cout << Tree->Data << endl; //访问根节点
InOrder_Op(Tree->Right_Child); //访问右子树
}
}
template
void Binary_tree::PostOrder_Op(Bt_Node* &Tree)
{
if (Tree)
{
PostOrder_Op(Tree->Left_Child); //访问左子树
PostOrder_Op(Tree->Right_Child); //访问右子树
cout << Tree->Data << endl; //访问根节点
}
}
template
int Binary_tree::LevelOrder_Op(Bt_Node* &Tree, int Level)
{
if (Level < 0 || !Tree)//该层的根节点为空或者没有找到该层,返回0
return 0;
if (Level == 0)//该层根节点不空
{
cout << Tree->Data << " ";
return 1; //访问该节点并返回
}
return LevelOrder_Op(Tree->Left_Child, Level - 1), LevelOrder_Op(Tree->Right_Child, Level - 1);
//还没有到所要访问的层次,从左子树开始往下一层开始检测节点
}
/*End*/
/******************* * * * * * * * * * * * * * * * * * * ********************/
/******************* * * * * * * * * * * * * * * * * * * ********************/
/*外部接口函数*/
//
//构造
template
Binary_tree::Binary_tree()
{
Create_BTree(Tree);
}
//析构
template
Binary_tree::~Binary_tree()
{
Distory_BTree(Tree);
}
//End
/*
1.PreOrder : 先序遍历
2.InOrder :中序遍历
3.PostOrder :后序遍历
4.LevelOrder:层次遍历
*/
template
void Binary_tree::PreOrder()
{
PreOrder_Op(Tree);
}
template
void Binary_tree::InOrder()
{
InOrder_Op(Tree);
}
template
void Binary_tree::PostOrder()
{
PostOrder_Op(Tree);
}
template
void Binary_tree::LevelOrder()
{
for (int i = 0;; i++) //穷举树的度数(从0开始算)
{
if (!LevelOrder_Op(Tree, i)) //递归结果为0表示第i层不存在,即树的深度为i,树的根节点为0
break;
cout << endl;
}
cout << endl;
}
/******************* * * * * * * * * * * * * * * * * * * ********************/
// /* 类结束 */ //
日常BB:四十几天没有更文,也是自己有点懒,放假了后面我尽量多出文吧~
预告:二叉树非递归实现
传送门:待续~