树结构是一种比线性结构(例如:线性表、栈、队列等)复杂的数据结构,但是树结构在计算机领域中有着广泛的应用。二叉树是一种最简单的树结构,下面分析以二叉树为研究对象。
结点的度、树的度:某个结点拥有子树的个数,我们称之为某结点的度;而在一棵树中的某结点有最多的子树,该结点的度我们称之为树的度。
结点的层数、树的深度(高度)、树的宽度:记根结点的层数为1,结点的层数通过从根结点开始计数得到;树中所有结点的最大层数称之为树的深度(高度);树中某一层结点的个数的最大值称之为树的宽度。
满二叉树:在二叉树中,所有分支的结点都有左右子树,而且所有叶子结点都分布在同一层,我们称之为满二叉树。
完全二叉树:深度为k的完全二叉树在k-1层是满二叉树,叶子结点只出现在最下两层,并且最下层叶子要分布在左侧连续的位置,如下图所示。
二叉树的一些重要性质:
1.在二叉树中,叶子结点的个数记为 ,度为2的结点个数记为
,则满足等式:
;
2.二叉树的第 层有
个结点;
3.深度为 的二叉树,最多有
个结点;
4.具有 个结点的完全二叉树的深度为
;
二叉树的遍历(前序遍历、中序遍历、后序遍历、层序遍历)
可以用一个结构体来描述二叉树中的结点信息,程序如下所示。
template <typename datatype>
struct bi_node
{
datatype data;
bi_node<datatype>* rchild;
bi_node<datatype>* lchild;
};
1.前序遍历
//前序遍历的递归形式遍历
template <typename datatype>
void preorder(bi_node<datatype>* bt)
{
if (bt == NULL)
return;
else
{
cout << bt->data << " ";
preorder(bt->lchild);
preorder(bt->rchild);
}
}
//前序遍历的非递归形式遍历
template <typename datatype>
void preorder(bi_node<datatype>* root)//输入二叉链表的根指针
{
bi_node<datatype>* bt = root;
bi_node<datatype>* s[20];//定义顺序栈,最多20个结点指针
int top = -1;//顺序栈初始化,指向栈顶
while (bt != NULL || top != -1)
{
while (bt != NULL)
{
cout << bt->data << " ";
s[++top] = bt;
bt = bt->lchild;
}
if (top != -1)//栈非空
{
bt = s[top--];
bt = bt->rchild;
}
}
}
2.中序遍历
//中序遍历的递归形式遍历
template <typename datatype>
void midorder(bi_node<datatype>* bt)
{
if (bt == NULL)
return;
else
{
midorder(bt->lchild);
cout << bt->data << " ";
midorder(bt->rchild);
}
}
//中序遍历的非递归形式遍历
template <typename datatype>
void midorder(bi_node<datatype>* root)//输入二叉链表的根指针
{
bi_node<datatype>* bt = root;
bi_node<datatype>* s[20];//定义顺序栈,最多20个结点指针
int top = -1;//顺序栈初始化,指向栈顶
while (bt != NULL || top != -1)
{
while (bt != NULL)
{
s[++top] = bt;
bt = bt->lchild;
}
if (top != -1)//栈非空
{
bt = s[top--];
cout << bt->data << " ";
bt = bt->rchild;
}
}
}
3.后序遍历
//后序遍历的递归形式遍历
template <typename datatype>
void postorder(bi_node<datatype>* bt)
{
if (bt == NULL)
return;
else
{
postorder(bt->lchild);
postorder(bt->rchild);
cout << bt->data << " ";
}
}
template <typename datatype>
struct element
{
bi_node<datatype>* ptr;
int flag;
};
//后序遍历的非递归形式遍历
template <typename datatype>
void postorder(bi_node<datatype>* root)//输入二叉链表的根指针
{
bi_node<datatype>* bt = root;
element s[20];//定义顺序栈,最多20个元素
int top = -1;//顺序栈初始化,指向栈顶
while (bt != NULL || top != -1)
{
while (bt != NULL)
{
++top;
s[top].ptr = bt;//bt连同标志flag入栈
s[top].flag = 1;
bt = bt->lchild;
}
if (top != -1 && s[top].flag == 2)
{
bt = s[top--].ptr;
cout << bt->data << " ";
}
if (top != -1)
{
s[top].flag = 2;
bt = s[top].ptr->rchild;
}
}
}
4.层序遍历
template <typename datatype>
void levelorder(bi_node<datatype>* root)
{
bi_node<datatype>* Queue[20], * q = NULL;
int front = -1, rear = -1;//队列进行初始化
if (root == NULL)
return;
Queue[++rear] = root;//根指针入队
while (front != rear)//当队列非空时
{
q = Queue[++front];//出队
cout << q->data << " ";
if (q->lchild != NULL)
Queue[++rear] = q->lchild;
if (q->rchild == NULL)
Queue[++rear] = q->rchild;
}
}