在說鏈式二叉樹的遍歷之前,我們先來說一下如何建立乙個鏈式二叉樹。建立乙個鏈式二叉樹,需要乙個已知的字串,這個字串必須支援建立二叉樹的規則。比如:
我們通過遞迴來實現二叉樹的建立,開始先向左走,如果遇到#,就返回,然後向右走,直到遇到#,就返回乙個null,這樣,就完成了乙個鏈式二叉樹的建立。
這裡先將除了主要函式外的其他呼叫到的函式放在這裡,供查閱
標頭檔案
#ifndef _btree_h__
#define _btree_h__
#include#includetypedef char btdatatype;
typedef struct binarytreenode
btnode;
typedef btnode* qudatatype;
typedef btnode* stdatatype;
typedef struct stack
stack;
typedef struct queuenode
queuenode;
typedef struct queue
queue;
btnode* binarytreecreate(btdatatype* src);
void binarytreeprevorder(btnode* root);
void binarytreeinorder(btnode* root);
void binarytreepostorder(btnode* root);
void binarytreelevelorder(btnode* root);
void binarytreeprevordernonr(btnode* root);
void binarytreeinordernonr(btnode* root);
void binarytreepostordernonr(btnode* root);
void biarytreelevelprint(btnode* root, int num);
#endif//_btree_h__
btnode* binarytreecreate(btdatatype* src)//鏈式二叉樹的建立
btnode *cur = (btnode*)malloc(sizeof(btdatatype));
cur->data = src[n];
n++;
cur->lchild = binarytreecreate(src);
cur->rchild = binarytreecreate(src);
return cur;
}void queueinit(queue* qu)//佇列的初始化
void queuepop(queue* qu)//出對頭
void queuedestory(queue* qu)//銷毀佇列
void queuepush(queue* qu, qudatatype x)//佇列中進入元素
stdatatype stacktop(stack * st)//拿取棧頂
void stackinit(stack *st)//棧的初始化
void stackpop(stack *st)//退棧
void stackpush(stack *st,stdatatype x)//壓棧
st->_a[st->_top] = x;
st->_top++;
}void stackdestory(stack *st)//銷毀棧
二叉樹的鏈式結構的7種遍歷方法
遞迴遍歷:
前序遍歷
前序遍歷的思路是,通過遞迴的方式,讓鏈式二叉樹,先不停地從左孩子向下,每遇到乙個節點,就進行該節點列印,直到遇到「#」,然後又從右孩子開始向下走,直到遇到「#」,就返回上乙個節點,然後又從這個節點開使向右孩子的位置向下。
void binarytreeprevorder(btnode* root)//遞迴式的前序遍歷
if (root->rchild)
}
中序遍歷
中序遍歷和前序遍歷一樣,唯一的差別是,先進型向左孩子的查詢,然後進行乙個,遇到「#」後,就進行該節點的列印,然後再進行右孩子的查詢。
void binarytreeinorder(btnode* root)//遞迴式的中序遍歷
printf("%c ", root->data);
if (root->rchild)
}
後續遍歷
和中序,前序一樣,也僅僅只是列印的順序發生了改變。
void binarytreepostorder(btnode* root)//遞迴式的後序遍歷
if (root->rchild)
printf("%c ", root->data);
}
層序遍歷:
層序遍歷是通過乙個佇列來實現的,通過利用佇列先入後出的原則,來完成層序遍歷。思路如下:從根節點開始,先將根節點列印,然後如果有左孩子,就將左孩子入佇列,如果有右孩子,就將右孩子入佇列。然後從佇列**乙個元素,將這個元素列印,然後如果有左孩子,就將左孩子入佇列,如果有右孩子,就將右孩子入佇列,就這樣,如果有乙個孩子是null;那就看另外乙個孩子,如果都是null,那就只進行乙個出佇列的列印就好了,這樣,層層迴圈,就完成了層序遍歷。
void binarytreelevelorder(btnode* root)//層序遍歷
if (root->rchild)
root = qu.head->_data;//拿取對頭
queuepop(&qu);//出對頭
} //queuedestory(&qu);
}
非遞迴的遍歷:
前序遍歷
用非遞迴方式的前序遍歷,是利用自己模擬乙個棧,通過棧的先入後出的原則,進行乙個前序遍歷。思路如下:我們在一開始,先將根節點列印,然後將根節點的右孩子進棧(右孩子不為null),將根節點變為左孩子(左孩子不為null),然後繼續執行的讓根節點的右孩子進棧,列印根節點,直到遇到null,這個時候,我們已經將左孩子遍歷了一遍,需要進入右孩子了,我們進行乙個拿取棧頂的操作,然後讓節點變為棧頂的那個元素,同時進行一次退棧,這個時候,拿到地棧頂就是這個葉子節點的根節點的右孩子了,這樣進行乙個迴圈,就完成了非遞迴的前序遍歷。
void binarytreeprevordernonr(btnode* root)//非遞迴式的前序遍歷
if (root->lchild)
else
root = st._a[st._top - 1];
stackpop(&st);
} }}
中序遍歷
思路:中序遍歷,是先進行乙個根節和根節點所有左孩子的進棧,然後在遇到根節點的左孩子是null時,然後根節點變為棧頂的元素,進行乙個根節點的列印,進行一次退棧操作,然後去根節點的右孩子的位置,繼續進行乙個根節點的左孩子進棧操作。就這樣,利用乙個迴圈,完成這樣的非遞迴式的中序遍歷。
void binarytreeinordernonr(btnode* root)//非遞迴式的中序遍歷
cur = stacktop(&st);//拿取棧頂
putchar(cur->data);
stackpop(&st);//退棧
cur = cur->rchild;//進入右孩子
if (!cur)
}} stackdestory(&st);
}
後序遍歷
後續遍歷的要求是,在左孩子和右孩子都已經進行了列印後,才列印父親節點,這樣的話,我們就要直到從左孩子回來時,父親節點被訪問的次數,因為父親節點聯絡著左右兩個孩子節點,二叉樹通過左節點回來的根節點,需要經過乙個自己的父親節點,然後才能去到右孩子的位置,因此,我們需要乙個標記,來標出,父親節點被訪問的次數。如果父親節點沒有被左孩子返回時訪問,這個標記就是0,如果被左孩子返回訪問了一次,就記做1。這時,我們可以定義乙個陣列,這個陣列的下表等於棧空間中父親節點的位置。我們通過進行最初始的根節點的入棧開始,一直向左孩子方向進行入棧操作,直到遇到null停止,這個時候,棧頂的下標就代表了自己在陣列中的訪問次數,我們進行乙個拿取棧頂的操作,同時將陣列中這個節點的位置,進行乙個置1的操作,這樣,如果下一次拿去棧頂的時候,如果發現這個棧頂在陣列中的數是1的時候,就代表這個棧頂,已經被訪問過一次,就進行乙個棧頂的列印,這裡的列印是乙個迴圈列印,如果根節點及他的父親節點的標記都是1的話,就依次向上進行列印,直到遇到0的位置停止,每次列印完了就進行一次退棧。最後通過乙個迴圈,就完成了乙個非遞迴式的後序遍歷。
void binarytreepostordernonr(btnode* root)//非遞迴式的後序遍歷
;//建立乙個陣列
stackinit(&st);
while (1)
while (arr[st._top - 1])//關鍵所在,判斷父親節點是否是的陣列元素是否是1,若是,則進行乙個迴圈列印,直到遇到是0的停止
cur = stacktop(&st);//拿取棧頂
putchar(cur->data);
stackpop(&st);//退棧
} if (st._top == 0)//判斷在退棧之前 棧是否是空
cur = stacktop(&st);//拿取棧頂
arr[st._top - 1] = 1;//將該父親節點的陣列元素置1
cur = cur->rchild;//進入右孩子
} stackdestory(&st);
}
二叉樹的7種遍歷演算法
中根遞迴遍歷演算法 後根遞迴遍歷演算法 先根非遞迴遍歷演算法 中根非遞迴遍歷演算法 後根非遞迴遍歷演算法 層序遍歷演算法 1.若二叉樹為空則退出,否則進行以下步驟 2.訪問當前的根節點 3.先根順序遍歷訪問左子樹 4.先根順序遍歷訪問右子樹 5.退出 public static void proor...
二叉樹 鏈式儲存的遍歷
include include include define status void define teletype char define null 0 typedef struct bitnode bitnode,bitree bitree jj bitree bin jj 構造二叉樹鍊錶表示的...
二叉樹遍歷方式
先序遍歷 根 左子樹 右子樹 遞迴版本 public static void preprint treenode root 非遞迴版本 public static void preorder treenode root if s.empty 中序遍歷 左子樹 根 右子樹 遞迴版本 public st...