/*----------------------------------------
树结构 : A
Bl Cr
El Fr Gl
Hl Il Jr Kr
先序:A B E H F I J C G K
中序:H E B I F J A G K C
后序:H E I J F B K G C A
-----------------------------------------*/
#include<stdio.h>
#include<malloc.h>
//-------------------------数据结构----------------------------------------------
//二叉树结点的定义
typedef char ElemType;
typedef struct Node
{
ElemType data;
struct Node* lchild;
struct Node* rchild;
//本题为二叉链
}node,*pnode;
//定义顺序堆栈结构
#define LEN 15
typedef struct
{
pnode p[LEN];
int max;
int top;
}stack,*pstack;
//-----------------------------------------------------------------------------------
//--------------------------函数声明-------------------------------------------------
int iNodeNum = 0; //遍历时记录结点数
pnode Create_BT(ElemType );
pnode Insert_Lchild(pnode ,ElemType );
pnode Insert_Rchild(pnode ,ElemType );
pstack InitStack(pstack );
void Push(pstack ,pnode );
pnode Pop(pstack );
void TLR_Recursion(pnode );
void LTR_Recursion(pnode );
void LRT_Recursion(pnode );
void LTR_StackTrav(pnode );
void TLR_StackTrav(pnode );
//void LRT_StackTrav(pnode );
//-------------------------------------------------------------------------------------
//---------------------------堆栈算法--------------------------------------------------
//初始化堆栈
pstack InitStack(pstack sp)
{
int i;
sp = (pstack)malloc(sizeof(stack));
for(i=0;i<LEN;i++)
{
sp->p[i] = NULL;
}
sp->max = LEN-1;
sp->top = -1;
return sp;
}
//入栈
void Push(pstack sp,pnode x)
{
if(sp->top == sp->max)
{
printf("error!the stack is full!\n");
return;
}
else
{
sp->top++;
sp->p[sp->top] = x;
}
}
//出栈
pnode Pop(pstack sp)
{
if(sp->top == -1)
{
printf("error!the stack is empty!\n");
return NULL;
}
else
{
return sp->p[sp->top--];
}
}
//---------------------------------------------------------------------------------------
//------------------------------二叉树算法-----------------------------------------------
//新建一棵只有根节点的二叉树,返回树的起始结点指针
pnode Create_BT(ElemType x)
{
pnode ptr,pBT;
ptr = (pnode)malloc(sizeof(node));
pBT = ptr;
ptr->data = x;
ptr->lchild = NULL;
ptr->rchild = NULL;
return pBT;
}
//在当前父节点parent的左孩子插入一个数据位x的新结点,返回新建结点
pnode Insert_Lchild(pnode p,ElemType x)
{
pnode ptr;
if(p == NULL)
{
printf("无法插入新结点!父节点错误!\n");
return NULL;
}
ptr = (pnode)malloc(sizeof(node));
ptr->data = x;
ptr->lchild = NULL;
ptr->rchild = NULL;
if(p->lchild == NULL)
{
p->lchild = ptr;
}
else
{
//若父节点已有左子树,则新建结点插入父节点和左树之间
ptr->lchild = p->lchild;
p->lchild = ptr;
}
return ptr;
}
//在当前父节点parent的右孩子插入一个数据位x的新结点,返回新建结点
pnode Insert_Rchild(pnode p,ElemType x)
{
pnode ptr;
if(p == NULL)
{
printf("无法插入新结点!父节点错误!\n");
return NULL;
}
ptr = (pnode)malloc(sizeof(node));
ptr->data = x;
ptr->lchild = NULL;
ptr->rchild = NULL;
if(p->rchild == NULL)
{
p->rchild = ptr;
}
else
{
//若父节点已有左子树,则新建结点插入父节点和左树之间
ptr->rchild = p->rchild;
p->rchild = ptr;
}
return ptr;
}
//-------------------------------------------------------------------------------------------
//----------------------------------5种遍历算法-----------------------------------------------
//TLR先序遍历递归算法
void TLR_Recursion(pnode BT)
{
if( BT != NULL)
{
printf("%3c",BT->data); //访问根节点
iNodeNum++;
TLR_Recursion(BT->lchild); //先序遍历左子树
TLR_Recursion(BT->rchild); //先序遍历右子树
}
}
//LTR中序遍历递归算法
void LTR_Recursion(pnode BT)
{
if( BT != NULL)
{
LTR_Recursion(BT->lchild); //中序遍历左子树
printf("%3c",BT->data); //访问根节点
iNodeNum++;
LTR_Recursion(BT->rchild); //中序遍历右子树
}
}
//LRT后序遍历递归算法
void LRT_Recursion(pnode BT)
{
if( BT != NULL)
{
LRT_Recursion(BT->lchild); //后序遍历左子树
LRT_Recursion(BT->rchild); //后序遍历右子树
printf("%3c",BT->data); //访问根节点
iNodeNum++;
}
}
//TLR先序遍历非递归算法(堆栈,好吧ps:神用递归,人用迭代)
void TLR_StackTrav(pnode BT)
{
pstack pStack = NULL;
pnode ptr;
iNodeNum = 0;
ptr = BT;
pStack = InitStack(pStack); //初始化堆栈
Push(pStack,NULL); //压入一个空元素,为下列while设立退出循环值
while(pStack->top!=-1)
{
while(ptr != NULL)
{
printf("%3c",ptr->data);
iNodeNum++;
if(ptr->rchild != NULL)
{
Push(pStack,ptr->rchild);
}
ptr = ptr->lchild;
}
if(pStack->top != -1)
{
ptr = Pop(pStack);
}
}
printf("\n先序非递归遍历结点数为:%d\n",iNodeNum);
}
//LTR中序遍历非递归算法(堆栈)
void LTR_StackTrav(pnode BT)
{
pstack pStack = NULL;
pnode ptr;
iNodeNum = 0;
ptr = BT;
pStack = InitStack(pStack); //初始化堆栈
Push(pStack,NULL); //压入一个空元素,为下列while设立退出循环值
while(pStack->top != -1)
{
while(ptr != NULL)
{
Push(pStack,ptr);
ptr = ptr->lchild;
}
if(pStack->top != -1)
{
ptr = Pop(pStack);
if(ptr != NULL)
{
printf("%3c",ptr->data);
iNodeNum++;
ptr = ptr->rchild; //这步是中序的关键(理解!)
}
}
}
printf("\n中序非递归遍历结点数为:%d\n",iNodeNum);
}
//-------------------------------------------------------------------------------------
//---------------------------------------主函数-----------------------------------------
//先建立树,然后开始遍历
int main()
{
pnode BT,ptr,qtr;
//初始化树
BT = Create_BT('A');
qtr = Insert_Lchild(BT,'B'); //左树
ptr = Insert_Lchild(qtr,'E');
ptr = Insert_Lchild(ptr,'H');
qtr = Insert_Rchild(qtr,'F');
ptr = Insert_Lchild(qtr,'I');
ptr = Insert_Rchild(qtr,'J');
qtr = Insert_Rchild(BT,'C'); //右树
qtr = Insert_Lchild(qtr,'G');
qtr = Insert_Rchild(qtr,'K');
qtr = BT; //指针用完回原位
ptr = BT;
//开始遍历
//依次先序中序后序递归遍历树。
iNodeNum = 0;
TLR_Recursion(BT);
printf("\n先序递归遍历共有节点数为:%d\n",iNodeNum);
getchar();
iNodeNum = 0;
LTR_Recursion(BT);
printf("\n中序递归遍历共有节点数为:%d\n",iNodeNum);
getchar();
iNodeNum = 0;
LRT_Recursion(BT);
printf("\n后序递归遍历共有节点数为:%d\n",iNodeNum);
getchar();
//依次先序中序后序非递归遍历树。
TLR_StackTrav(BT);
getchar();
LTR_StackTrav(BT);
getchar();
return 0;
}
//-------------------------------------------------------------------------------
由于后序非递归遍历方法较为麻烦,需要设置两个堆栈,一个暂存数据,一个做标识,所以未做研究。