資料結構 樹筆記-7 二叉樹的非遞迴中序遍歷
二叉樹的 非遞迴 中序遍歷 |
|
//#define ElemType char |
|
typedef char ElemType; |
結點中存放的資料的型別的定義 |
|
|
typedef struct BiTNode{ |
樹結點的定義 |
ElemType data; |
|
struct BiTNode *lchild, *rchild; |
|
}BiTNode, *BiTree; |
BiTNode是一個結構體變數; BiTree是一個結構體變數的地址; BiTree = BiTNode * |
|
|
#define MAX 10000 |
巨集定義是簡單的符號代換,這裡MAX符號的含義是棧中最多存放10000個結點的地址 |
typedef struct{ |
自定義一個結構體型別SeqStack用於 棧操作 |
BiTree data[MAX]; |
定義一個數組型別的變數data,用於儲存棧中的元素。 |
int top; |
定義棧的棧頂指標top,它始終指向棧頂元素 |
}SeqStack; |
|
|
|
void in_order_nonrecursive(BiTree T) |
T:根結點的地址 |
{ |
|
SeqStack s; |
宣告一個用於棧操作的結構體變數s |
s.top = -1; |
初始化棧頂指標為-1, |
|
|
BiTree p = T; |
變數p是結點地址型別,用於遍歷一棵二叉樹的各個結點,初始化為樹根結點(的地址) |
|
|
while(p || (s.top != -1)){ |
外層while迴圈:用於找到每一個左枝的第一個結點,這個結點是上一個左枝的最後一個結點的右孩子 |
while(p){ |
內層while迴圈: 把P結點的左枝上的所有結點入棧, 僅僅是結點的入棧操作,沒有訪問操作。 因為左枝上的每一個結點都是其子樹的根結點, 中序遍歷是:左根右,要先遞迴訪問(列印)到左枝上的最後一個左結點,所以作為枝上的這些結點都需要入棧,以備後續進行訪問(列印) |
if(s.top == MAX - 1){ |
如果棧滿 |
exit(0); |
不進行任何操作,直接退出 |
} |
|
|
如果棧不滿 |
s.data[++s.top]=p; |
把當前這個p結點地址入棧(入棧前要先把棧頂棧頂指標加1,因為棧頂指標的初始值是-1,而陣列是從下標為0的單元開始存放資料),因為中序遍歷是:左根右,在沒有找到左枝的最後一個結點之前,這些結點都要入棧,用於後序的重新訪問(列印結點操作) |
p=p->lchild; |
更新當前結點為這個結點的左孩子 |
} |
內層while迴圈結束,表示當前p是空結點,而棧頂元素是左枝上的最後一個結點 |
|
|
if(s.top!=-1){ |
如果棧不空 |
p = s.data[s.top--]; |
從棧中通過棧頂指標取出棧頂元素(左枝上的最後一個結點),並作為棧操作的配套操作,把棧頂指標減1 |
printf("%c",p->data); |
這個剛從棧頂取出的元素是之前左枝上的最後一個元素,這個元素自然就沒有左孩子,所以直接訪問(這裡是列印操作)這個結點 |
p=p->rchild; |
訪問(列印)完這個結點,就立即把結點更新為它的右孩子。因為中序遍歷:左根右,沒有左孩子,又把這個沒有左孩子的結點訪問完畢,接下來就要對以其右孩子為首的左枝進行while操作(下一次內層while操作) |
} |
|
} |
|
|
|
printf("\n"); |
|
} |
|
|
程式碼:
#include <stdio.h>
#include <malloc.h>
//#define ElemType char
typedef char ElemType;
typedef struct BiTNode{
ElemType data;
struct BiTNode *lchild, *rchild;
}BiTNode, *BiTree;
#define MAX 10000
typedef struct{
BiTree data[MAX];
int top;
}SeqStack;
void in_order_nonrecursive(BiTree T)
{
SeqStack s;
s.top = -1;
BiTree p = T;
while(p || (s.top != -1)){
while(p){
if(s.top == MAX - 1){
exit(0);
}
s.data[++s.top]=p;
p=p->lchild;
}
if(s.top!=-1){
p = s.data[s.top--];
printf("%c",p->data);
p=p->rchild;
}
}
printf("\n");
}