树的基础知识(二)
二叉树
顺序存储
- 数组表示(只将存在的结点写入)
- 链表表示
typedef struct TreeNode *BinTree;//定义一个指向结构体自己的指针
typedef BinTree Position;
struct TreeNode{
//data--根、Left--左子树、Right--右子树
ElementType Data;//使用过程用 “elemtype” 代表所有可能的数据类型,简单明了的概括整体。
//在算法中,除特别说明外,规定ElemType的默认是int型。
BinTree Left;
BinTree Right;
};
遍历
先序遍历:根、左子树、右子树
中序遍历:左、根、右
后序遍历:左、右、根
先序:
void PreOrderTraversal(BinTree BT){//先序遍历递归方法
if(BT){
printf("%d",BT->Data);//访问根节点
PreOrderTraversal(BT->Left);//遍历左子树 ,递归
PreOrderTraversal(BT->Right);//遍历右子树 ,递归
}
}
中序:
//非递归的中序遍历
void InOrderTraversal(BinTree BT){//参数BT
/*遇见一个结点,把它压栈,并去遍历左子树
左子树遍历结束后,从栈顶弹出这个结点并访问它
按其右指针再去中序遍历该结点的右子树*/
BinTree T=BT;
Stack S=CreatStack(MaxSize);//创建并初始化堆栈S
while(T||!IsEmpty(S)){//树不空或者堆栈不空
while(T){//一直向左并沿途节点压入堆栈
Push(S,T);
T=T->Left;//类对象的指针T通过->运算符访问对象的成员。
}
if(!IsEmpty(S)){
T=Pop(S);//结点弹出堆栈
printf("%5d",T->Data);//(访问)打印节点
T=T->Right;//转向右子树
}
}
}
先序遍历非递归遍历:
//先序遍历非递归遍历,即printf改变位置
void PreOrderTraversal(BinTree BT){//参数BT
BinTree T=BT;
Stack S=CreatStack(MaxSize);
while(T||!IsEmpty(S)){
while(T){
Push(S,T);
printf("%5d",T->Data);
T=T->Left;
}
if(!IsEmpty(S)){
T=Pop(S);
T=T->Right;
}
}
}
层序遍历:
根节点入队、循环、结点出队、访问该结点、其左右儿子入队
void LevelOrderTraversal(BinTree BT){
Queue Q;
BinTree T;
if(!BT) return;//若是空树则直接返回
Q=CreatQueue(MaxSize);//创建并初始化队列
AddQ(Q,BT);
while(!IsEmptyQ(Q)){
T=DeleteQ(Q);
printf("%d\n",T->Data);//访问取出队列结点
if(T->Left) AddQ(Q,T->Left);
if(T->Right) AddQ(Q,T->Right);
}
}
输出二叉树中叶子节点数
void PreOrderTraversal(BinTree BT){//先序遍历
if(!BT->Left&&!BT->Right){//访问左右节点均空
printf("%d",BT->Data);//访问根节点
PreOrderTraversal(BT->Left);//遍历左子树 ,递归
PreOrderTraversal(BT->Right);//遍历右子树 ,递归
}
}
求二叉树高度
即左右子树深度最大值加一
void PreOrderTraversal(BinTree BT){
int HL,HR,MaxH ;
if(BT){
PreOrderTraversal(BT->Left);//遍历左子树 ,递归
PreOrderTraversal(BT->Right);//遍历右子树 ,递归
MaxH=(HL>HR)?HL:HR;//求左右子树最大深度
return(MaxH+1);
}
else return 0;//空树深度为0
}