分层遍历二叉树
http://www.cnblogs.com/pangxiaodong/archive/2011/09/11/2173560.html
1. 簡述
??? 問題一:給定一棵二叉樹,要求按分層遍歷該二叉樹,即從上到下的層次訪問該二叉樹(每一層將單獨輸出一行),每一層要求訪問的順序為從左到右,并將節點依次編號。
?? ?問題二:寫一個函數,打印二叉樹中某層次的節點(從左到右),其中根節點為第0層,函數原型為int PrintNodeAtLevel(Node* root, int level),成功返回1,失敗返回0。
2. 思路
??? 使用隊列進行廣度優先搜索,主要有一個特點,即如果第k層元素一個都沒出隊,那么隊列中必然沒有k+1層元素,而且如果第k層元素剛好都出隊了,隊列中只有第k+1層元素,且包含所有的k+1層元素。所以從第一層開始,把根節點入隊,記錄當前層節點數1,然后輸出這個層得所有節點,跟新隊列,然后正好隊列中就只有且包含所有第2層得節點數了,依次類推直到隊列為空為止。
?? 簡述中的兩個問題基本上就是一回事,第二個問題就是在第一個問題的基礎上,注意判斷層數,和當前層位置即可。
3. 代碼
??? 這里給出第一個問題的代碼實現。??????
#include<iostream>#include<deque>
using namespace std;
struct NODE {
NODE* pLeft;
NODE* pRight;
int value;
};
void PrintTreeByLevel(const NODE* root) {
deque<const NODE*> store;
int left_num;
if(!root)
return;
store.push_back(root);
while(!store.empty()) {
left_num = store.size(); // 當前層的節點數
while(left_num-- > 0) {
const NODE* tmp = store.front();
store.pop_front();
cout << tmp->value << " ";
if(tmp->pLeft)
store.push_back(tmp->pLeft);
if(tmp->pRight)
store.push_back(tmp->pRight);
}
cout << endl;
}
}
int main() {
NODE* array[8];
for(int i=0; i<8; i++) {
array[i] = new NODE;
array[i]->value = 1 + i;
array[i]->pLeft = array[i]->pRight = NULL;
}
array[0]->pLeft = array[1]; array[0]->pRight = array[2];
array[1]->pLeft = array[3]; array[1]->pRight = NULL;
array[2]->pLeft = array[4]; array[2]->pRight = array[5];
array[4]->pLeft = array[6]; array[4]->pRight = array[7];
PrintTreeByLevel(array[0]);
ReversePrintTreeByLevel(array[0]);
system("PAUSE");
return 0;
}
??? 輸出結果為:?
????
4. 擴展問題
??? 擴展問題中要求先輸出最后一層,然后輸出倒數第二層,···,最后輸出第一層。
??? 第一直覺是按照前面的方法遍歷的過程中,記錄每層元素個數,注意遍歷中只入隊不出隊,每層遍歷是否結束,需要多設置一些計數變量。
??? 不過在參考中的一篇文章中,看到使用啞元素的方法,即在每層中間插入NULL,同樣,遍歷中也是只入隊不出對,每層遍歷是否結束,需要多設置一些計數變量。
??? 代碼如下:???
deque<const NODE*> store;
int index = 0; // 遍歷元素和啞元素的下標
int no = 0; // 遍歷過的元素個數
if(!root) {
return;
}
store.push_back(root);
index = 0;
while(index < store.size()) {
store.push_back(NULL); // 啞元素
while(store[index] != NULL) { // 訪問當前層
no++;
if(store[index]->pRight)
store.push_back(store[index]->pRight);
if(store[index]->pLeft)
store.push_back(store[index]->pLeft);
index++;
}
index++;
}
for(int i=store.size()-1; i>=0; i--) {
if(store[i] == NULL)
cout << endl;
else {
cout << store[i]->value << " ";
}
}
cout << endl;
}
??? 合并兩部分代碼輸出結果為:
????
總結
- 上一篇: 数组分割问题——另一种方法
- 下一篇: 二分查找的各种条件