==二叉树(Binary Tree)是n(n ≥ 0)个节点有限集合。==当n=0时,称为空二叉树,当n>0时,该集合有一个根节点及互不可交的,分别被称为左子树和右子树的二叉树组成。
二叉树可以被理解为一下两个条件的树型结构。
typedef int myType;
typedef struct treeNode
{
myType element; //值域元素
struct treeNode *lchild; //左孩子
struct treeNode *rchild; //右孩子
}Btree;
递归创建一个二叉树
void createTree(Btree **T) //传入一个Btree的指针的地址
{
myType data;
scanf("%d", &data);
if(data == -1) { //-1代表终端节点值
*T = NULL;
} else {
*T = (Btree *)malloc(sizeof(struct treeNode));
(*T)->element = data;
printf("请输入%d的左孩子节点:", data);
createTree(&((*T)->lchild));
printf("请输入%d的右孩子节点:", data);
createTree(&((*T)->rchild));
}
}
void preOrder(Btree *T)
{
if(T != NULL) {
printf("%d ", T->element); //访问根节点
preOrder(T->lchild); //先根序遍历左子树
preOrder(T->rchild); //先根序遍历右子树
}
}
void inOrder(Btree *T)
{
if(T != NULL) {
inOrder(T->lchild); //中根序遍历左子树
printf("%d ", T->element); //访问根节点
inOrder(T->rchild); //中根序遍历右子树
}
}
void postOrder(Btree *T)
{
if(T != NULL) {
postOrder(T->lchild); //后根序遍历左子树
postOrder(T->rchild); //后根序遍历右子树
printf("%d ", T->element); //访问根节点
}
}
==对于二叉树递归遍历的时间复杂度均为O(n)。==
层次遍历的特点是:先访问的节点其孩子也将先访问,后访问的节点其孩子也将后访问,这与队列操作的特点类似,因此应用队列进行节点的访问次序控制。下面层次遍历的代码会引用到这篇文章中的队列数据结构的相关接口:队列的实现
利用队列遍历的层次思想是:
首先根节点入队,当队列非空时,重复如下两部操作:
void levelOrder(Btree *T)
{
QUEUE *q = createQueue(100); //创建一个容量为100的队列
while(T != NULL) {
printf("%d ", T->element); //访问根节点
if(T->lchild != NULL)
enQueue(T->lchild, q); //如果左孩子存在,左孩子入队
if(T->rchild != NULL)
enQueue(T->rchild, q); //如果左孩子存在,左孩子入队
if(!isEmpty(q)) //当队列非空时
T = frontAndDequeue(q); //队头元素出队,并且访问出队元素
else
T = NULL; //队列为空,遍历完成
}
disposeQueue(q); //销毁队列
}
void distroyTree(Btree **T)
{
Btree *pl, *pr;
if((*T) == NULL) {
return ;
} else {
pl = (*T)->lchild; //保存左孩子的地址
pr = (*T)->rchild; //保存右孩子的地址
(*T)->lchild = NULL;
(*T)->rchild = NULL;
free(*T); //释放根节点
(*T) = NULL;
distroyTree(&pl); //递归销毁
distroyTree(&pr);
}
}
int tree_deep(Btree *T)
{
int deep = 0;
if(T) {
int leftdeep = tree_deep(T->lchild);
int rightdeep = tree_deep(T->rchild);
deep = leftdeep > rightdeep ? leftdeep+1 : rightdeep+1;
}
return deep;
}
int leafnode_count(Btree *T, int num)
{
if(T) {
if(T->lchild == NULL && T->rchild == NULL)
num++;
leafnode_count(T->lchild, num);
leafnode_count(T->rchild, num);
}
return num;
}