二叉树方面的常见问题总结
View Code
1 #include <iostream>
2 #include <deque>
3 using namespace std;
4 /*
5 1.二叉树三种周游(traversal)方式(也就是三种遍历)
6 2.怎样从顶部开始逐层打印二叉树结点数据 (层次遍历)
7 3.如何判断一棵二叉树是否是平衡二叉树
8 4.设计一个算法,找出二叉树上任意两个节点的最近共同父结点,复杂度如果是O(n2)则不得分。
9 5.如何不用递归实现二叉树的前序/后序/中序遍历?
10 6.在二叉树中找出和为某一值的所有路径
11 7.怎样编写一个程序,把一个有序整数数组放到二叉树中?
12 8.判断整数序列是不是二叉搜索树的后序遍历结果
13 9.求二叉树的镜像
14 10.一棵排序二叉树(即二叉搜索树BST),令 f=(最大值+最小值)/2,设计一个算法,找出距
15 离f值最近、大于f值的结点。复杂度如果是O(n2)则不得分。
16 11.把二叉搜索树转变成排序的双向链表
17 12.打印二叉树中的所有路径(与题目5很相似) (这道题很重要)
18 */
19 typedef struct BiTNode // 二叉树结构体
20 {
21 int data;
22 struct BiTNode *lchild,*rchild; // 左右孩子指针
23 }BiTNode,*BiTree;
24
25 typedef struct LNode // 双向链表结构体
26 {
27 int data;
28 struct LNode *next,*prior; // 后继、前继
29 }LNode,*Linklist;
30
31 void CreateBiTree(BiTree &T)
32 {
33 char ch;
34 cin >> ch;
35 if(ch == '#') { T = NULL; return;}
36 else
37 {
38 BiTNode *pt = new BiTNode;
39 T = pt;
40 T->data = ch;
41 CreateBiTree(T->lchild);
42 CreateBiTree(T->rchild);
43 }
44 }
45
46 void PreOrder(BiTree T) // 先序遍历
47 {
48 if(T != NULL) { cout << T->data - '0' << ' ';}
49 else
50 {
51 cout << '#' << ' ';
52 return;
53 }
54 PreOrder(T->lchild);
55 PreOrder(T->rchild);
56 }
57
58 void InOrder(BiTree T) // 中序遍历
59 {
60 if(T != NULL)
61 {
62 InOrder(T->lchild);
63 cout << T->data - '0' << ' ';
64 InOrder(T->rchild);
65 }
66 else
67 {
68 cout << '#' << ' ';
69 return;
70 }
71 }
72
73 void LevelOrder(BiTree T) // 层次遍历
74 {
75 // 需要用到队列
76 deque<BiTNode> deq;
77 if(T == NULL )
78 {
79 cout << '#' << ' '; return;
80 }
81 else
82 deq.push_back(*T);
83
84 while(!deq.empty())
85 {
86 BiTNode p;
87 deque<BiTNode>::iterator i = deq.begin();
88 p = *i;
89 cout << p.data - '0' << ' ';
90 if(p.lchild != NULL)
91 deq.push_back(*p.lchild);
92
93 if(p.rchild != NULL) // 这里怎么使得#在队列中下次打印【还不知道怎么输出#字符】
94 deq.push_back(*p.rchild);
95 deq.pop_front();
96 }
97 }
98
99 void foundLeafNode(BiTree T) // 打印所有的叶子节点
100 {
101 if(T != NULL )
102 {
103 if(T->lchild == NULL && T->rchild == NULL)
104 cout << T->data - '0' << ' ';
105 else
106 {
107 foundLeafNode(T->lchild);
108 foundLeafNode(T->rchild);
109 }
110 }
111 }
112
113 void printArray(int Path[],int pathLen) // print array
114 {
115 for(int i=0;i<pathLen;++i)
116 {
117 cout << Path[i] << ' ';
118 }
119 cout << endl;
120 }
121 void foundPath(BiTree T,int Path[],int pathLen) // 打印所有的路径
122 {
123 if(T == NULL) return;
124 Path[pathLen] = T->data - '0';
125 ++pathLen;
126
127 if(T->lchild == NULL && T->rchild == NULL)
128 printArray(Path,pathLen);
129 else
130 {
131 foundPath(T->lchild,Path,pathLen);
132 foundPath(T->rchild,Path,pathLen);
133 }
134 }
135
136 int a = 0,b = 0;
137 BiTNode *foundSameFatherNode(BiTree T,int p,int q) // found latest same father node
138 {
139 if(a == 0)
140 {
141 if(T == NULL) return NULL;
142 if(p == T->data - '0') return T;
143 if(q == T->data - '0') return T;
144
145 BiTNode *lch=NULL,*rch=NULL;
146 if(T!=NULL && T->lchild!=NULL)
147 lch = foundSameFatherNode(T->lchild,p,q);
148 if(T!=NULL && T->rchild!=NULL)
149 rch = foundSameFatherNode(T->rchild,p,q);
150
151 if(lch!=NULL && rch!=NULL)
152 {
153 if(a == 0)
154 {
155 a = 1; b = T->data - '0';
156 }
157 return T;
158 }
159 else
160 return NULL;
161 }
162 else
163 return NULL;
164 }
165
166 void changeMirror(BiTree &T) // change tree to mirror
167 {
168 if(T == NULL) return ;
169 BiTree p = T->lchild;
170 T->lchild = T->rchild;
171 T->rchild = p;
172 changeMirror(T->lchild);
173 changeMirror(T->rchild);
174 }
175
176 BiTree pre = new BiTNode;
177 void BiTreeToLinklist(BiTree &T) // change tree to linklist
178 {
179 /*if(T != NULL) // 线索化
180 {
181 changeBiTreeToLinklist(T->lchild);
182 if(T->lchild == NULL)
183 T->lchild = pre;
184 if(pre->rchild == NULL)
185 pre->rchild = T;
186 pre = T;
187 changeBiTreeToLinklist(T->rchild);
188 }*/
189 if(T != NULL) // 双向链表化
190 {
191 BiTree Current = T->rchild; // 这里需要保存当前节点的右子树指针,因为在pre->rchild = T;这步可能改变了当前节点的右子树指针指向,所以要提前保存
192 BiTreeToLinklist(T->lchild);
193 T->lchild = pre;
194 pre->rchild = T;
195 pre = T;
196 BiTreeToLinklist(Current);
197 }
198 }
199
200 void main()
201 {
202
203 pre->lchild = NULL;
204 pre->rchild = NULL;
205 BiTree p;
206 p = pre;
207
208 BiTree proot;
209 CreateBiTree(proot);
210
211 cout << "先序" << endl;
212 PreOrder(proot);
213 cout << endl;
214
215 cout << "中序"<< endl;
216 InOrder(proot);
217 cout << endl;
218
219 cout << "层次遍历,还找到怎么输出#字符"<< endl;
220 LevelOrder(proot);
221 cout << endl;
222
223 cout << "找到所有叶子节点"<< endl;
224 foundLeafNode(proot);
225 cout << endl;
226
227 int path[100];
228 memset(path,0,100);
229 cout << "所有的路径"<< endl;
230 foundPath(proot,path,0);
231 cout << endl;
232
233 cout << "寻找最近共同父节点"<< endl;
234 foundSameFatherNode(proot,1,4);
235 if( b != 0 )
236 cout << b <<endl;
237
238 /*cout << "二叉树的镜像" << endl;
239 changeMirror(proot);
240 PreOrder(proot);
241 cout << endl;*/
242
243 cout << "二叉树转化为双向链表" << endl;
244 BiTreeToLinklist(proot);
245 while(p->rchild != NULL)
246 {
247 cout << p->rchild->data - '0' << ' ';
248 p = p->rchild;
249 }
250 cout << endl;
251
252 }