資料結構----二叉樹遍歷的非遞迴演算法實現
阿新 • • 發佈:2019-01-30
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define OK 0;
#define ERROR -1
#define OVERFLOW -2
#define YES 1
#define NO 0
#define STACK_INIT_SIZE 100
#define STACK_INCREMENT 10
typedef int Status;
typedef int TElemType;
//二叉樹的順序儲存結構
#define MaxTreeSize 101
typedef TElemType BiTreeArr[MaxTreeSize];
BiTreeArr bt;
//二叉樹的鏈式儲存結構
typedef struct BiTNode
{
TElemType data;
struct BiTNode *lchild,*rchild;
}BiTNode,*BiTreeLk;
typedef BiTreeLk SElemType;
//@@@@@@@@@@@@@@@@@@@
//棧的資料結構部分開始
typedef struct
{
SElemType *base;
SElemType *top;
int stacksize;
}SqStack;
//初始化棧
Status InitStack(SqStack &Stack)
{
Stack.base = (SElemType *)malloc(sizeof(SElemType)*STACK_INIT_SIZE);
if(!Stack.base) exit(OVERFLOW);
Stack.top = Stack.base;
Stack.stacksize = STACK_INIT_SIZE;
return OK;
}
//得到棧頂元素
Status GetTop(SqStack &Stack,SElemType &e)
{
if(Stack.top==Stack.base)
return ERROR;
e = *(Stack.top-1);
return OK;
}
//壓棧
Status Push(SqStack &Stack,SElemType e)
{
if(Stack.top-Stack.base>=Stack.stacksize)
{
Stack.base= (SElemType *)realloc(Stack.base, sizeof(SElemType)*(Stack.stacksize+STACK_INCREMENT));
if(!Stack.base) return ERROR;
Stack.top = Stack.base+Stack.stacksize;
Stack.stacksize += STACK_INCREMENT;
}
*Stack.top++ = e;
return OK;
}
//出棧
Status Pop(SqStack &Stack,SElemType &e)
{
if(Stack.top==Stack.base) return ERROR;
Stack.top--;
e = *Stack.top; return OK;
}
Status StackEmpty(SqStack &Stack)
{
if(Stack.base == Stack.top)
return YES;
return NO;
}
//棧的資料結構部分結束
//@@@@@@@@@@@@@@@@@@@@@@@@@@@
Status Visit(TElemType data)
{
if(&data==NULL)
{
return ERROR;
}
else
{
printf(" %d",data);
return OK;
}
}
//採用遞迴演算法的先序、中序和後序遍歷演算法
//先序遞迴便利演算法
Status PreOrderTraverse( BiTreeLk T, Status(*Visit)(TElemType) )
{
if(T)
{
if(Visit(T->data))
if(PreOrderTraverse(T->lchild, Visit))
if (PreOrderTraverse(T->rchild, Visit))
return OK;
return ERROR;
}
else
return OK;
}
//中序遞迴遍歷演算法
Status InOrderTraverse( BiTreeLk T, Status(*Visit)(TElemType) )
{
if(T)
{
if(PreOrderTraverse(T->lchild, Visit))
if(Visit(T->data))
if (PreOrderTraverse(T->rchild, Visit))
return OK;
return ERROR;
}
else
return OK;
}
//後序遞迴遍歷演算法
Status PostOrderTraverse( BiTreeLk T, Status(*Visit)(TElemType) )
{
if(T)
{
if(PreOrderTraverse(T->lchild, Visit))
if (PreOrderTraverse(T->rchild, Visit))
if(Visit(T->data))
return OK;
return ERROR;
}
else
return OK;
}
//非遞迴的二叉樹中序遍歷演算法
//大體的思路是儲存在遍歷樹時走過的路徑,節點彈出的順序即為節點訪問的順序
Status InOrderTraverse1(BiTreeLk T,Status(*Visit)(TElemType e))
{
SqStack Stack;
BiTreeLk p;
InitStack(Stack); //初始化一個棧
Push(Stack,T); //將根節點壓入棧中
while(!StackEmpty(Stack)) //滿足棧不空的條件
{
while(GetTop(Stack,p)&&p) //獲取棧的最上面的指標
Push(Stack,p->lchild); //向左走到盡頭,將這條線路上的點都壓入棧中
Pop(Stack,p); //彈出入棧的空指標
if(!StackEmpty(Stack)) //如果棧不為空
{
Pop(Stack,p); //彈出一個節點指標
if(
!Visit(p->data)) //訪問這個節點
return ERROR;
Push(Stack,p->rchild); //將其右節點入棧
}
}
return OK;
}
//非遞迴的二叉樹中序遍歷演算法
Status InOrderTraverse2(BiTreeLk T, Status (*Visit)(TElemType e))
{
SqStack Stack;
InitStack(Stack);
BiTreeLk p = T;
while(p||!StackEmpty(Stack))
{
if(p)
{
Push(Stack,p);
p = p->lchild;
}
else
{
Pop(Stack,p);
if(!Visit(p->data))
return ERROR;
p = p->rchild;
}
}
return OK;
}
Status CreateBitreeLk(BiTreeLk &T)
{
char ch=' ';
scanf("%c",ch);
if(ch==' ')
T = NULL;
else
{
if(!(T=(BiTreeLk)malloc(sizeof(BiTNode))))
return ERROR;
T->data = ch;
CreateBitreeLk(T->lchild);
CreateBitreeLk(T->rchild);
}
return OK;
}
int main()
{
//Todo functions is here
//test the data structure above using the sampes of " A B C @ @ D E @ g @ @ f @ @ @ "
//'@' denote the empty character
BiTreeLk T;
CreateBitreeLk(T);
InOrderTraverse1(T,Visit);
return 0;
}
#include <stdlib.h>
#include <string.h>
#define OK 0;
#define ERROR -1
#define OVERFLOW -2
#define YES 1
#define NO 0
#define STACK_INIT_SIZE 100
#define STACK_INCREMENT 10
typedef int Status;
typedef int TElemType;
//二叉樹的順序儲存結構
#define MaxTreeSize 101
typedef TElemType BiTreeArr[MaxTreeSize];
BiTreeArr bt;
//二叉樹的鏈式儲存結構
typedef struct BiTNode
{
TElemType data;
struct BiTNode *lchild,*rchild;
}BiTNode,*BiTreeLk;
typedef BiTreeLk SElemType;
//@@@@@@@@@@@@@@@@@@@
//棧的資料結構部分開始
typedef struct
{
SElemType *base;
SElemType *top;
int stacksize;
}SqStack;
//初始化棧
Status InitStack(SqStack &Stack)
{
Stack.base = (SElemType *)malloc(sizeof(SElemType)*STACK_INIT_SIZE);
if(!Stack.base) exit(OVERFLOW);
Stack.top = Stack.base;
Stack.stacksize = STACK_INIT_SIZE;
return OK;
}
//得到棧頂元素
Status GetTop(SqStack &Stack,SElemType &e)
{
if(Stack.top==Stack.base)
return ERROR;
e = *(Stack.top-1);
return OK;
}
//壓棧
Status Push(SqStack &Stack,SElemType e)
{
if(Stack.top-Stack.base>=Stack.stacksize)
{
Stack.base= (SElemType *)realloc(Stack.base, sizeof(SElemType)*(Stack.stacksize+STACK_INCREMENT));
if(!Stack.base) return ERROR;
Stack.top = Stack.base+Stack.stacksize;
Stack.stacksize += STACK_INCREMENT;
}
*Stack.top++ = e;
return OK;
}
//出棧
Status Pop(SqStack &Stack,SElemType &e)
{
if(Stack.top==Stack.base) return ERROR;
Stack.top--;
e = *Stack.top; return OK;
}
Status StackEmpty(SqStack &Stack)
{
if(Stack.base == Stack.top)
return YES;
return NO;
}
//棧的資料結構部分結束
//@@@@@@@@@@@@@@@@@@@@@@@@@@@
Status Visit(TElemType data)
{
if(&data==NULL)
{
return ERROR;
}
else
{
printf(" %d",data);
return OK;
}
}
//採用遞迴演算法的先序、中序和後序遍歷演算法
//先序遞迴便利演算法
Status PreOrderTraverse( BiTreeLk T, Status(*Visit)(TElemType) )
{
if(T)
{
if(Visit(T->data))
if(PreOrderTraverse(T->lchild, Visit))
if (PreOrderTraverse(T->rchild, Visit))
return OK;
return ERROR;
}
else
return OK;
}
//中序遞迴遍歷演算法
Status InOrderTraverse( BiTreeLk T, Status(*Visit)(TElemType) )
{
if(T)
{
if(PreOrderTraverse(T->lchild, Visit))
if(Visit(T->data))
if (PreOrderTraverse(T->rchild, Visit))
return OK;
return ERROR;
}
else
return OK;
}
//後序遞迴遍歷演算法
Status PostOrderTraverse( BiTreeLk T, Status(*Visit)(TElemType) )
{
if(T)
{
if(PreOrderTraverse(T->lchild, Visit))
if (PreOrderTraverse(T->rchild, Visit))
if(Visit(T->data))
return OK;
return ERROR;
}
else
return OK;
}
//非遞迴的二叉樹中序遍歷演算法
//大體的思路是儲存在遍歷樹時走過的路徑,節點彈出的順序即為節點訪問的順序
Status InOrderTraverse1(BiTreeLk T,Status(*Visit)(TElemType e))
{
SqStack Stack;
BiTreeLk p;
InitStack(Stack); //初始化一個棧
Push(Stack,T); //將根節點壓入棧中
while(!StackEmpty(Stack)) //滿足棧不空的條件
{
while(GetTop(Stack,p)&&p) //獲取棧的最上面的指標
Push(Stack,p->lchild); //向左走到盡頭,將這條線路上的點都壓入棧中
Pop(Stack,p); //彈出入棧的空指標
if(!StackEmpty(Stack)) //如果棧不為空
{
Pop(Stack,p); //彈出一個節點指標
if(
!Visit(p->data)) //訪問這個節點
return ERROR;
Push(Stack,p->rchild); //將其右節點入棧
}
}
return OK;
}
//非遞迴的二叉樹中序遍歷演算法
Status InOrderTraverse2(BiTreeLk T, Status (*Visit)(TElemType e))
{
SqStack Stack;
InitStack(Stack);
BiTreeLk p = T;
while(p||!StackEmpty(Stack))
{
if(p)
{
Push(Stack,p);
p = p->lchild;
}
else
{
Pop(Stack,p);
if(!Visit(p->data))
return ERROR;
p = p->rchild;
}
}
return OK;
}
Status CreateBitreeLk(BiTreeLk &T)
{
char ch=' ';
scanf("%c",ch);
if(ch==' ')
T = NULL;
else
{
if(!(T=(BiTreeLk)malloc(sizeof(BiTNode))))
return ERROR;
T->data = ch;
CreateBitreeLk(T->lchild);
CreateBitreeLk(T->rchild);
}
return OK;
}
int main()
{
//Todo functions is here
//test the data structure above using the sampes of " A B C @ @ D E @ g @ @ f @ @ @ "
//'@' denote the empty character
BiTreeLk T;
CreateBitreeLk(T);
InOrderTraverse1(T,Visit);
return 0;
}