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 }