二叉树
a
/ \
b $
/ \
c d
/ \ / \
$ $ e f
/ \ / \
$ g $ $
/ \
$ $
结点类型和指针
typedef char TElemType;
typedef struct BiTNode
{
TElemType data;
struct BiTNode *lchild, *rchild; //左右孩子指针
} BiTNode, *BiTree;
① 创建二叉树CreatBiTree()
char Vexch[15]={'a','b','c','$','$','d','e','$','g','$','$','f','$','$','$'};
int i=0;
//二叉树的创建
Status CreatBiTree(BiTree &T)
{
if(Vexch[i++]=='$') T=NULL;
else
{
T= new BiTNode;
if(!T) return 0;
T->data=Vexch[i-1];//生成根节点
CreatBiTree(T->lchild);//创建左子树
CreatBiTree(T->rchild);//创建右子树
}
return 1;
}
建立二叉树时:判断 i 是否为空 ,那么指针指向空
建树建完本结点后,首先先建左子树,左子树碰到叶子后,才往右边建右子树
② 先序遍历二叉树 PreOrderTraverse()
//先序遍历二叉树
Status PreOrderTraverse(BiTree T,void( * visit)(TElemType))
{
if(T)
{
visit(T->data);
PreOrderTraverse(T->lchild,visit);
PreOrderTraverse(T->rchild,visit);
}
return 1;
}
判断本结点是否为空,非空就输出本结点的data(根),再输出左子树(左),再输出右子树(右):(根>左>右)
③ 中序遍历二叉树 InOrderTraverse()
//中序遍历二叉树
Status InOrderTraverse(BiTree T,void( * visit)(TElemType))
{
if(T)
{
InOrderTraverse(T->lchild,visit);
visit(T->data);
InOrderTraverse(T->rchild,visit);
}
return 1;
}
判断本结点是否为空,非空先输出左子树(左),再输出本结点data(根),再输出右子树(右):(左>根>右)
④ 后序遍历二叉树 PostOrderTraverse()
//后序遍历二叉树
Status PostOrderTraverse(BiTree T,void( * visit)(TElemType))
{
if(T)
{
PostOrderTraverse(T->lchild,visit);
PostOrderTraverse(T->rchild,visit);
visit(T->data);
}
return 1;
}
判断本节点是否为空,非空先输出左子树(左),再输出右子树(右),再输出本节点data(根):(左>右>根)
⑤ 释放子树 Destory()
//释放T所指子树,该函数在析构函数中被调用
void Destory(BiTree T)
{
if(T)
{
Destory(T->lchild);
Destory(T->rchild);
delete T;
}
}
用后序遍历,释放子树。
⑥ 中序遍历非递归实现 InOrderNotRescure()
//中序遍历二叉树的非递归实现,visit为遍历操作函数
void InOrderNotRescure(BiTree T,void( * visit)(TElemType))
{
stack<BiTree> S;
while(!S.empty() || T!=NULL )
{
if(T!=NULL)
{
S.push(T);
T=T->lchild;
}
else
{
T=S.top();
visit(T->data);
S.pop();
T=T->rchild;
}
}//end of while
}
.利用栈,先将根节点存到栈里(暂不输出),然后往左子树探,探到最左后,没有左边之后(弹出栈,输出值),再往右边探。
⑦ 计算二叉树结点 NodesCount()
//计算二叉树结点
int NodesCount(BiTree T)
{
if(T == NULL) return 0;
else
return NodesCount(T->lchild)+NodesCount(T->rchild)+1;
}
用递归,每一个函数往左边和右边(顺序无关),两个方向探索,然后每探索成功一次,说明有一个结点,+1。出口为结点为空
⑧ 计算二叉树深度 Deepth()
//计算二叉树深度
int Deepth(BiTree T)
{
if(T == NULL) return 0;
else
{
int left= Deepth(T->lchild);
int right = Deepth(T->rchild);
if(left > right)
return left+1;
else
return right+1;
}
}
用递归,向左右探索(顺序无关),返回的值是二叉树的深度,分治思想,在左边和右边的子树那个深度大,那么就选那个深度大的+1 。出口为结点为空。
⑨ 计算二叉树叶子数目 LeafCount()
//计算二叉树的叶子数目
int LeafCount(BiTree T)
{
if(T == NULL)
return 0;
else if(T->lchild == NULL && T->rchild==NULL)
return 1;
else
return LeafCount(T->lchild)+LeafCount(T->rchild);
}
递归,和探索结点一样,左右探索(顺序无关),结点左右子树皆为空,才是叶子。出口两个,结点为空返回0,结点的左右子树为空返回1。
(为什么要结点为空返回0?因为A的左子树这个情况的时候,就要返回0,B的情况返回1)
A
/ \
$ B
/ \
$ $
⑩ 主函数main()和visit()函数
void visit (char e)
{
printf("%5c",e);
}
int main()
{
BiTree T;
printf("1.建立二叉树\n");
printf("二叉树:");CreatBiTree(T);
printf("\n2.前序遍历二叉树\n");
PreOrderTraverse(T,visit);
printf("\n3.中序遍历二叉树\n");
InOrderTraverse(T,visit);
printf("\n4.后序遍历二叉树\n");
PostOrderTraverse(T,visit);
printf("\n5.非递归中序遍历二叉树\n");
InOrderNotRescure(T,visit);
printf("\n6.计算二叉树的深度\n");
printf("树的深度为:%d\n",Deepth(T));
printf("\n7.计算二叉树的叶子树\n");
printf("树的叶子树为:%d\n",LeafCount(T));
printf("\n8.计算二叉树的节点数\n");
printf("树的节点数为:%d\n",NodesCount(T));
return 0;
}