樹的非遞迴遍歷
阿新 • • 發佈:2018-12-06
前序非遞迴遍歷
void preOrder2(BinTree *root) //非遞迴前序遍歷 { stack<BinTree*> s; BinTree *p=root; while(p!=NULL||!s.empty()) { while(p!=NULL) { cout<<p->data<<" "; s.push(p); p=p->lchild; }if(!s.empty()) { p=s.top(); s.pop(); p=p->rchild; } } }
中序非遞迴遍歷
void inOrder2(BinTree *root) //非遞迴中序遍歷 { stack<BinTree*> s; BinTree *p=root; while(p!=NULL||!s.empty()) { while(p!=NULL) { s.push(p); p=p->lchild; } if(!s.empty()) { p=s.top(); cout<<p->data<<" "; s.pop(); p=p->rchild; } } }
後序非遞迴遍歷
要保證根結點在左孩子和右孩子訪問之後才能訪問,因此對於任一結點P,先將其入棧。如果P不存在左孩子和右孩子,則可以直接訪問它;或者P存 在左孩子或者右孩子,但是其左孩子和右孩子都已被訪問過了,則同樣可以直接訪問該結點。若非上述兩種情況,則將P的右孩子和左孩子依次入棧,這樣就保證了 每次取棧頂元素的時候,左孩子在右孩子前面被訪問,左孩子和右孩子都在根結點前面被訪問。
void postOrder3(BinTree *root) //非遞迴後序遍歷 { stack<BinTree*> s; BinTree *cur; //當前結點 BinTree *pre=NULL; //前一次訪問的結點 s.push(root); while(!s.empty()) { cur=s.top(); if((cur->lchild==NULL&&cur->rchild==NULL)|| (pre!=NULL&&(pre==cur->lchild||pre==cur->rchild))) { cout<<cur->data<<" "; //如果當前結點沒有孩子結點或者孩子節點都已被訪問過 s.pop(); pre=cur; } else { if(cur->rchild!=NULL) s.push(cur->rchild); if(cur->lchild!=NULL) s.push(cur->lchild); } } }