思路是很簡單。
一種思路是對每一層的節點數進行計數,首先在佇列中預存好整棵樹的根節點。然後不斷地從佇列中取出當前層的節點,以及加入下一層的節點。如果你只是按照層序的順序遍歷,那很簡單。但如果你在每一層結束之後還需要做一些額外操作(比如換行等),那麼就有一些細節需要注意。這裡主要是剖析一下後面的情況。
如果在每一層的最後都需要一些額外操作,那麼每一層的尾節點(每一層的最後乙個節點)很關鍵,必須先處理完所有普通節點都具有的操作(比如列印當前值、新增左右子節點到佇列等)後,然後再處理尾節點作為乙個特殊節點所特有的操作(比如換行等)。詳細看下圖和**。
**如下:
#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...