思路比較簡單:
就是先調用minimum找到二叉樹中的最小關鍵字的結點,即二叉樹最左邊的樹葉,然後依然迭代地調用tree_successor尋找前一個結點x的後繼:即比x->key大的所有關鍵字中最小的一個的節點。依次輸出即可。
minimum很容易理解,利用蠻力一直往左遍曆,到底即可。
tree_successor分兩種情況,如果x有右子樹,則x的後繼就是右子樹中最小關鍵字的那個結點,如果x沒有右子樹,則後繼是x的最底層祖先。最底層祖先聽著很拗口,用圖示表示就是:13號結點的後繼是15,15即為13的後繼,13的祖先有15和30,而15為13的最底層祖先。
代碼:
#include<iostream>using namespace std;struct node//結點{int key;node* p;node* left;node* right;node(){}node(int k):key(k),p(NULL),left(NULL),right(NULL){}};struct TREE//樹{node* root;TREE():root(NULL){}};node* minimum(node* x)//一直往左遍曆到最底即可{while(x->left!=NULL)x=x->left;return x;}node* tree_successor(node* x)//找後繼{if(x->right!=NULL)//如果有右子樹,則後繼為右子樹中最小值return minimum(x->right);node* y=x->p;//如果沒有右子樹,後繼為最底層祖先while(y!=NULL && y->right==x){x=y;y=y->p;}return y;}void tree_insert(TREE* T,node* z)//插入節點{node* y=NULL;node* x=T->root;//管理兩個指標,父指標y,y的子樹指標xwhile(x!=NULL)//一直向下遍曆到z應該插入的位置{y=x;if(x->key < z->key)x=x->right;else x=x->left;}z->p=y;//先將z的父指標p指向yif(y==NULL)//若樹為空白,樹根即為zT->root=z;else if(z->key < y->key)//否則分插入左邊還是右邊y->left=z;else y->right=z;}void iterative_tree_walk(node* x){node* p=minimum(x);//先找到最小值while(p!=NULL)//然後依次迭代遍曆前一個關鍵字的後繼{cout<<p->key<<' ';p=tree_successor(p);}}void tree_walk(node* x)//遞迴中序{if(x!=NULL){tree_walk(x->left);cout<<x->key<<' ';tree_walk(x->right);}}void main(){int A[]={15,6,18,3,7,17,20,2,4,13,9};int len=sizeof(A)/sizeof(A[0]);TREE* T=new TREE;node* z;for(int i=0;i<len;i++){z=new node(A[i]);tree_insert(T,z);}cout<<"Recursion"<<endl;tree_walk(T->root);cout<<endl;cout<<"Iteration"<<endl;iterative_tree_walk(T->root);cout<<endl;}
運行結果: