10.4-5 O(n)非遞歸O(1)空間遍歷二叉樹樹節點node
轉自http://blog.csdn.net/mishifangxiangdefeng/article/details/7708490ios
採用相似中序遍歷的處理方法,對一個結點,能夠分爲如下幾種狀況數組
1.從父結點進入子結點進行處理函數
(1)若是有左孩子,就處理左孩子spa
(2)返回到本身.net
(3)訪問本身指針
(4)若是有右孩子,就處理右孩子blog
(5)返回到本身的父結點遞歸
2.從左孩子返回,說明左孩子已經處理過,本身還沒訪問,本身的右孩子也沒有處理過,就進行1-(2)ci
3.從右孩子返回,說明左右孩子都已經處理,本身也訪問過,就返回到更上層
4.返回到根結點時,遍歷結束
#include <iostream> using namespace std; //二叉樹結點的結構體 struct node { int key;//值 node *left;//指向左孩子 node *right;//指向右孩子 node(){}//默認構造函數 node(int x):key(x),left(NULL),right(NULL){}//構造函數 }; //樹的結構體 struct tree { node *root;//樹中只有一個指向根結點的指針 tree():root(NULL){}//構造函數 }; /************10.4-2-遞歸地遍歷訪問二叉樹***************************************/ //輸出訪問某個結點 void Node_Print(node *N) { //訪問當前結點 cout<<N->key<<' '; //遞歸地訪問其左孩子 if(N->left) Node_Print(N->left); //遞歸地訪問其右孩子 if(N->right) Node_Print(N->right); } //遍歷二叉樹 void Tree_Print(tree *T) { //只孩子訪問根結點,其它結點都在遞歸中訪問了 Node_Print(T->root); cout<<endl; } /*************10.4-3-非遞歸地遍歷二叉樹*******************************************/ //把x結點壓入棧S的頂部 void Push(node *S, node x) { S[0].key++; S[S[0].key] = x; } //彈出棧頂元素並返回 node* Pop(node *S) { if(S[0].key == 0) return NULL; node *ret = &S[S[0].key]; S[0].key--; return ret; } //用非遞歸的方式遍歷二叉樹 void Tree_Print2(tree *T) { //這種方式要藉助一個棧來實現,棧的大小爲樹的深度 node Stack[15] = {0};//簡單的數組棧,Stack[0]存儲棧頂位置 node *t = T->root; //當處理一個結點時,作以下處理 while(1) { //訪問這個結點 cout<<t->key<<' '; //入棧 Push(Stack, *t); //若是有左孩子,下一步處理其左孩子 if(t->left) t = t->left; //若是沒有左孩子 else { do{ //彈出棧頂元素 t = Pop(Stack); //若棧中元素已經所有彈出,那麼二叉樹訪問結束了 if(t == NULL) { cout<<endl; return; } } //若是這個棧頂元素沒有右孩子,則繼續出棧,直到訪問結束或找到一個有右孩子的元素 while(t->right == NULL); //若是這個棧頂元素有右孩子,則訪問其右孩子 t = t->right; } } } /*input:0=NIL 12 7 3 15 8 0 4 10 0 10 5 9 2 0 0 18 1 4 7 0 0 14 6 2 21 0 0 5 0 0 */ int main() { //構造一棵樹按照10.4-1 int i; node A[11];//這個數組僅僅用於構造10.4-1中的樹,在遍歷時不使用 for(i = 1; i <= 10; i++) { int key, left, right; cin>>key>>left>>right; A[i].key = key; if(left) A[i].left = &A[left]; else A[i].left = NULL; if(right) A[i].right = &A[right]; else A[i].right = NULL; } //生成一棵樹 tree *T = new tree(); T->root = &A[6]; //10.4-2,遞歸方式 Tree_Print(T); //10.4-3,非遞歸方式 Tree_Print2(T); return 0; }