二叉树的构造_遍历_求数高和求节点数

 
   
  1 //手工构造一颗二叉树 ,并给出递归和非递归2类7种遍历方法,树高,节点数求法和逆时针90度显示二叉树 

  2 //注意本文中2个 typename的使用层次 

  3 //递归遍历容易溢栈 

  4 #include <cstdlib>

  5 #include <iostream>

  6 #include <queue> //用到队列时需要包含此文件 

  7 #include <stack> //用到栈时需要包含此文件 

  8 

  9 using namespace std;

 10 

 11 

 12 template <typename T>//模板类需要template和struct2个语句!!!!!!!! 

 13 struct Btnode{

 14        Btnode *lc_,*rc_;T value_;

 15        Btnode(T const& v=T(),Btnode*lc=0,Btnode*rc=0)

 16        :lc_(lc),rc_(rc),value_(v){}

 17        bool haslc(void) const{return lc_!=0;}

 18        bool hasrc(void) const{return rc_!=0;} 

 19        };

 20 

 21 template<typename NT>

 22 //中序遍历 

 23 void inorder(NT* root,void(*visit)(NT*)){//注意第二个参数的函数传递方法 

 24      if(root!=0){

 25        inorder(root->lc_,visit);

 26        visit(root);

 27        inorder(root->rc_,visit);          

 28                  } 

 29      }

 30 template<typename NT>

 31 //中序遍历 

 32 void inorder2(NT* root,void(*visit)(NT*)){   

 33   if(root==0) return;

 34    stack<NT* > s; s.push(root);

 35    while(true){

 36     root=s.top();

 37     while(root->haslc()) s.push(root=root->lc_);

 38     do{visit(root=s.top());s.pop();}while(!root->hasrc()&&!s.empty());

 39     if(root->hasrc()) s.push(root->rc_);

 40     else return;           

 41               }    

 42      } 

 43      

 44 //后序遍历 

 45 template<typename NT>    

 46 void postorder(NT* root,void(*visit)(NT*)){

 47      if(root!=0){

 48      postorder(root->lc_,visit);

 49      postorder(root->rc_,visit);

 50      visit(root);            

 51                  }

 52      }  

 53      

 54 template<typename NT>    

 55 void postorder2(NT* root,void(*visit)(NT*)){    

 56      if(root==0) return;

 57      stack<NT*> s; s.push(root);

 58      while(true){

 59      root=s.top();

 60      while(root->haslc()) s.push(root=root->lc_);

 61      if(root->hasrc()) s.push(root->rc_);

 62      else{

 63           do{

 64              visit(root=s.top());s.pop();

 65              if(s.empty()) return;         

 66                        }while((root==s.top()->rc_)||!(s.top()->hasrc()));

 67                        s.push(s.top()->rc_);

 68         }

 69      }

 70      }

 71      

 72          

 73 //先序遍历

 74 template<typename NT>//发现该语句必须紧紧在preorder前面才可以 

 75 void preorder(NT* root,void(*visit)(NT*)){

 76      if(root!=0){

 77      visit(root); 

 78      preorder(root->lc_,visit);

 79      preorder(root->rc_,visit);              

 80                  }

 81      }     

 82 template<typename NT>

 83  void preorder2(NT*root,void(*visit)(NT*)){

 84       if(root==0) return;

 85       stack<NT*> s;

 86       while(true){

 87       visit(root);

 88       if(root->hasrc()) s.push(root->rc_);

 89       if(root->haslc()) root=root->lc_;

 90       else if(s.empty()) return;

 91       else{root=s.top();s.pop();}

 92                   }

 93       }    

 94      

 95      

 96   // 按层遍历 

 97   template<typename NT>   

 98    void levelorder(NT* root,void(*visit)(NT*)){

 99      if(root==0) return;

100      queue<NT*> q; q.push(root);

101      while(!q.empty()){

102        NT* t=q.front();q.pop();

103        if(t->haslc()) q.push(t->lc_);

104        if(t->hasrc()) q.push(t->rc_);    

105        visit(t);           

106                        } 

107      }     

108      

109  template<typename NT>   

110  int height(NT const* root){

111     if(root==0) return 0;

112     int ld=height(root->lc_);

113     int rd=height(root->rc_);

114     return 1+std::max(ld,rd); 

115    }    

116      

117   template<typename NT> 

118   int size(NT const* root){

119       if(root==0) return 0;

120       return 1+size(root->lc_)+size(root->rc_);

121       }   

122  template<typename NT>

123  void display(NT* root,int col=0){

124       if(root==0) return;

125       display(root->rc_,col+1);

126       for(int i=0;i<col;++i) std::cout<<"|";

127       std::cout<<"|"<<root->value_<<std::endl;

128       display(root->lc_,col+1);

129       

130       }

131      

132 typedef Btnode<char> NT;//该语句必须在print函数前,以防 NT不能找到 

133 void print(NT*p){std::cout<<p->value_<<"";}

134 

135 

136 int main(int argc, char *argv[])

137 {  

138    

139     //定义二叉树 

140     NT i('I',0,0);NT h('H',0,0);  NT f('F',&h,&i);

141     NT g('G',0,0);NT e('E',&g,0); NT d('D',0,0);

142     NT c('C',0,&f);NT b('B',&d,&e);NT a('A',&b,&c);

143     NT* root=&a;

144     inorder(root,&print);cout<<endl;

145     inorder2(root,&print);cout<<endl;

146     preorder(root,&print);cout<<endl;

147     preorder2(root,&print);cout<<endl;

148     postorder(root,&print);cout<<endl;

149     postorder2(root,&print);cout<<endl;

150     levelorder(root,&print);cout<<endl;

151     cout<<"height="<<height(root)<<endl;

152     cout<<"number of nodes="<<size(root)<<endl;

153     display(root,0); 

154     system("PAUSE");

155     return EXIT_SUCCESS;

156 }
 
   

 

 
二叉树的构造_遍历_求数高和求节点数 二叉树的构造_遍历_求数高和求节点数
 

 

 
   
 
  

 

你可能感兴趣的:(二叉树)