鏈式二叉樹的7種遍歷方式

2021-09-26 08:21:05 字數 4816 閱讀 2211

在說鏈式二叉樹的遍歷之前,我們先來說一下如何建立乙個鏈式二叉樹。建立乙個鏈式二叉樹,需要乙個已知的字串,這個字串必須支援建立二叉樹的規則。比如:

我們通過遞迴來實現二叉樹的建立,開始先向左走,如果遇到#,就返回,然後向右走,直到遇到#,就返回乙個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...