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 }