声明:本篇博客的图来源于: https://blog.csdn.net/qq_35433716/article/details/89710720
一、相关名词说明
度:结点拥有的子树数;(树的度是树内各节点的度的最大值)
叶节点或终端结点:度为0的结点
非终端结点或分支节点:度不为0的结点;
二、二叉树的定义
二叉树是n个结点的有限集合,该集合或者为空集(称为空二叉树),或者由一个根结点和两棵互不相交的、分别称为根节点的左子树和右子树组成。
三、二叉树的特点
1、每个结点最多由两颗子树;
2、左子树和右子树是有顺序的;
3、二叉树的五种形态:
图3-1
四、特殊二叉树
1、斜树
左斜树:所有的结点都只有左子树的二叉树,如图3-1的(3);
右斜树:所有的结点都只有右子树的二叉树,如图3-2的(4);
2、满二叉树
定义:在一棵二叉树中,所有的分支结点都存在左子树和右子树,并且所有叶子都在同一层中,如图4-1所示。
图4-1 满二叉树
3、完全二叉树
定义:对一根具有n个结点的二叉树按层序编号,如果序号为i(1<=i<=n)的结点与同样深度的满二叉树中编号为i的结点在二叉树中的位置完全相同,则这颗二叉树称为完全二叉树,如图4-2所示。
特点:(1)叶子结点只能出现在最下两层;(2)最下层的叶子一定集中在左部连续位置;(3)倒数二层,若有叶子结点,一定在右部连续位置;(4)如果结点度为1,则该结点只有左孩子;(5)同样结点树的二叉树,完全二叉树的深度最小。
图4-2 完全二叉树
五、二叉树性质
六、二叉树存储结构
1、顺序存储结构:只适用于完全二叉树
2、二叉链表:包括data:数据域,lchild:左孩子指针域,rchild:右孩子指针域
template<typename T>
class treeNode
{
T data;
treename *lchild, *rchild;
};
七、遍历二叉树
定义:二叉树的遍历是指从根结点出发,按照某种次序依次访问二叉树中所有结点,使得每个结点被访问一次且仅被访问一次。
遍历方法:
1、前序遍历
若二叉树非空,则执行以下操作
(1)访问根结点;
(2)先序遍历左子树;
(3)先序遍历右子树。
2、中序遍历
若二叉树非空,则执行以下操作
(1)中序遍历左子树;
(2)访问根结点;
(3)中序遍历右子树。
3、后序遍历
若二叉树非空,则执行以下操作
(1)后序遍历左子树;
(2)后序遍历右子树;
(3)访问根节点。
4、层序遍历
若二叉树非空,则从树的根结点开始,从上而下逐层遍历,在同一层中,按从左到右的顺序对结点逐个访问。
八、二叉树C++实现
以下代码参考自:https://blog.csdn.net/Ajay666/article/details/76736333
#include <iostream>
#include <string>
using namespace std;
class treeNode
{
public:
char data;
treeNode *lchild, *rchild;
};
class tree
{
public:
private:
treeNode *root;
int height; //树高
void pre_order(treeNode *t);
void in_order(treeNode *t);
void post_order(treeNode *t);
treeNode *create(string &s, int &pos);
void get_height(treeNode *t, int h);
public:
tree(){ root = NULL; height = 0; }
void createtree(string &s);
void preorder();
void inorder();
void postorder();
int getheight();
};
//递归创建二叉树,如果是#则表示空结点
treeNode* tree::create(string &s, int &pos)
{
++pos;
treeNode *t;
if ((unsigned)pos >= s.size())
{
return NULL;
}
else
{
if (s[pos] == '#')
{
t = NULL;
}
else
{
t = netreeNode; //分配内存空间
t->data = s[pos];
t->lchild = create(s, pos);
t->rchild = create(s, pos);
}
return t;
}
}
//按照前序遍历创建二叉树
void tree::createtree(string &s)
{
int pos = -1;
root=create(s, pos);
}
//前序遍历二叉树
void tree::preorder()
{
pre_order(root);
cout << endl;
}
void tree::pre_order(treeNode *t)
{
if (t != NULL)
{
cout << t->data << " ";
pre_order(t->lchild);
pre_order(t->rchild);
}
}
//中序遍历二叉树
void tree::inorder()
{
in_order(root);
cout << endl;
}
void tree::in_order(treeNode *t)
{
if (t != NULL)
{
in_order(t->lchild);
cout << t->data << " ";
in_order(t->rchild);
}
}
//后序遍历二叉树
void tree::postorder()
{
post_order(root);
cout << endl;
}
void tree::post_order(treeNode *t)
{
if (t != NULL)
{
post_order(t->lchild);
post_order(t->rchild);
cout << t->data << " ";
}
}
//求树的高度
void tree::get_height(treeNode *t, int h)
{
if (t != NULL)
{
h++;
if (h > height)
{
height = h;
}
get_height(t->lchild, h);
get_height(t->rchild, h);
}
}
int tree::getheight()
{
get_height(root, 0);
cout <<"树的高度:"<< height << endl;
return height;
}
int main()
{
string s1= "ABD##E#F##C##";
tree t1;
t1.createtree(s1); //创建树
t1.preorder(); //前序遍历树
t1.inorder(); //中序遍历树
t1.postorder(); //后序遍历树
t1.getheight(); //树高度
system("pause");
return 0;
}