《程式設計之美 分層遍歷二叉樹》的另外兩個實現

2021-06-23 02:14:26 字數 2325 閱讀 4435

之前重溫本書寫書評時,也嘗試找尋更好的程式設計解法。今天把另乙個問題的實現和大家分享。

給定一棵二叉樹,要求按分層遍歷該二叉樹,即從上到下按層次訪問該二叉樹(每一層將單獨輸出一行),每一層要求訪問的順序為從左到右,並將節點依次編號。下面是乙個例子:

輸出:

1

2 34 5 6

7 8

節點的定義:

struct node ;
書上舉出兩個解法。第乙個解法是用遞迴方式,搜尋並列印某一層的節點,再列印下一層的節點。這方法簡單但時間效率不高(但不需要額外空間),因此書中亦提供了第二個解法。

書中第二個解法,使用vector容器來儲存n個節點資訊,並用乙個游標變數last記錄前一層的訪問結束條件,實現如下:

void printnodebylevel(node* root) 

cout << endl; // 當cur == last時,說明該層訪問結束,輸出換行符}}

書中沒有提及,本問題其實是以廣度優先搜尋(breath-first search, bfs)去遍歷乙個樹結構。廣度優先搜尋的典型實現是使用佇列(queue)。其偽**如下:

enqueue(q, root)

do node = dequeue(q)

process(node) //如把內容列印

for each child of node

enqueue(q, child)

while q is not empty

書上的解法,事實上也使用了乙個佇列。但本人認為,使用vector容器,較不直覺,而且其空間複雜度是o(n)。

如果用佇列去實現bfs,不處理換行,能簡單翻譯偽**為c++**:

void printbfs(node* root) 

while (!q.empty());

}

本人覺得這樣的演算法實現可能比較清楚,而且空間複雜度只需o(m),m為樹中最多節點的層的節點數量。最壞的情況是當二叉樹為完整,m = n/2。

之後的難點在於如何換行。

第乙個嘗試,利用了兩個佇列,乙個儲存本層的節點,另乙個儲存下層的節點。遍歷本層的節點,把其子代節點排入下層佇列。本層遍歷完畢後,就可換行,並交換兩個佇列。

void printnodebylevel(node* root)  while (!q1.empty());

cout << endl;

q1.swap(q2);

} while(!q1.empty());

}

本實現使用deque而不是queue,因為deque才支援swap()操作。注意,swap()是o(1)的操作,實際上只是交換指標。

這實現要用兩個迴圈(書上的實現也是),並且用了兩個佇列。能夠只用乙個迴圈、乙個佇列麼?

換行問題其實在於如何表達一層的結束。書上採用了游標,而第乙個嘗試則用了兩個佇列。本人想到第三個可行方案,是把乙個結束訊號放進佇列裡。由於使用queue,可以插入乙個空指標去表示一層的遍歷結束。

void printnodebylevel(node* root) 

else if (!q.empty())

} while (!q.empty());

}

這個實現的**很貼近之前的printbfs(),也只有乙個迴圈。注意一點,當發現空指標(結束訊號)時,要檢查佇列內是否還有節點,如果沒有的話還插入新的結束訊號,則會做成死迴圈。

void link(node* nodes, int parent, int left, int right) 

void main();

for (int i = 1; i < 9; i++)

test1[i].data = i;

link(test1, 1, 2, 3);

link(test1, 2, 4, 5);

link(test1, 3, 6, -1);

link(test1, 5, 7, 8);

printbfs(&test1[1]);

cout << endl << endl;

printnodebylevel(&test1[1]);

cout << endl;

}

第乙個嘗試是幾個月前做的,沒想到今晚寫博文又想到了第二個嘗試。兩個嘗試難分優劣,但兩種思維或許也可以解決其他問題。還有其他方法麼?

程式設計之美 分層遍歷二叉樹

問題定義 給定一棵二叉樹,要求按分層遍歷該二叉樹,即從上到下按層次訪問該二叉樹 每一層將單獨輸出一行 每一層要求訪問的順序為從左到右,並將節點依次編號。下面是乙個例子 輸出 1 2 34 5 6 7 8節點的定義 1structnode 書上舉出兩個解法。第乙個解法是用遞迴方式,搜尋並列印某一層的節...

程式設計之美 分層遍歷二叉樹

問題 給定乙個二叉樹,要求按分層遍歷該二叉樹,即從上到下按層次訪問該二叉樹 每一層將單獨輸出一行 每一層要求訪問的順序為從左到右,並將節點依次編號。那麼分層遍歷如圖的二叉樹,正確的輸出應該為 分析與解法 關於二叉樹的問題,由於其本身固有的遞迴特性,通常可以用遞迴解決。為了解決給出的問題,我們可以發現...

《程式設計之美 分層遍歷二叉樹》的另外兩個實現

之前重溫本書寫 書評時,也嘗試找尋更好的程式設計解法。今天把另乙個問題的實現和大家分享。給定一棵二叉樹,要求按分層遍歷該二叉樹,即從上到下按層次訪問該二叉樹 每一層將單獨輸出一行 每一層要求訪問的順序為從左到右,並將節點依次編號。下面是乙個例子 節點的定義 書上的解法 書上舉出兩個解法。第乙個解法是...