深度優先遍歷(棧,先壓右節點,再壓左節點)
也就深入的遍歷,沿着每一個分支直到走到最后,然后才返回來遍歷剩余的節點。二叉樹不同於圖,圖需要標記節點是否已經訪問過,因為可能會存在環,而二叉樹不會出現環,所以不需要標記。那么,我們只需要一個棧空間,來壓棧就好了。因為深度優先遍歷,遍歷了根節點后,就開始遍歷左子樹,所以右子樹肯定最后遍歷。我們利用棧的性質,先將右子樹壓棧,然后在對左子樹壓棧。此時,左子樹節點是在top上的,所以可以先去遍歷左子樹。
如下是深度優先遍歷的代碼:
1 void DepthFirstTravel(Tree *root) 2 { 3 stack<Tree *> s; 4 s.push(root); 5 while(!s.empty()) 6 { 7 root = s.top(); 8 cout << root->data << " "; 9 s.pop(); 10 if(root->rchild != NULL) 11 { 12 s.push(root->rchild); 13 } 14 if(root->lchild != NULL) 15 { 16 s.push(root->lchild); 17 } 18 19 } 20 }
廣度優先遍歷二叉樹(隊列:先壓左節點,再壓右節點)
也就是按層次的去遍歷。依次遍歷根節點,然后是左孩子和右孩子。所以要遍歷完當前節點的所有孩子,這樣才是層次遍歷嘛。此時我們就不能用棧這個數據結構了,因為棧只能在棧頂操作。在這里,我們需要根據左右孩子的順序來輸出,所以就是先進先出的原則,那么我們當然就想到了隊列這個數據結構。可以在rear依次插入左右孩子,在front依次讀取並刪除左右孩子,這樣就保證了層次的輸出。
下面是二叉樹的廣度優先遍歷代碼:
1 void BreadthFirstTravel(Tree *root) 2 { 3 queue<Tree *> q; 4 q.push(root); 5 while(!q.empty()) 6 { 7 root = q.front(); 8 cout << root->data << " "; 9 q.pop(); 10 if(root->lchild != NULL) 11 { 12 q.push(root->lchild); 13 } 14 if(root->rchild != NULL) 15 { 16 q.push(root->rchild); 17 } 18 } 19 }