【二叉樹】指定結點到根節點的路徑
阿新 • • 發佈:2018-12-19
利用後序遍歷非遞迴的思想,結合棧。
如果某結點的左右子樹均未找到指定結點,則將該結點出棧,那就需要標記一下當前結點的訪問狀態。
直到找到結點,或者遍歷完樹仍未找到(此時棧空)。
typedef struct BNode { int data; BNode *lchild,*rchild; }*BTree; typedef struct { BNode* bt; int isFirst; }SElemType; typedef struct { SElemType leaf[MAXSIZE]; int top; } Stack; void initStack(Stack &s) { s.top=0; } void push(Stack &s,SElemType n) { s.leaf[s.top]=n; s.top++; } SElemType pop(Stack &s) //出棧並返回棧頂元素 { SElemType x=s.leaf[s.top-1]; s.top--; return x; } int isEmpty(Stack s) { if(s.top==0) return 1; //空 return 0; //非空 } void createBTree(BTree &t) { int ch; cin>>ch; if(ch==0) t=NULL; else { t=(BTree)malloc(sizeof(BNode)); t->data=ch; createBTree(t->lchild); createBTree(t->rchild); } } Stack getPath(BTree t,int x) { Stack s; initStack(s); SElemType elem; while(t||!isEmpty(s)) { //所有左孩子入棧 while(t) { elem.isFirst=1; //第一次訪問 elem.bt=t; push(s,elem); if(t->data==x) return s; //找到指定結點,返回。 t=t->lchild; } if(!isEmpty(s)) { elem=pop(s); t=elem.bt->rchild; //如果第一次訪問該節點(即還有右子樹沒有查詢),出棧後取其右孩子後,更改訪問狀態再放回 if(elem.isFirst==1) { elem.isFirst=0; push(s,elem); } } } return s; } int main() { BTree t; Stack sta; int x; cout<<"先序遍歷輸入樹:"; createBTree(t); cout<<"輸入要查詢的結點資料"; cin>>x; sta=getPath(t,x); cout<<"路徑為:"; if(isEmpty(sta)) cout<<"不存在"<<endl; else { while(!isEmpty(sta)) { cout<<pop(sta).bt->data<<" "; } } return 0; }