1 //邻接表存储结构定义
2 #define MAXVEX 100
3 struct ArcNode
4 {
5 int adjvex;
6 char info;
7 struct AecNode *nextarc;
8 };
9 struct vexnode
10 {
11 char data;
12 struct ArcNode*firstarc;
13 };
14 typedef struct vexnode AdjList[MAXVEX];
15 //通过用户交互产生一个有向图的邻接表
16 void createbgraph(AdjList*&g,int &n)
17 {
18 int e,i,s,d;
19 struct ArcNode*p;
20 printf("结点数(n)和边数(e):");
21 printf("%d%d",&n,&e);
22 for(i=0;i<n;i++)
23 {
24 printf("第%d个结点信息:",i);
25 scanf("%c",g[i]->data);
26 g[i]->firstarc=NULL;
27 }
28 for(i=0;i<e;i++)
29 {
30 printf("第%d条边 起点序号,终点序号:",i+1);
31 scanf("%d%d",&s,&d);
32 p=(struct ArcNode)malloc(sizeof(struct ArcNode));
33 p->adjvex=d;
34 p->info=g[d]->data;
35 p->nextarc=g[s]->firstarc;//*p插入到顶点s的邻接表中
36 g[s]->firstarc=p;
37 }
38 }
39
40 //输出有向图的邻接表
41 void dispbgraph(AdjList*g,int n)
42 {
43 int i;
44 struct ArcNode *p;
45 printf("图的邻接表表示如下:\n");
46 for(i=0;i<n;i++)
47 {
48 printf(" [%d,%d]",i,g[i]->data);
49 p=g[i]->firstarc;
50 while(p!=NULL)
51 {
52 printf("(%d,%c)->",p->dajvex,p->info);
53 p=p->nextarc;
54 }
55 printf("\n");
56 }
57 }
58
59 //深度优先搜索的递归函数
60 int visited[MAXVEX];
61 void dfs(AdjList*adj,int v0)
62 {
63 struct ArcNode*p;
64 visited[v1]=1;
65 prinf("%d",v0);
66 p=adj[v0]->firstarc;
67 while(p!=NULL)
68 {
69 if(visited[p->adjvex]==0)
70 dfs(adj,p->adjvex);
71 p=p->nextarc;
72 }
73 }
74 int visited[MAXVEX];
75 void bfs(AdjList *adj,int vi)//广度优先遍历
76 {
77 int front=0,rear=0,v;
78 struct ArcNode *p;
79 visited[vi]=1;//访问初始顶点vi
80 printf("%d",vi);
81 rear++;
82 queue[rear]=vi;
83 while(front!=rear)//队列不空时循环
84 {
85 front=(front+1)%MAXVEX;
86 v=queue[front];//按访问次序依次出队列
87 p=adj[v]->firstarc;//找v的下一个邻接点
88 while(p!=NULL)
89 {
90 if(visited[p->adjvex]==0)
91 {
92 visited[p->adjvex]=1;
93 printf("%d",p->adjvex);//访问该点并使之入队列
94 rear=(rear+1)%MAXVEX;
95 queue[rear]=p->adjvex;
96 }
97 p=p->nextarc;//找v的下一个邻接点
98 }
99 }
100 }
101
102 //将一个无向图的邻接矩阵转换成邻接表
103 void mattolist(AdjMatrix a,AdjList *&g)
104 {
105 int i,j,n;
106 n=a.n;
107 ArcNode *p;
108 for(i=0;i<n;i++)
109 g[i].firstarc=NULL;
110 for(i=0;i<N;i++)
111 for(j=n-1;j>=0;j++)
112 if(a.edges[i][j]!=0)
113 {
114 p=(ArcNode*)malloc(sizeof(ArcNode));
115 p->adjvex=j;
116 p->nextarc=g[i]->firstarc;//添加的是新分配的p节点
117 g[i]->firstarc=p;
118 }
119 }
120
121 //求无向图的G的连通分量个数
122 int getnum(AdjList*g)
123 {
124 int i,n=0,visited[MAXVEX];
125 for(i=0;i<MAXVEX;i++)
126 visited[i]=0;
127 dfs(g,0);
128 for(i=0;i<g->n;i++)
129 if(visited[i]==0)
130 {
131 n++;
132 dfs(g,i);
133 }
134 return n;
135 }
136 //判断vi到vj是否可达
137 int visited[MAXVEX];
138 void connected(AdjList adj,int i,int j,int &c)
139 {
140 int k;
141 if(i==j)
142 c=1;
143 else
144 {
145 k=0;
146 c=0;
147 while(k<adj.n&&c==0)
148 if(adj.edges[i][k]==1&&visited[k]==0)
149 {
150 visited[k]=1;
151 connected(adj,k,j,c);
152 }
153 else k++;
154 }
155 }
156
157 int visited[MAXVEX];//输出vi到vj的所有简单路径
158 int p[MAXVEX];
159 void path(AdjMatrix,int i,int j,int k)
160 {
161 int s;
162 if(p[k]==j)
163 {
164 for(s=0;s<=k;s++)
165 printf("%d",p[s]);
166 printf("\n");
167 }
168 else
169 {
170 s=0;
171 while(s<adj.n)
172 {
173 if(adj.edges[p[k]][s]==1&&visited[s]==0)
174 {
175 visited[s]=1;
176 p[k+1]=s;
177 path(adj,i,j,k+1);
178 visited[s]=0;
179 }
180 s++;
181 }
182 }
183 }
184 void disppath(AdjMatrix adj,int i,int j);
185 {
186 int k;
187 p[0]=i;
188 for(k=0;k<MAXVEX;k++)
189 visited[i]=0;
190 path(adj,i,j,0);
191 }
192 //二叉树前序遍历的非递归算法
193 void porder(BTree*b)
194 {
195 BTree*St[MaxSize],*p;
196 int top=-1;
197 if(b!=NULL)
198 {
199 top++;
200 St[top]=p;
201 while(top>-1)
202 {
203 p=St[top];
204 top--;
205 printf("%d",p->data);
206 if(p->rchild!=NULL)
207 {
208 top++;
209 St[top]=p->rchild;
210 }
211 if(lchild!=NULL)
212 {
213 top++;
214 St[top]=p->lchild;
215 }
216 }
217 }
218 }
219 //后序遍历二叉树的非递归算法
220 void psorder(BTree*t)
221 {
222 BTree *St[MaxSize];
223 BTree *p;
224 int flag,top=-1;//栈指针置初值
225 do
226 {
227 while(t)//将t的所有左结点入栈
228 {
229 top++;
230 St[top]=t;
231 t=t->lchild;
232 }
233 p=NULL;//p指向当前结点的前一个已访问的结点
234 flag=1;//设置t的访问标记为已访问过
235 while(top!=1&&flag)
236 {
237 t=St[top];//取出当前的栈顶元素
238 if(t->rchild==p)//右子树不存在或已被访问过,访问之
239 {
240 printf("%c",t->data);
241 top--;
242 p=t;
243 }
244 else{t=t->rchild;
245 flag=0;}
246 }
247 }while(top!=-1);
248 }
249
250 //求二叉树指定结点的层次
251 int level(b,x,h)
252 {
253 int h1;
254 if(b==NULL)
255 {
256 return 0;
257 }
258 else if(b->data==x)
259 {
260 return h;
261 }
262 else
263 {
264 h1=level(b->lchild,x,h+1);
265 if(h!=0)
266 return h1;
267 else
268 return level(b->rchild,x,h+1);
269 }
270 }
271
272 //按层次遍历二叉树
273 void translevel(BTree*b)
274 {
275 struct node
276 {
277 BTree*vec[MaxSize];
278 int f,r;//对头和对尾
279 }Qu;
280 Qu.f=0;//置队列尾空队列
281 Qu.r=0;
282 if(b!=NULL)
283 printf("%c ",b->data);
284 Qu.vec[Qu.r]=b;//结点指针进入队列
285 Qu.r=Qu.r+1;
286 while(Qu.f<Qu.r)
287 {
288 b=Qu.vec[Qu.f];
289 Qu.f=Qu.f+1;
290 if(b->lchild!=NULL)
291 {
292 printf("%c",b->lchild->data);
293 Qu.vec[Qu.r]=b->lchild;
294 Qu.r=Qu.r+1;
295 }
296 if(b->rchild!=NULL)
297 {
298 printf("%c ",b->rchild->data);
299 Qu.vec[Qu.r]=b->rchild;
300 Qu.r=Qu.r+1;
301 }
302 }
303 printf("\n");
304 }
305 //判断两棵二叉树是否相似
306 int like(BTree*b1,BTree *b2)
307 {
308 int like1,like2;
309 if(b1==NULL&&b2==NULL)
310 return 1;
311 else if(b1==NULL||b2)
312 return 0;
313 else
314 {
315 like1=like(b1->lchild,b2->lchild);
316 like2=like(b1->rchild,b2->rchild);
317 return (like1&&like2);
318 }
319 }
320
321 //释放二叉树所占用的全部存储空间
322 void release(BTree*b)
323 {
324 if(b!=NULL)
325 {
326 release(b->lchild);
327 release(b->rchild);
328 free(b);
329 }
330 }
331 //判断是否为完全二叉树
332 #define MAX 100
333 int fullbtree1(BTree*b)
334 {
335 BTree*Qu[Max],*p;//定义一个队列,用于分层判断
336 int first=0,rear=0,bj=1,cm=1;
337 if(b!=NULL)//cm表示表示整个二叉树是否为完全二叉树,bj表示到目前为止所有节点均有左右孩子
338 {
339 rear++;
340 Qu[rear]=b;
341 while(first!=rear)
342 {
343 first++;
344 p=Qu[first];
345 if(p->lchild==NULL)
346 {
347 bj=0;
348 if(p->rchild!=NULL)
349 cm=0;
350 }
351 else
352 {
353 cm=bj;
354 rear++;
355 Qu[rear]=p->lchild;
356 if(p->rchild==NULL)
357 bj=0;
358 else
359 {
360 rear++;
361 Qu[rear]=p->rchild;
362 }
363 }
364 }
365 return cm;
366 }
367 return 1;
368 }
369
370 //上述的算法2
371 #define MaxNum 100
372 typedef char Sbtree[MaxNum];
373 int fullbtree2(Sbtree A,int n)
374 {
375 int i;
376 for(i=1;i<=n;i++)
377 if(A[i]=' ')
378 return 0;
379 return 1;
380 }
381
382 //根据数组,建立与之对应的链式存储结构
383 void creab(char tree[],int n,int i,BTree &b)
384 {
385 if(i>n)
386 b=NULL;
387 else
388 {
389 b=(BTree*)malloc(sizeof(BTree));
390 b->data=tree[i];
391 creab(tree,n,2*i,b->lchild);
392 creab(tree,n,2*b+1,b->rchild);
393 }
394 }
395
396 //求根节点root到p所指节点之间的路径
397 void path(BTree*root,BTree*p)
398 {
399 BTree*St[MaxSize],*s;
400 int tag[MaxSize];
401 int top=-1,i;
402 s=root;
403 do
404 {
405 while(s!=NULL)//扫描左结点,入栈
406 {
407 top++;
408 St[top]=s;
409 tag[top]=0;
410 s=s->lchild;
411 }
412 if(top>-1)
413 {
414 if(tag[top]==1)//左右节点均已访问过,则要访问该结点
415 {
416 if(St[top]==p)//该结点就是要找的点
417 {
418 printf("路径:");//输出从栈底到栈顶元素的构成路径
419 for(i=1;i<=top;i++)
420 printf("%c ",St[i]->data);
421 printf("\n");
422 break;
423 }
424 top--;
425 }
426 else
427 {
428 s=St[top];
429 if(top>0)
430 {
431 s=s->rchild;//扫描右结点
432 tag[top]=1;//表示当前结点的右子树已访问过
433 }
434
435 }
436 }
437 }while(s!=NULL||top!=1)
438 }
439
440 //计算p和q两结点的共同最近的祖先
441 BTree *ancestor(BTree*root,BTree*p,BTree*q)
442 {
443 BTree*St[MaxSize],&anor[MaxSize],*b,*r;
444 int tag[MaxSize],find=0;
445 int top=-1;
446 b=root;
447 do
448 {
449 while(b!=NULL)//扫描左结点
450 {
451 top++;
452 St[top]=b;
453 tag[top]=0;
454 b=b->lchild;
455 }
456 if(top>-1)
457 {
458 if(tag[top]==1)
459 {
460 if(St[top]==p)//找到p所指结点,则将其祖先复制到anor中
461 for(i=1;i<=top;i++)
462 anor[i]=St[i];
463 if(St[top]==q)//找到q所指结点,则比较找出最近的共同祖先
464 {
465 j=top;
466 while(!find)
467 {
468 k=i-1;
469 while(k>0&&St[j]!=anor[k])
470 k--;
471 if(k>0)
472 {
473 find=1;
474 r=anor[k];
475 }
476 else
477 j--;
478 }
479 }
480 top--;
481 }
482 else
483 {
484 b=St[top];
485 if(top>0&&!find)
486 {
487 b=b->rchild;
488 tag[top]=1;
489 }
490 }
491 }
492 }while(!find&&(b!=NULL||top!=0));
493 return r;
494 }
495 //假设二叉树中之多有一个数据域值为x,如结点为x,则拆去以该节点为跟的二叉树
496 BTree *dislink(BTree*&t,elemtype x)
497 {
498 BTree *p,*find;
499 if(t!=NULL)//t为原二叉树,拆开后的第一课二叉树,分拆成功后返回第二颗二叉树
500 {
501 if(t->data==x)//根结点数据域为x
502 {
503 p=t;
504 t=NULL;
505 return p;
506 }
507 else
508 {
509 find=dislink(t->lchild,x);
510 if(!find)
511 find=dislink(t->rchild,x);
512 return (find);
513 }
514 }
515
516 else return (NULL);
517 }
518
519 //双序遍历二叉树
520 void dorder(BTree *b)
521 {
522 if(b!=NULL)
523 {
524 printf("%c ",b->data);
525 dorder(b->lchild);
526 printf("%c ",b->data);
527 dorder(b->rchild);
528 }
529 }
530
531 //计算一颗二叉树的所有节点数
532 int nodes(BTree *b)
533 {
534 int num1,num2;
535 if(b==NULL)
536 return(0);
537 else
538 {
539 num1=nodes(b->lchild);
540 bum2=nodes(b->rchild);
541 return(num1+num2+1);
542 }
543 }
544
545 //求一颗给定二叉树的单孩子的结点数
546 int onechild(BTree*b)
547 {
548 int num1,num2,n=0;
549 if(b==NULL)
550 return 0;
551 else if((b->lchild==NULL&&b->rchild!=NULL)||(b->lchild!=NULL&&b->rchild==NULL))
552 n=1;
553 num1=onechild(b->lchild);
554 num2=onechild(b->rchild);
555 return (num1+num2+n);
556 }
557 //表示父子,夫妻,兄弟关系的病=并且恩能够查找任一双亲结点的所有儿子的函数
558 void find(BTree*b,int p)
559 {
560 BTree *q;
561 q=findnode(b,p);
562 if(q!=NULL)
563 {
564 q=q->lchild;
565 q=q->rchild;
566 while(q!=NULL)
567 {
568 printf("%c",q->data);
569 q=q->rchild;
570 }
571 }
572
573 }
574 BTree*findnode(BTree*b,int p)
575 {
576 BTree*q;
577 if(b==NULL)
578 return NULL;
579 else if(b->data==p)
580 return b;
581 else
582 {
583 q=findnode(b->lchild,p);
584 if(q!=NULL)
585 return q;
586 else
587 return(findnode(b->rchild,p));
588 }
589 }
590 //由前序序列和中序序列构造该二叉树
591 BTree *restore(char *ppos,char *ipos,int n)
592 {
593 BTree*ptr;
594 char *rpos;
595 int k;
596 if(n<=0)
597 return NULL;
598 ptr=(BTree*)malloc(sizeof(BTree));
599 ptr->data=*ppos;
600 for(rpos=ipos;rpos<ipos+n;rpos++)
601 if(*rpos==*ppos)
602 break;
603 k=rpos-ipos;
604 ptr->lchild=restore(ppos+1,i,pos,k);//分别从左右进行遍历,构造二叉树
605 ptr->rchild=restore(ppos+1+k,rpos+1,n-1-k);
606 return ptr;
607 }
608
609 //已知中序序列和后序序列,建立起该二叉链结构的非递归算法
610 //in[1……n],post[1^n]是中序序列和后序序列的两数组
611 //二叉树的二叉链结点类型定义为:
612 typedef struct
613 {
614 int lchild,rchild;
615 int flag;
616 char data;
617 }
618
619 #include<iostream.h>
620 #include<iomanip.h>
621 #define MaxSize 100
622 BTree B[MaxSize];
623 int ctree(char in[],char post[])
624 {
625 int i=0,j,t,n,root,k;
626 while(in[i]!='\0')//把in[i]中元素赋完
627 {
628 B[i].data=in[i];
629 B[i].lchild=B[i].rchild=-1;
630 B[i].flag=i;
631 i++;
632 }
633 n=i;//n存放结点个数
634 k=0;
635 while(post[n-1]!=B[k].data)
636 k++;
637 root=k;
638 for(i=n-2;i>=0;i--)
639 {
640 t=k;
641 j=0;
642 while(post[i]!=B[j].data)
643 j++;
644 while(t!=-1)//将B[j]插入到以k为结点的二叉树中
645 if(B[j].flag<B[t].flag)
646 {
647 if(B[t].lchild==-1)
648 {
649 B[t].lchild=j;
650 t=-1;//
651 }
652 else t=B[t].lchild;
653 }
654 else if(B[j].flag>B[t].flag)
655 {
656 if(B[t].rchild==-1)
657 {
658 B[t].rchild=j;
659 t=-1;//插入成功后让t=-1
660 }
661 else t=B[t].rchild;
662 }
663 }
664 return root;//返回根节点下标
665 }
666 //二叉树从根节点到每个叶子结点的路径
667 typedef struct node
668 {
669 elemtype data;
670 struct node*lchild,*rchild;
671 struct node *parent;
672 }BTree;
673
674 #deine N 10//设二叉树中最长路径上结点个数不超过N
675 void disppath(BTree *p)//输出一条从当前叶子节点*p的一条路径
676 {
677 if(p->parent!=NULL)
678 {
679 disppath(p->parent);
680 printf("%c ",p->data);
681 }
682 else
683 printf("%c ",p->data);
684 }
685 void path(BTree*b)
686 {
687 BTree *St[N],*p;
688 int top=-1;
689 if(b!=NULL)
690 {
691 b->parent=NULL;//根节点的父节点指针置为空
692 top++;//根节点入栈
693 St[top]=b;
694 while(top>=0)//栈不空时循环
695 {
696 p=St[top];//退栈并访问该结点
697 top--;
698 if(p->lchild==NULL&&p->rchild==NULL)//为叶子节点时
699 {
700 disppath(p);
701 printf("\n");
702 }
703 if(p->rchild!=NULL)//右孩子入栈
704 {
705 p->rchild-->parent=p;
706 top++;
707 St[top]=p->rchild;
708 }
709 if(p->rchild!=NULL)//左孩子入栈
710 {
711 p->lchild->parent=p;
712 top++;
713 St[top]=p->lchild;
714 }
715 }
716 }
717 }
718
719 //终须线索二叉树求后续结点的算法
720 //并依此写出终须线索二叉树的非递归算法
721 //在终须线索二叉树中找一个结点后续的过程:若该结点有右线索,则右孩子为后续结点,否则,其右子树最左下的孙子便是后续结点,
722 TBTree*succ(TBTree*p)
723 {
724 TBTree*q;
725 if(p->rtag==1)
726 return p->rchild;
727 else
728 {
729 q=p->rchild;
730 while(q->ltag==0)
731 q=q->lchild;
732 return q;
733 }
734 }
735 //求一个结点前驱
736 TBTree *pre(TBTree*p)
737 {
738 TBTree*q;
739 if(p->ltag==1)
740 return p->lchild;
741 else
742 {
743 q=p->lchild;
744 while(q->rtag==0)
745 q=q->rchild;
746 return q;
747 }
748 }
749
750 void inorder(TBTree*root)//
751 {
752 TBTree*p,*head;
753 if(root!=NULL)
754 {
755 head=root;
756 p=root;
757 while(p!=NULL)//循环结束后,head指向中序遍历的头结点
758 {
759 head=p;
760 p=pre(p);
761 }
762 p=head;//从头结点开始中序遍历
763 do
764 {
765 printf("%c ",p->data);
766 p=succ(p);
767 }while(p!=NULL);
768 }
769 }