先序递归遍历字符序列(用#字符表示NULL指针域)建立二叉链表存储结构,然后将其输出完全二叉树顺序存储结构(哑元素采用@字符表示)

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.}

如果有大佬还有更好的方法,求告知,我实在太蠢了,这个时间是真的要爆了,(试图拿非递归减少时间)

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值