双亲与孩子链表

  1 #include"stdio.h"
  2 #include"stdlib.h"
  3 #include"malloc.h"
  4 
  5 
  6 const int maxlen=1000;//线性表的最大长度
  7 typedef char type;
  8 //------------线性表------------------
  9 struct List
 10 {
 11     type Data[maxlen];//存放数据
 12     int CurNum;//当前线性表
 13 };
 14 
 15 void Intialize( List &A)//线性表初始化
 16 {
 17     A.CurNum = 0;//线性表元素个数为0
 18 }
 19 
 20 int Length(List &A)//求表长度的实现
 21 {
 22     return A.CurNum;
 23 }
 24 
 25 void Insert(    List &A,const int i,const int x)//插入元素运算对应的函数
 26 {
 27     if(A.CurNum==maxlen)printf("溢出!\n");//溢出,不能插入
 28     if(i<1||i>Length(A)+1)printf("插入范围有错!\n");//插入范围有错
 29     else {
 30         for(int j=A.CurNum-1;j>=i-1;j--){
 31             A.Data[j+1]=A.Data[j];
 32         }
 33         A.Data[i-1]=x;
 34         A.CurNum++;
 35 
 36     }
 37 }
 38 void  Get_int(List &A,const int i,int &x)//按序号取元素运算
 39 {
 40     if(i<=0||i>A.CurNum)printf("序号错误!\n");
 41     else {
 42         x=A.Data[i-1];
 43     }
 44 }
 45 //------------线性表------------------
 46 
 47 
 48 //-------------链表------------------
 49 
 50 struct link_list
 51 {
 52     type data;
 53     link_list *next;
 54 };
 55 
 56 /*创建链表*/
 57 link_list *Create_list(link_list *head)
 58 {
 59     head = (link_list *)malloc(sizeof link_list);
 60     if(head==NULL)
 61     {
 62         printf("setup fail\n");
 63 
 64         exit(0);
 65     }
 66     head->data=NULL;
 67     head->next=NULL;
 68     return head;
 69 }
 70 
 71 /*向链表中插入一个元素*/
 72 void Insert_list(link_list *head,type data)
 73 {
 74     link_list *q=NULL;
 75     link_list *p=NULL;
 76     link_list *s=NULL;
 77     q=head;
 78     p=q->next;
 79     while(p!=NULL)
 80     {
 81         q=p;
 82         p=q->next;
 83     }
 84     s=(link_list *)malloc(sizeof link_list);
 85     s->data = data;
 86     q->next=s;
 87     s->next=p;
 88 }
 89 
 90 void browse(link_list *head)
 91 {
 92     link_list *q=NULL;
 93     q=head->next;
 94     while(q!=NULL)
 95     {
 96         printf("num:%c\n",q->data);
 97         q=q->next;
 98     }
 99 }
100 
101 
102 /*查找元素 并返回位置*/
103 link_list *find_list(link_list *head,int data)
104 {
105     link_list *q=NULL;
106     link_list *p=NULL;
107     q=head;
108     p=q->next;
109     while(p!=NULL&&p->data!=data)
110     {
111         q=p;
112         p=q->next;
113     }
114     printf("num :%c data : %c\n",p->data);
115     return p;
116 }
117 
118 struct BNode
119 {
120     type info;
121     link_list *child;
122 };
123 
124 char Allch[maxlen];
125 int numchar = 0;
126 
127 BNode Tree[maxlen];
128 int num_tree = 0;
129 List node;
130 void  Create_Tree()
131 {
132     int i,j,select;//选择
133     char A,B;//结点A,B
134     int flags;
135     //char 
136     A=' ';
137     B=' ';
138     select = 0;
139     Intialize(node);//初始化存放各个结点
140     printf("[--------树的建立---------]\n");
141     printf("输入几组数据:");
142     scanf("%d",&select);
143     char ch[maxlen];
144     printf("结点(node)\t父节点(parent)\n");
145     scanf("%s",&ch);
146     for(i=0;i<2*select;i++)
147     {
148         flags =1;
149         for(j=0;j<numchar;j++)
150         {
151             if(ch[i]==Allch[j])//该字符已经存在
152             {
153                 flags =0;
154                 break;
155             }
156         }
157         if(flags==1)//该字符不存在
158         {
159             Allch[numchar++]=ch[i];
160         }
161     }
162     
163     for(i=1;i<2*select;i=i+2)
164     {
165         flags = 1;
166         for(j=0;j<=node.CurNum;j++)
167         {
168             if(node.Data[j]==ch[i])///结点原先存在
169             {
170                 flags = 0;
171                 break;
172             }
173         }
174         //printf("%d %c\n",flags,ch[i]);
175         if(flags==1)//结点不存在,添加
176         {
177             Insert(node,node.CurNum+1,ch[i]);
178         }
179         
180         int pa = 0;//标识父节点是否存在
181         for(j=0;j<num_tree;j++)
182         {
183             if(Tree[j].info==ch[i])//父节点已经存在
184             {
185                 Insert_list(Tree[j].child,ch[i-1]);
186                 pa =1;
187                 break;
188             }
189         }
190         if(pa==0)//父节点尚未不存在
191         {
192             Tree[num_tree].info = ch[i];
193             Tree[num_tree].child = NULL;
194             Tree[num_tree].child=Create_list(Tree[num_tree].child);
195             Insert_list(Tree[num_tree].child,ch[i-1]);
196             num_tree++;
197         }
198     }
199 
200     /*
201     
202     for(i=0;i<=node.CurNum;i++)printf(" %c",node.Data[i]);
203     printf("\n");
204     
205     for(i=0;i<num_tree;i++)
206     {
207         printf("  %c",Tree[i].info);
208         printf("孩子链表:");
209         browse(Tree[i].child);
210         printf("孩子链表:");
211     }
212     */
213 }
214 
215 void Print_Tree()
216 {
217     int i,j,select;//选择
218     printf("      ------------------------------------\n");
219     printf("     |--------1:双亲表示法----------------|\n");
220     printf("     |--------0:复合链表法----------------|\n");
221     printf("      ------------------------------------\n");
222     printf("您的选择是:");
223     scanf("%d",&select);
224     while(select!=0&&select!=1)
225     {
226         printf("您输入有误,请重新输入:");
227         scanf("%d",&select);
228     }
229     if(select==1)
230     {
231         printf("---------双亲表示法----------\n");
232         printf("结点(node)\t父节点(parent)\n");
233         for(i=0;i<num_tree;i++)
234         {
235             link_list *q=NULL;
236             q=Tree[i].child->next;
237             while(q!=NULL)
238             {
239                 printf("%c\t%c\n",q->data,Tree[i].info);
240                 q=q->next;
241             }
242         }
243         printf("-------以上是双亲表示法--------\n");
244     }else{
245         printf("---------复合链表法------------\n");
246         printf("结点(node)\t父节点(parent)\n");
247         //printf("num%d]\n",numchar);
248         for(i=0;i<numchar;i++)
249         {
250             //printf("父:%c\n",node.Data[i]);
251             int flags = 1;
252             for(j=0;j<num_tree;j++)
253             {
254                 if(Tree[j].info==Allch[i])
255                 {
256                     flags = 0;
257                     printf("父节点:%c\t",Tree[j].info);
258                     printf("孩子节点:\t");
259                     link_list *q=NULL;
260                     q=Tree[j].child->next;
261                     while(q!=NULL)
262                     {
263                         printf("%c\t",q->data);
264                         q=q->next;
265                     }
266                     printf("\n");
267                     break;
268                 }
269             }
270             if(flags==1){//不存在子节点
271                 printf("父节点:%c\t",Allch[i]);
272                 printf("不存在孩子节点\n");
273             }
274         }
275         printf("-------以上是复合链表法----------\n");
276     }
277 }
278 
279 char  boot()//找根节点(~)
280 {
281     int i;
282     char ch;
283     for(i=0;i<num_tree;i++)
284     {
285         if(Tree[i].info=='~')//找根节点
286         {
287             link_list *q=NULL;
288             q=Tree[i].child->next;
289             if(q!=NULL)
290             {
291                 ch = q->data;
292             }
293             break;
294         }
295     }
296     return ch;
297 }
298 void preorder(char ch)//先序输出
299 {
300     printf("%c ",ch);
301     int i;
302     for(i=0;i<num_tree;i++)
303     {
304         if(Tree[i].info ==ch)
305         {
306             
307             link_list *q=NULL;
308             q=Tree[i].child->next;
309             while(q!=NULL)
310             {
311                 preorder(q->data);
312                 q=q->next;
313             }
314             break;
315         }
316     }
317 }
318 
319 void postorder(char ch)//后序输出
320 {
321     int i;
322     for(i=0;i<num_tree;i++)
323     {
324         if(Tree[i].info ==ch)
325         {
326             link_list *q=NULL;
327             q=Tree[i].child->next;
328             while(q!=NULL)
329             {
330                 postorder(q->data);
331                 q=q->next;
332             }
333             break;
334         }
335     }
336     printf("%c ",ch);
337 }
338 
339 void layer(char ch)//后序输出
340 {
341     int i;
342     for(i=0;i<num_tree;i++)
343     {
344         if(Tree[i].info ==ch)
345         {
346             link_list *q=NULL;
347             link_list *s=NULL;
348             q=Tree[i].child->next;
349             s=Tree[i].child->next;
350             while(q!=NULL)
351             {   printf("%c ",q->data);
352                 q=q->next;
353             }
354             while(s!=NULL)
355             {
356                 layer(s->data);
357                 s=s->next;
358             }
359             break;
360         }
361     }
362     //printf("%c ",ch);
363 }
364 
365 int Degree(char ch)//求一个字符的度数(入度+出度)
366 {
367     int i,count =0;
368     for(i=0;i<num_tree;i++)
369     {
370         if(Tree[i].info ==ch)
371         {
372             if(ch=='~')count--;
373             link_list *q=NULL;
374             q=Tree[i].child->next;
375             while(q!=NULL)
376             {   count++;
377                 q=q->next;
378             }
379             break;
380         }
381     }
382     //if(ch!='~')count++;//根节点 的父节点不算
383     //count++;
384     return count;
385 }
386 
387 void All_degree()//求所有结点的度以及度出现的而次数(去除根节点)
388 {
389     int i,j,max;
390     int a[maxlen];//存放所有结点的度
391     int b[maxlen][2];//存放结点度1,2,3...的个数
392     max = 0;
393     for(i=0;i<numchar;i++)//根节点的出度为1也算入(最终去除)
394     {
395         a[i] = Degree(Allch[i]);
396         if(max<a[i]) max=a[i];
397         //printf("%d ",a[i]);
398     }
399     for(i=0;i<=max;i++)
400     {
401         b[i][0] = i;
402         b[i][1] = 0;
403     }
404     for(i=0;i<numchar;i++)
405     {
406         for(j=0;j<=max;j++)
407         {
408             if(a[i]==b[j][0])b[j][1]++;
409         }
410     }
411     b[0][1]--;//去掉根节点的数目
412     printf("树中结点度的统计:\n");
413     for(i=0;i<=max;i++)
414     {
415         printf("度为%d的结点数目为:%d\n",b[i][0],b[i][1]);
416     }
417     printf("\n树中结点度的统计完成\n");
418 }
419 int  main()
420 {
421 
422     int select,i=0;
423     Create_Tree();
424     char ch = boot();
425     do{
426         printf("      ------------------------------------\n");
427         printf("     |--------1:树的输出------------------|\n");
428         printf("     |--------2:树的先序遍历--------------|\n");
429         printf("     |--------3:树的后序遍历--------------|\n");
430         printf("     |--------4:树的层次输出--------------|\n");
431         printf("     |--------5:树中结点度统计------------|\n");
432         printf("      ------------------------------------\n");
433         printf("您的选择是:");
434         scanf("%d",&select);
435         while(select!=1&&select!=2&&select!=3&&select!=4&&select!=5)
436         {
437             printf("您输入有误,请重新输入:");
438             scanf("%d",&select);
439         }
440         switch(select)
441         {
442         case 0:
443             
444         case 1:
445             Print_Tree();
446             break;
447         case 2:
448             printf("先序输出结果为:");
449             preorder(ch);
450             printf("\t先序输出完毕!\n\n");
451             break;
452         case 3:
453             printf("后序输出结果为:");
454             postorder( ch);
455             printf("\t后序输出完毕!\n\n");
456             break;
457         case 4:
458             printf("按层次输出结果为:");
459             printf("%c ",ch);
460             layer(ch);
461             printf("\t按层次输出完毕!\n\n");
462             break;
463         default:
464             All_degree();
465             break;
466         }
467         printf("\n");
468         printf("      ------------------------------------\n");
469         printf("     |--------1:继续操作------------------|\n");
470         printf("     |--------0:退出----------------------|\n");
471         printf("      ------------------------------------\n");
472         printf("您的选择是:");
473         scanf("%d",&select);
474     }while(select==1);
475     return 0;
476 }

 

转载于:https://www.cnblogs.com/minmsy/p/5084544.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值