1. 程式人生 > >資料結構(二叉樹的遍歷)

資料結構(二叉樹的遍歷)

程式碼及執行結果分析

(包括先序,中序,後序遍歷,以 及先序的非遞迴呼叫)相關程式碼如下:
#include<stdio.h>
#include <stdlib.h>
#define STACK_INIT_SIZE 100 //巨集定義 棧區的容量
#define STACKINCREMENT 10 //當容量不充足的時候增加的容量大小
#define MAX_TREE_SIZE 100//二叉樹的最大結點數
#define ERROR 0
#define OK 1
typedef int elemtype;//定義結點值
typedef int Status;//返回值狀態
typedef struct BiTNode{
elemtype data;
BiTNode *lchild,*rchild; /左右孩子指標

/
}BiTNode,*BiTree;

//宣告棧的資料結構
typedef BiTree SElemType;
typedef struct {
SElemType *top; //棧頂
SElemType *base; //棧底
int stacksize; //棧的容量

} SqStack;
//初始化棧
Status InitStack(SqStack S) {
S->base=(SElemType )malloc(STACK_INIT_SIZEsizeof(SqStack));
if(!S->base)
{
return ERROR;//分配棧空間失敗則返回錯誤
}
S->top=S->base;
S->stacksize=STACK_INIT_SIZE;//增加棧容量
return OK;
}
//進棧
Status Push(SqStack S,SElemType e) {
//判斷棧區記憶體是否充足
if(S->top-S->base >= S->stacksize) {
//增加記憶體空間
S->base = (SElemType

)realloc(S->base,sizeof(SqStack));
if(!S->base) {
printf(“增加記憶體失敗\n”);
return ERROR;
}
//top重新指向棧頂
S->top = S->base + S->stacksize;
S->stacksize += STACKINCREMENT;
}
S->top++ = e;
return OK;
}
//出棧
Status Pop(SqStack S,SElemType e) {
//沒有元素返回錯誤
if(S->top == S->base) {
return ERROR;
}
//把棧頂的值返回並把指向棧頂的指標下移
e = –S->top;
return OK;
}
Status getTop(SqStack S,SElemType e) {
//棧中沒有元素
if(S.top == S.base) {
printf(“棧中無元素\n”);
return ERROR;
}
e = (S.top - 1);
return OK;
}
//判斷棧是否為空
Status StackEmpty(SqStack S) {
if(S.top == S.base) {
return OK;
} else {
return ERROR;
}
}
/
CreateBiTree
/
Status CreateBiTree(BiTree &T) {
/按先序次序輸入二叉樹中結點的值(一個字元),空格字元表示空樹,
構造二叉連結串列表示的二叉樹T。
/
elemtype ch;
scanf("%d",&ch);
if (ch==0)
{
T = NULL;
}
else {
if(!(T = (BiTNode )malloc(sizeof(BiTNode))))
return ERROR;
T->data = ch; /
生成根結點
/
CreateBiTree(T->lchild); /
構造左子樹
/
CreateBiTree(T->rchild); /
構造右子樹
/
}
return OK;
}
/採用二叉連結串列儲存結構,Visit是對資料元素操作的應用函式,
先序遍歷二叉樹T的遞迴演算法,對每個資料元素呼叫函式Visit。
最簡單的Visit函式是:
/
Status visit(elemtype e) { // 輸出元素e的值
printf("%3d",e); // 實用時,加上格式串
return OK;
}
// 呼叫例項:PreOrderTraverse(T, PrintElement);
/
//先序遞迴呼叫,呼叫函式本身(效率較低)
Status PreOrderTraverse( BiTree T )
{
if(T) {//存在二叉樹
visit(T->data);//遍歷根節點
PreOrderTraverse(T->lchild);//遍歷左孩子
PreOrderTraverse(T->rchild);//遍歷右孩子
}
} /
PreOrderTraverse*/
Status NRPreOrder(BiTree bt)
{/非遞迴先序遍歷二叉樹,用棧來做儲存結構/
BiTree p = bt;//將樹賦值給一個臨時變數p
SqStack S;
InitStack(&S);//初始化棧
//當樹的結點不為空或者棧不為空時執行迴圈遍歷
while(p||!StackEmpty(S))
{
if§//當此結點不為空繼續執行條件語句
{
visit(p->data);//p結點不為空輸出p結點的資料域
Push(&S,p);//繼續進棧
p = p->lchild;//遍歷左孩子
}else
{
//否則父節點出棧,p指向父節點的右子樹
Pop(&S,&p);
p = p->rchild;
}
}
}
//中序遍歷 通過輔助儲存結構 棧
Status InOrderTraverse(BiTree T) {
//先宣告一個棧
SqStack S;
BiTree p;
//初始化棧
InitStack(&S);
//根指標進棧
Push(&S,T);
while(!StackEmpty(S)) {
while(getTop(S,&p) && p) {
Push(&S,p->lchild);//迴圈遍歷左孩子直到盡頭
}
Pop(&S,&p);
if(!StackEmpty(S)) {
Pop(&S,&p);
if(!visit(p->data)) {
return ERROR;
}
Push(&S,p->rchild);
}
}
}
//後序遍歷
Status postOrderTraverse(BiTree T) {

if(T==NULL) {
	return ERROR;;
}
postOrderTraverse(T->lchild);
postOrderTraverse(T->rchild);
visit(T->data);

}
int main()
{
BiTree T;
printf(“構件二叉樹輸入0表示當前分支結束:\n”);
CreateBiTree(T);
printf(“先序遍歷遞迴呼叫後為:\n”);
PreOrderTraverse( T );
getchar();
printf("\n先序遍歷非遞迴呼叫後為:\n");
NRPreOrder(T);
printf("\n中序遍歷後為:\n");
InOrderTraverse(T);
printf("\n後序遍歷後為:\n");
postOrderTraverse(T);
getchar();
}

執行後結果是:

0表示
結果所遍歷的二叉樹是:
在這裡插入圖片描述
先序遍歷是:“根,左,右”
中序遍歷是:“左,根,右”
後序遍歷是:“左,右,根”
先序非遞迴採用棧儲存結構