線索化二叉樹(附三種非遞迴方式遍歷二叉樹)
阿新 • • 發佈:2018-11-17
資料結構二叉樹這快學的雲裡霧裡,所以就寫歌c++樹的類來將這寫東西全部封裝起來,想用那個直接呼叫方法,我決免費將這個大類提供給大家,提供學習上的參考,少走彎路,由於程式碼比較多,我就將各方法的功能做了註釋,如果那有什麼不懂的,可以交流。線面就是原始碼了~~~
tree.h
#ifndef _TREE_H #define _TREE_H class tree{ public: tree(){ } ~tree(){} tree*input(); void firstNdigui(); void midNdigui(); void lastNdigui(); void getThTree(); tree* getMcur(tree*root); void FthreadTree(tree*root); void Mprint(tree*root); void MthreadTree(tree*root); tree*getNext(tree*p); void Fprint(tree*root); private: int data ; tree* root; tree*l ; int tag ; int tag_r; tree * pre ; tree*r ; }; #endif
trees.h
#ifndef _TREES_H #define _TREES_H #include"tree.h" #include<stack> #include<stdio.h> #include<iostream> using namespace std ; //建立擴充套件先序二叉樹 tree*tree::input(){ tree *t; int a ; cin>>a ; if(a == -1){ return NULL ; } else{ t= new tree() ; t->data =a ; t->tag = 0 ; t->tag_r = 0 ; t->l = input(); t->r = input(); } return t ; } //先序非遞迴遍歷二叉樹 void tree::firstNdigui(){ root= input(); stack<tree*>s ; tree* q ; q = root ; while(q!=NULL||!s.empty()){ if(q != NULL){ cout<<q->data<<endl ; s.push(q); q= q->l ; } else{ q=s.top(); q=q->r ; s.pop(); } } } //中序非遞迴遍歷二叉樹 void tree::midNdigui(){ root = input(); stack<tree*>s ; tree * q ; q = root ; while(q!=NULL||!s.empty()){ if(q!= NULL) { s.push(q); q= q->l; } else{ q= s.top(); cout<<q->data<<endl ; q = q->r ; s.pop(); } } } //後續非遞迴 void tree::lastNdigui(){ root= input(); stack<tree*>s; tree* q= root ; while(q!= NULL ||!s.empty()){ while(q!= NULL){ s.push(q); q= q->l ; } if(!s.empty()){ q = s.top(); if(q->tag==0){ q->tag = 1 ; q= q->r; } else{ cout<<q->data<<endl; s.pop(); q = NULL; } } } } //獲取線索二叉樹並列印 void tree::getThTree(){ pre = NULL ; pre= new tree(); tree * root = input(); //解註釋用中序線索化二叉樹 //MthreadTree(root); //Mprint(root); //先序線索化二叉樹 FthreadTree(root); Fprint(root); } //先序線索化二叉樹 void tree::FthreadTree(tree * root){ if(root){ if(root->l == NULL){ root->l = pre ; root->tag = 1; } if(pre != NULL&& pre->r == NULL){ pre->r = root ; pre->tag_r = 1 ; } pre= root ; if(root->tag == 0) FthreadTree(root->l); if(root->tag_r == 0){ FthreadTree(root->r); } } } //先序線索二叉樹遍歷 void tree::Fprint(tree *root){ tree* p = root; while(p){ cout<<p->data<<endl ; if(p->tag== 0){ p = p->l; } else{ p = p->r ; } } } //中序線索化 void tree::MthreadTree(tree*root){ if(root){ MthreadTree(root->l); if(root->l == NULL) { root->l = pre ; root->tag = 1 ; } if(pre!= NULL&&pre->r == NULL ){ pre->r = root ; pre->tag_r = 1 ; } pre = root ; MthreadTree(root->r); } } //列印中序線索化二叉樹 void tree::Mprint(tree *root){ tree * p ; p = getMcur(root); while(p){ cout<<p->data<<endl; p = getNext(p); if(p->r== NULL){ cout<<p->data<<endl; break; } } } //獲取中序線索二叉樹下一個節點 tree*tree::getNext(tree *p){ if(p->tag_r == 1){ p = p->r ; } else for(p = p->r ;p->tag !=1 ; p= p->l); return p ; } //獲取中序線索二叉樹當前節點 tree* tree::getMcur(tree * root){ tree* q = root; if(q ==NULL){ return NULL ; } while(q->tag != 1)q= q->l ; return q ; } #endif
tree.cpp
#include<iostream> #include"trees.h" #include"tree.h" #include<list> using namespace std; int main(){ tree tt ; cout<<"先序非遞迴遍歷二叉樹:"<<endl ; tt.firstNdigui(); cout<<"後續非遞迴遍歷二叉樹:"<<endl ; //使用後序非遞迴進行遍歷二叉樹 tt.lastNdigui(); cout<<"中序非遞迴遍歷二叉樹:"<<endl ; tt.midNdigui(); cout<<"線索化二叉樹:(先序和中序)"<<endl; tt.getThTree(); }
執行截圖:
線索化二叉樹這塊展示的是先序線索化結果,中序可以解註釋,在執行。樹這塊就是暫時用的少,長時間不接觸,多看程式碼。否則真會忘~~~