1. 程式人生 > >線索化二叉樹(附三種非遞迴方式遍歷二叉樹)

線索化二叉樹(附三種非遞迴方式遍歷二叉樹)

資料結構二叉樹這快學的雲裡霧裡,所以就寫歌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();
}

執行截圖:
在這裡插入圖片描述
線索化二叉樹這塊展示的是先序線索化結果,中序可以解註釋,在執行。樹這塊就是暫時用的少,長時間不接觸,多看程式碼。否則真會忘~~~