数据结构的学习

  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+1286     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 }

 

posted @ 2013-12-16 01:01  yuanqi  阅读(399)  评论(0编辑  收藏  举报