1.前言
emmmm,ssyh哈,博主实力有限,用来分享讨论的,因为想不到什么好的方法,其中的二叉树建立用的非递归的建立,如果有同学要cv的话,记得不要太明显了,这个非递归建立借鉴另一位博主的,太久远记不住了,本人直接拿过来用了(问就是太菜了qwq)
2.实现过程
先按照先序递归遍历字符序列那样建立一个二叉树,下面是其例子
A#BC#D###
图如下
按理说应该挺简单的一个遍历(bushi),但是因为要求输出要求如下:
输出的完全二叉树顺序结构为:A@B@@C@@@@@@D
emmm,就开始有趣起来了,所以我这边实现的方法是,先将其全部补为完全二叉树,然后再一个层序遍历,限制条件为最后一个字符即可。
3.代码
代码展示:
仔细说一下:怎么补完一个完全二叉树。
1.先找到其层数
2.然后按照层数进行限制,递归建立树那样建立树,但是到达最后一层时就必须得return,这样就有一棵完全二叉树,但因输出要求,所以需要在输出时在进行一下限制,不能让其将后面的完全二叉树输出出来。
2.#include<stdio.h>
3.#include<stdlib.h>
4.#include<math.h>
5.#include<string.h>
6.#define Max 100
7.//A#BC#D###
8.//ABDH#K###E##CFI###G#J##
9.struct Root{
10. char val;
11. struct Root * left;
12. struct Root * right;
13.};
14.struct stack{
15. struct Root* base[Max];
16. int tag[Max];//标记数组
17. int top;//标记数组的位置
18.};
19.struct Queue{
20. struct Root *base[Max];
21. int front;
22. int rear;
23.};
24.char A[Max];
25.struct Queue* create(struct Queue*queue){
26. queue = (struct Queue*)malloc(sizeof(struct Queue));
27.
28. queue->front =queue-> rear = 0;
29.}
30.void EnQueue(struct Queue*queue,struct Root*root){
31. if(queue->front == (queue->rear + 1) % Max ){
32. printf("队列满");
33. return ;
34. }
35. queue->base[queue->rear] = root;
36.
37. queue->rear = (queue->rear+1) % Max;
38.}
39.void DeQueue(struct Queue*queue){
40. if(queue->front == queue->rear){
41. printf("队列空");
42. }
43.
44. queue->front = (queue->front + 1) % Max;
45.
46.}
47.void push(struct stack*st,struct Root *root){
48. st->base[st->top] = root;
49. st->top++;
50.}
51.struct Root * pop(struct stack*st){
52. if(st->top != 0){
53. st->top--;
54. return st->base[st->top];
55. }
56. else{
57. return NULL;
58. }
59.}
60.struct Root* top(stack* st)//取栈顶元素,但不删除,返回指向栈顶元素的指针。
61.{
62. if (st->top != 0)
63. {
64. return st->base[st->top - 1];
65. }
66. else
67. {
68. return NULL;
69. }
70.}
71.struct Root *creat(){
72. int i = 0;
73. char ch[Max];
74. printf("输入二叉树的节点(以#作为哑节点):\n");
75. scanf("%s", ch, Max);
76.
77.
78. struct stack A;
79. struct stack * st;
80. st = &A;
81. st->top = 0;
82. struct Root* root; // 根节点
83. struct Root * p1,*p2;
84. while(ch[i] != '\0'){
85. if(i == 0){//建立根节点
86. root = (struct Root*)malloc(sizeof(struct Root));
87. root -> val = ch[i];
88. root->left = NULL;
89. root->right = NULL;
90. p1 = root;
91. //printf("?");
92. push(st,p1); // 将p1 代替root ,因为root 不能移动
93. st->tag[st->top - 1] = 0;
94.
95. }else{
96. if(ch[i] != '#' && st->tag[st->top - 1] == 0){//建立左节点
97.
98. p2 = (struct Root*)malloc(sizeof(struct Root));
99. p2->val = ch[i];
100. p2 -> left = NULL;
101. p2 -> right = NULL;
102. push(st,p2);
103. p1->left = p2;
104. p1 = p2;
105. st->tag[st->top - 1] = 0;
106.
107. }
108. else if(ch[i] == '#'&&st->tag[st->top - 1] == 0){//左子树建立完成
109. p1->left = NULL;
110. st->tag[st->top - 1] = 1;
111.
112. }
113. else if(ch[i] != '#'&&st->tag[st->top - 1] == 1){//建立右子树
114. p2 = (struct Root*)malloc(sizeof(struct Root));
115. p2->val = ch[i];
116. p2 -> left = NULL;
117. p2 -> right = NULL;
118. push(st, p2);
119. p1->right = p2;
120. p1 = p2;
121. st->tag[st->top - 1] = 0;
122. //printf("?");
123. }
124. else if(ch[i] == '#'&&st->tag[st->top - 1] == 1){//右子树建立完成.
125. p2->right = NULL;//保证了节点的初始化。
126. st->tag[st->top - 1] = 2;
127. }
128. while(st->tag[st->top - 1] == 2){
129. st->tag[st->top - 1] = 0;
130. p1 = pop(st);//出栈
131.
132. if(st->top != 0)
133. p1 = top(st);
134. else
135. break;
136. if(st->tag[st->top - 1] == 1){ //左子树存在,并且此节点从右节点处返回而来
137. st->tag[st->top - 1] = 2;
138. }
139. }
140. if(p1->left != NULL || st->tag[st->top - 1] == 1){ // 对返回上来的节点进行判断,有左子树则改变标记为1
141. st->tag[st->top - 1] = 1;
142. }
143. }
144. i++;
145. }
146. return root;
147.}
148.bool Empty(struct Queue* queue){
149. return (queue->front == queue->rear);
150.}
151.
152.int height(struct Root*root){
153. if(!root) return 0;
154. int hl,hr;
155. hl = height(root->left);
156. hr = height(root->right);
157. return fmax(hl,hr) + 1;
158.}
159.struct Root* createallleft(struct Root*root,int n,int m){ //m用来计数
160. if(root == NULL){
161. root = (struct Root*)malloc(sizeof(struct Root));
162. root->left = NULL;
163. root->right = NULL;
164. root->val = '@';
165. }
166. if(m == n){
167. return root;
168. }
169. //printf("%c",root->val);
170. root->left = createallleft(root->left,n+1,m);
171. root->right = createallleft(root->right,n+1,m);
172.}
173.
174.void cengxu(struct Root*root){
175. struct Root*p1 = root;
176. int i = 0;
177. struct Queue * queue;
178. queue = create(queue);
179. EnQueue(queue,root);
180.
181. while(!Empty(queue)){
182. DeQueue(queue);
183. printf("%c ",root->val);
184. if(root->left != NULL)
185. EnQueue(queue,root->left);
186. if(root->right != NULL)
187. EnQueue(queue,root->right);
188. root = queue->base[queue->front];
189. }
190.
191.}
192.void cengxu1(struct Root*root){
193. struct Root*p1 = root;
194. int i = 0;
195. struct Queue * queue;
196. queue = create(queue);
197. EnQueue(queue,root);
198.
199. while(!Empty(queue)){
200. DeQueue(queue);
201. printf("%c ",root->val);
202. if(root->val == A[strlen(A)-1]){
203. exit(0);
204. }
205. if(root->left != NULL)
206. EnQueue(queue,root->left);
207. if(root->right != NULL)
208. EnQueue(queue,root->right);
209. root = queue->base[queue->front];
210. }
211.
212.}
213.void pre(struct Root*root,int i){//递归前序查看树
214. //printf("?");
215. if(root != NULL){
216. printf("%c ",root->val);
217. A[i] = root->val;
218. i++;
219. }
220. else{
221. return;
222. }
223.
224. pre(root->left,i);
225. pre(root->right,i);
226.
227.}
228.
229.void mid(struct Root*root){//递归中序查看树
230. //printf("?");
231. if(root == NULL){
232.
233. return;
234. }
235. mid(root->left);
236. if(root != NULL){
237. printf("%c ",root->val);
238. }
239. mid(root->right);
240.
241.}
242.void after(struct Root*root){//递归后序查看树
243. //printf("?");
244. if(root == NULL){
245. return;
246. }
247. after(root->left);
248. after(root->right);
249. if(root != NULL){
250. printf("%c ",root->val);
251. }
252.
253.}
254.bool empty(struct stack *s){
255. if(s->top == 0){
256. return 0;
257. }else{
258. return 1;
259. }
260.
261.}
262.
263.int main(){
264. struct Root* root;
265. struct Root* root1;
266.
267. int i;
268. root = creat();
269. root1 = root;
270. i = height(root);
271. printf("前序遍历:\n");
272. pre(root,0);
273. printf("\n");
274. printf("中序遍历:\n");
275. mid(root);
276. printf("\n");
277. printf("后序遍历:\n");
278. after(root);
279. printf("\n");
280. printf("层序遍历:\n");
281. cengxu(root);
282. printf("\n");
283. printf("完全二叉树的顺序结构为:\n");
284. root = createallleft(root,0,i);
285.
286. cengxu1(root);
287.}
如果有大佬还有更好的方法,求告知,我实在太蠢了,这个时间是真的要爆了,(试图拿非递归减少时间)