用链表表示二叉树,每个结点由数据和左右指针三个数据成员组成
typedef int ElementType;
typedef struct TNode* Position;
typedef Position BinTree; //二叉树类型
struct TNode //树结点定义
{
ElementType Data; //结点数据
BinTree Left; //指向左子树
BinTree Right; //指向右子树
};
//递归遍历
//中序遍历 中序遍历左子树 访问根结点 中序遍历右子树
/*从非递归的角度来理解,遍历实际上是从树根结点开始后,沿其左孩子域向下移动,直到某一结点无左孩子为止,访问这个最左边的结点,
接下来再从此结点的右孩子结点开始进行中序遍历,当右子树遍历完了以后,退回上一层未访问结点继续二叉树的遍历,直到树中所有结点被访问*/
void InorderTraversal(BinTree BT)
{
if(BT)
{
InorderTraversal(BT->Left);
//假设对BT结点的访问就是打印数据
printf("%d",BT->Data);
InorderTraversal(BT->Right);
}
}
//先序遍历 访问根结点 先序遍历左子树 先序遍历右子树
void PreorderTraversal(BinTree BT)
{
if(BT)
{
printf("%d",BT->Data);
PreorderTraversal(BT->Left);
PreorderTraversal(BT->Right);
}
}
//后序遍历 后序遍历左子树 后序遍历右子树 访问根结点
void PostorderTraversal(BinTree BT)
{
if(BT)
{
PostorderTraversal(BT->Left);
PostorderTraversal(BT->Right);
printf("%d",BT->Data);
}
}
//非递归遍历
//用栈实现 中序遍历二叉树
void InorderTraversal(BinTree BT)
{
BinTree T;
Stack S=CreateStack(); //创建空栈 元素类型为BinTree
T=BT; //从根结点出发
while(T||!IsEmpty(S))
{
while(T) //一直向左并将沿途节点压入栈
{
Push(S,T);
T=T->Left;
}
T=Pop(S); //结点弹出栈
printf("%d",T->Data); //(访问)打印结点
T=T->Right; //转向右子树
}
}
//队列实现 层序遍历二叉树
//按树的层次,从第一层的根结点开始逐层向下逐层访问每个结点,对某一层中的结点是按从左到右的顺序访问
/*从队列中取出一个元素 访问该元素所指结点 若该元素所指结点的左右孩子结点非空,则将其左右孩子的指针顺序入队
不断执行这散步操作,直到队列为空,二叉树的层序遍历就完成了*/
void LevelorderTraversal(BinTree BT)
{
Queue Q;
BinTree T;
if(!BT)
return; //若是空树则直接返回
Q=CreateQueue() //创建空队列
AddQ(Q,BT);
while(!IsEmpty(Q))
{
T=DeleteQ(Q);
printf("%d",T->Data); //访问出队列的结点
if(T->Left)
AddQ(Q,T->Left);
if(T->Right)
AddQ(T->Right);
}
}
//输出二叉树中所有叶结点
//看是否左右子树都为空
void PreorderPrintLeaves(BinTree BT)
{
if(BT)
{
if(!BT->Left&&!BT->Right) //如果BT结点是叶子
printf("%d",BT->Data);
PreorderPrintLeaves(BT->Left);
PreorderPrintLeaves(BT->Right);
}
}
//求二叉树的高度
int GetHeight(BinTree BT)
{
int HL,HR,MaxH;
if(BT)
{
HL=GetHeight(BT->Left); //求左子树的高度
HR=GetHeight(BT->Right); //求右子树的高度
MaxH=HL>HR?HL:HR; //取左右子树较大的高度
return(MaxH+1); //返回树的高度
}
else
return 0; //空树的高度为0
}