二叉樹的建立 非遞迴遍歷

2021-08-07 04:43:33 字數 1902 閱讀 9181

struct binarytree

;binarytree* createbinarytree() //先序建樹 若碰到『#』就是表示為空,如果不是空,就先建左子樹,後建立右子樹

else

return p;

}

借助棧。

判斷當前節點是否為空,否,把當前節點壓入棧,訪問該節點,並左路下降pnode指向pnode->left

若為空,指向右子樹(pnode->right),彈出棧頂元素。

void preordernorecursion(binarytree* pnode)  

else

}}

借助棧。 判斷是否為空,否,把當前節點壓入棧,並左路下降pnode指向pnode->left 。

若為空,取棧頂元素,訪問該元素節點,並指向右子樹(pnode->right),彈出棧頂元素。

void inordernorecursion(binarytree* pnode)

else

}}

乙個節點會入兩次棧,左路下降的時候第一次入棧,直到為空,彈出當前節點,這是第一次出棧,然後直接再壓進去棧,之後判斷其右子樹,然後繼續入棧。如果右子樹也為空了,此時第二次彈出,彈出的同時訪該節點。

void postordernorecursion(binarytree* pnode)

flagpnode = mystack.top(); //左邊沒有左子樹了,就要出棧了

mystack.pop(); //第一次出棧

if (!flagpnode->issecondpop) //如果是第一次出棧,就把它再壓進去,因為要判斷右邊還有沒有子樹

else

//如果是第二次出棧,就訪問它

}}

如果要求不能改變二叉樹的結構,則需要自己從新構造乙個具有判斷是否第二次進棧bool變數的新結構體。如下:

void postordernorecursion(binarytree* pnode)

; stack

mystack;

flagbt flagpnode;

while (pnode||!mystack.empty())

flagpnode = mystack.top(); //左邊沒有左子樹了,就要出棧了

mystack.pop(); //第一次出棧

if (!flagpnode.issecondpop) //如果是第一次出棧,就把它再壓進去,因為要判斷右邊還有沒有子樹

else

//如果是第二次出棧,就訪問它

}}

借助佇列:

void breadthorder(binarytree* pnode)

}

但是很多有分層輸出的要求,需要記錄每一層的終點,待補充……

還是需要乙個佇列來記錄,但是在每一層一開始會根據當前佇列的大小來標記為last,當小於這個last時,把這層的節點列印出來,然後這個節點彈出佇列,同時把他的左右孩子壓入佇列中。這樣沒列印出新的一層,這一層的節點都彈出了佇列,同時下一層(這一層的左右孩子)又壓入佇列,周而復始,直到隊列為空。

vector

> breadthorder_layer(binarytree* pnode)

res.push_back(layer); //當前層壓入結果陣列

//cout << endl;

}return res;

}

二叉樹遍歷(遞迴 非遞迴)

二叉樹以及對二叉樹的三種遍歷 先根,中根,後根 的遞迴遍歷演算法實現,以及先根遍歷的非遞迴實現。node public class node public node left public node right public object value 遍歷訪問操作介面 public inte ce ...

二叉樹非遞迴遍歷

二叉樹非遞迴遍歷的幾個要點 1 不管前序 中序還是後序,它們的遍歷路線 或者說是回溯路線,先沿左邊一直走到盡頭,然後回溯到某節點,並跳轉到該節點的右孩子 如果有的話 然後又沿著這個有孩子的左邊一直走到盡頭 都是一樣的。2 明確每次回溯的目的。比如,前序回溯的目的是為了訪問右子樹 中序回溯的目的是為了...

非遞迴遍歷二叉樹

中序遞迴遍歷 void inordertrvdigui node pnode 然而,當樹的深度很大 比如16 時 假設為滿二叉樹 樹的節點數為 2 0 2 1 2 2 2 15 2 16 65536,遍歷整個二叉樹意味著有65536次函式呼叫,這將極大地增加程式執行時間。這時,應該採取非遞迴便利二叉...