二叉樹 全面剖析層序遍歷演算法

2021-10-05 16:27:59 字數 4342 閱讀 5849

思路是很簡單。

一種思路是對每一層的節點數進行計數,首先在佇列中預存好整棵樹的根節點。然後不斷地從佇列中取出當前層的節點,以及加入下一層的節點。如果你只是按照層序的順序遍歷,那很簡單。但如果你在每一層結束之後還需要做一些額外操作(比如換行等),那麼就有一些細節需要注意。這裡主要是剖析一下後面的情況。

如果在每一層的最後都需要一些額外操作,那麼每一層的尾節點(每一層的最後乙個節點)很關鍵,必須先處理完所有普通節點都具有的操作(比如列印當前值、新增左右子節點到佇列等)後,然後再處理尾節點作為乙個特殊節點所特有的操作(比如換行等)。詳細看下圖和**。

**如下:

#include

#include

using

namespace std;

class

node

node

(int _val)

:val

(_val)

,left

(null),

right

(null),

next

(null

)node

(int _val, node* _left, node* _right, node* _next)

:val

(_val)

,left

(_left)

,right

(_right)

,next

(_next)};

void

f(node* root)

queue

> q;

q.push

(root)

;int cur_len =1;

int next_len =0;

while

(!q.

empty()

)if(cur-

>right)

// 尾節點作為乙個特殊節點所特有的操作

另一種思路不是對每一層計數,而是用level_begin記錄下一層的首節點(下一層的第乙個節點)的指標。當按照層序遍歷的順序遍歷到level_begin時,說明當前指標已經指向了新的一層。如果在每一層的最後都需要一些額外操作,那麼下一層的首節點(下一層的第乙個節點)很關鍵。對於首節點的處理,與上乙個思路正好相反,必須先處理完首節點作為乙個特殊節點所特有的操作(比如換行等)後,然後再處理所有普通節點都具有的操作(比如列印當前值、新增左右子節點到佇列等)。

**如下:

#include

#include

using

namespace std;

class

node

node

(int _val)

:val

(_val)

,left

(null),

right

(null),

next

(null

)node

(int _val, node* _left, node* _right, node* _next)

:val

(_val)

,left

(_left)

,right

(_right)

,next

(_next)};

void

f(node* root)

queue

> q;

q.push

(root)

; node* level_begin = root;

while

(!q.

empty()

)// 所有普通節點都有的操作

cout << cur-

>val <<

" ";

// 所有普通節點都有的操作

兩種思路的區別在於,按照第一種思路遍歷完之後,則會多輸出乙個換行符;而按照第二種思路,則會在輸出第一層的第乙個節點之前,多輸出乙個換行符。當然,多餘的換行符是可以避免輸出的。對於第一種思路,將尾節點的判斷條件if (cur_len <= 0)改為if (cur_len <= 0 && !q.empty()),多了乙個!q.empty();對於第二種思路,將level_begin的初值從root改為nullptr就好。

最終修改後的**如下:

第一種思路:

#include

#include

using

namespace std;

class

node

node

(int _val)

:val

(_val)

,left

(null),

right

(null),

next

(null

)node

(int _val, node* _left, node* _right, node* _next)

:val

(_val)

,left

(_left)

,right

(_right)

,next

(_next)};

void

f(node* root)

queue

> q;

q.push

(root)

;int cur_len =1;

int next_len =0;

while

(!q.

empty()

)if(cur-

>right)

// 尾節點作為乙個特殊節點所特有的操作

if(cur_len <=0&&

!q.empty()

)}}int

main()

第二種思路:

#include

#include

using

namespace std;

class

node

node

(int _val)

:val

(_val)

,left

(null),

right

(null),

next

(null

)node

(int _val, node* _left, node* _right, node* _next)

:val

(_val)

,left

(_left)

,right

(_right)

,next

(_next)};

void

f(node* root)

queue

> q;

q.push

(root)

; node* level_begin =

nullptr

;while

(!q.

empty()

)// 所有普通節點都有的操作

cout << cur-

>val <<

" ";

// 所有普通節點都有的操作

if(cur-

>left)

q.push

(cur-

>left);}

if(cur-

>right)

q.push

(cur-

>right);}

}}intmain()

二叉樹層序遍歷 求二叉樹的層序遍歷

給定乙個二叉樹,返回該二叉樹層序遍歷的結果,從左到右,一層一層地遍歷 例如 給定的二叉樹是,該二叉樹層序遍歷的結果是 3 9,20 15,7 示例1 輸入 返回值 1 2 示例2輸入 返回值 1 2,3 4,5 解題思路 重點是如何把在一層的節點放到一起,設定乙個引數專門放一層的節點 class t...

層序遍歷二叉樹

要求 設計乙個演算法層序遍歷二叉樹 同一層從左到右訪問 我寫了乙個演算法 用乙個佇列儲存被訪問的當前節點的左右孩子以實現層序遍歷。status hierarchybitree bitree t,status visit telemtype e destroyqueue q 釋放佇列空間 return...

二叉樹層序遍歷

主要流程 確定root非空 根指標進佇列 佇列非空就一直迴圈 依次掃瞄目前佇列中所有元素 新增的不算 從佇列取出第一元素 將值放入結果vector中 判斷左右子節點非空,並依次入隊 將本次結果放入二維陣列中 如果需要按層逆序輸出的話,在這裡將二維結果倒排一下 返回二維結果 vector levelo...