浙江大学数据结构与算法二叉树部分学习笔记
一、二叉树链表结构定义示例
typedef struct TNode *Position;
typedef Position BinTree; /* 二叉树类型 */
struct TNode{ /* 树结点定义 */
ElementType Data; /* 结点数据 */
BinTree Left; /* 指向左子树 */
BinTree Right; /* 指向右子树 */
};
二、 二叉树的存储结构
1.顺序存储结构
2.链表存储结构
三、二叉树的遍历方式
1.中序遍历方式
void InorderTraversal( BinTree BT )
{
if( BT ) {
InorderTraversal( BT->Left );
/* 此处假设对BT结点的访问就是打印数据 */
printf("%d ", BT->Data); /* 假设数据为整型 */
InorderTraversal( BT->Right );
}
}
2.前序遍历方式
void PreorderTraversal( BinTree BT )
{
if( BT ) {
printf("%d ", BT->Data );
PreorderTraversal( BT->Left );
PreorderTraversal( BT->Right );
}
}
3.后序遍历方式
void PostorderTraversal( BinTree BT )
{
if( BT ) {
PostorderTraversal( BT->Left );
PostorderTraversal( BT->Right );
printf("%d ", BT->Data);
}
}
4.层次遍历方式
void LevelorderTraversal ( BinTree BT )
{
Queue Q;
BinTree T;
if ( !BT ) return; /* 若是空树则直接返回 */
Q = CreatQueue(); /* 创建空队列Q */
AddQ( Q, BT );
while ( !IsEmpty(Q) ) {
T = DeleteQ( Q );
printf("%d ", T->Data); /* 访问取出队列的结点 */
if ( T->Left ) AddQ( Q, T->Left );
if ( T->Right ) AddQ( Q, T->Right );
}
}
5.先序中序后序的非递归(堆栈)遍历方法
以中序遍历为例说明堆栈的使用:
/*
中序遍历堆栈算法
*/
void InOrderTraversal(BinTree BT)
{
BinTree T=BT;
Stack S = CreatStack(MaxSize);/*创建并初始化堆栈S*/
while(T||!IsEmpty(S))//树不为空,或堆栈不为空
{
while(T)//一直向左并将沿途结点压入堆栈
{
Push(S,T);
T = T->Left;//到达叶结点停止,即T->Left为NULL,下一个循环退出
}
//此时若堆栈里面有存放祖先结点
if(!IsEmpty(S))
{
T = Pop(S);//结点弹出堆栈
printf("%5d",T->Data);//(访问)打印结点
T = T->Right;//转向右子树
}
}
}
——前序遍历只需稍加改动即可,第一次碰到结点时将其print出来,即将printf()函数移动到push()函数进栈之前。
——后序遍历比较特殊,在进入右子树之前做一个判断,若右子树存在,则直接进入;若不存在,打印该结点。
/*
后序遍历堆栈算法
*/
void InOrderTraversal(BinTree BT)
{
BinTree T=BT;
Stack S = CreatStack(MaxSize);/*创建并初始化堆栈S*/
while(T||!IsEmpty(S))//树不为空,或堆栈不为空
{
while(T)//一直向左并将沿途结点压入堆栈
{
Push(S,T);
T = T->Left;//到达叶结点停止,即T->Left为NULL,下一个循环退出
}
//此时若堆栈里面有存放祖先结点
if(!IsEmpty(S))
{
T = Pop(S);//结点弹出堆栈
if(T->Right)//判断有无右子树
{
T = T->Right;
}
else
{
printf("%5d",T->Data);//(访问)打印结点
}
}
}
}