数据结构之图的储存,搜索

来源:互联网 发布:java权限管理系统ssm 编辑:程序博客网 时间:2024/05/19 23:25

实验目的:掌握图的邻接矩阵和邻接表两个存储结构及表示。

          掌握图的DFS和BFS两种遍历算法。

          理解并掌握下述完整算法的基本思想以及算法实现方法:最小生成树算法、最短路径算法、拓扑排序算法及关键路径算法。

实验内容:1. 创建一个无向图,并分别对其进行DFS和BFS。

          2. 实现最短路径、最小生成树、拓扑排序三种算法。

#include<stdio.h>#include<string.h>#include<windows.h>#define MAX 100#include<malloc.h>int vis[MAX],map[MAX][MAX];int du[MAX];typedef struct {<span style="white-space:pre"></span>char vex[MAX];//顶点信息<span style="white-space:pre"></span>int edge[MAX][MAX];//邻接矩阵<span style="white-space:pre"></span>int n,e;//图中当前顶点数和边数 }graph;typedef char VertexType; //顶点类型 typedef struct node   //边表节点  {     int adjvex; //邻接点域    node* next; //链域 }EdgeNode;    typedef struct     //顶点表节点  {     VertexType vertex;  //顶点域    EdgeNode* firstedge; //边表头指针 }VertexNode;    typedef VertexNode AdjList[MAX];//AdjList是邻接表类型  typedef struct   {       AdjList adjlist;  //邻接表     int n,e;  //当前图中顶点数与边数 }ALGraph; typedef struct Lnode{  int data;<span style="white-space:pre"></span>//队列元素<span style="white-space:pre"></span>   struct Lnode *next;<span style="white-space:pre"></span> }Lnode, *QueuePtr;typedef struct{<span style="white-space:pre"></span>QueuePtr front;<span style="white-space:pre"></span>QueuePtr rear;}LinkQueue;void InitQueue(LinkQueue *q)//生成队列 {q->front=q->rear=(QueuePtr)malloc(sizeof(Lnode));q->front->next=NULL;}void EnQueue(LinkQueue *q, int e)//向队列中添加元素 {QueuePtr p;p=(QueuePtr)malloc(sizeof(Lnode));p->data=e;p->next=NULL;q->rear->next=p;q->rear=p;} int DeQueue(LinkQueue *q)//输出队列头元素 {return q->front->next->data;QueuePtr p;if(q->front==q->rear)   {   printf("\nqueue is empty\n");   return ERROR;  }  p=q->front->next;  q->front->next=p->next;  if(q->rear==p)   q->rear=q->front;  free(p);}int QueueEmpty(LinkQueue *q)//判断队列是否为空 {if(q->front==q->rear) return 1;else return 0;}void create(ALGraph *L) //建立邻接表  {      int i,j,k,w,v;      EdgeNode *s;      printf("读入顶点数和边数");      scanf("%d%d",&L->n,&L->e);      printf("建立顶点表");<span style="white-space:pre"></span> getchar();    for (i=0;i<L->n;i++)     {               scanf("%c",&L->adjlist[i].vertex);       L->adjlist[i].firstedge=NULL;     }     printf("建立边表\n");     for (k=0;k<L->e;k++)     {         printf("读入(vi-vj)的顶点对序号");         scanf("%d%d",&i,&j);         s=(EdgeNode*)malloc(sizeof(EdgeNode));         s->adjvex=j;         s->next=L->adjlist[i].firstedge;  //插入表头         L->adjlist[i].firstedge=s;         s=(EdgeNode*)malloc(sizeof(EdgeNode));         s->adjvex=i;         s->next=L->adjlist[j].firstedge;         L->adjlist[j].firstedge=s;       }    }  void shuchu(ALGraph *L)//输出邻接表 {<span style="white-space:pre"></span>int i;<span style="white-space:pre"></span>printf("%d ",L->n);for(i=0;i<L->n;i++)   {  printf("%d->",i);  while(L->adjlist[i].firstedge!=NULL)   {         printf("%d->",L->adjlist[i].firstedge->adjvex);      L->adjlist[i].firstedge=L->adjlist[i].firstedge->next;   }      printf("\n");                } } void creat1(graph *G)//构建邻接矩阵 {<span style="white-space:pre"></span>int i,j,k,w;<span style="white-space:pre"></span>char ch;<span style="white-space:pre"></span>printf("输入顶点数与边数\n");<span style="white-space:pre"></span>scanf("%d%d",&G->n,&G->e);<span style="white-space:pre"></span>printf("输入顶点信息\n");<span style="white-space:pre"></span>scanf("%s",G->vex);<span style="white-space:pre"></span>for(i=0;i<G->n;i++)<span style="white-space:pre"></span>for(j=0;j<G->n;j++)<span style="white-space:pre"></span>G->edge[i][j]=1000000;<span style="white-space:pre"></span>printf("输入边的信息\n"); <span style="white-space:pre"></span>for(k=0;k<G->e;k++)<span style="white-space:pre"></span>{<span style="white-space:pre"></span>scanf("%d%d%d",&i,&j,&w);<span style="white-space:pre"></span>G->edge[i][j]=w;<span style="white-space:pre"></span>G->edge[j][i]=w;<span style="white-space:pre"></span>}<span style="white-space:pre"></span>printf("构建成功!\n");}void DFS(graph *G,int i)//DFS深搜 {<span style="white-space:pre"></span>int j;<span style="white-space:pre"></span>printf("visit vertex:%c\n",G->vex[i]);<span style="white-space:pre"></span>vis[i]=1;<span style="white-space:pre"></span>for(j=0;j<G->n;j++)<span style="white-space:pre"></span>if(G->edge[i][j]!=0&&!vis[j])<span style="white-space:pre"></span>DFS(G,j);<span style="white-space:pre"></span>}void BFS(graph *G,int k)//BFS广搜 {<span style="white-space:pre"></span>int i,j;<span style="white-space:pre"></span>LinkQueue q;<span style="white-space:pre"></span>InitQueue(&q);<span style="white-space:pre"></span>printf("visit vertex:%c\n",G->vex[k]);<span style="white-space:pre"></span>vis[k]=1;<span style="white-space:pre"></span>EnQueue(&q,k);<span style="white-space:pre"></span>while(!QueueEmpty(&q))<span style="white-space:pre"></span>{<span style="white-space:pre"></span>i=DeQueue(&q);<span style="white-space:pre"></span>for(j=0;j<G->n;j++)<span style="white-space:pre"></span>if(G->edge[i][j]!=0&&!vis[j])<span style="white-space:pre"></span>BFS(G,j);<span style="white-space:pre"></span>}}void prim(graph *G,int u)//prim最小生成数 {<span style="white-space:pre"></span>int i,j,pos,min,result=0; <span style="white-space:pre"></span>int low[MAX];   for(i=0;i<=G->n;i++)      vis[i]=0;//从某点开始,分别标记和记录该点    vis[u]=1;    pos=u;   low[u]=0;//第一次给low数组赋值for(i=0;i<G->n;i++)  if(i!=pos) low[i]=G->edge[pos][i];//再运行n-1次for(i=1;i<G->n;i++){//找出最小权值并记录位置min=100000;for(j=0;j<G->n;j++)if(vis[j]==0&&min>low[j]){min=low[j];pos=j;}//最小权值累加result+=min;//标记该点vis[pos]=1;//更新权值for(j=0;j<G->n;j++)if(vis[j]==0&&low[j]>G->edge[pos][j])low[j]=G->edge[pos][j];} printf("以%d开始的最小生成树长度为:%d\n ",u,result);}void floyd(graph *G)//最短路径 {<span style="white-space:pre"></span>int i,j,k;<span style="white-space:pre"></span>for(i =0;i<G->n;i++)<span style="white-space:pre"></span>for(j=0;j<G->n;j++)<span style="white-space:pre"></span>map[i][j]=G->edge[i][j];<span style="white-space:pre"></span>for(k=0;k<G->n;k++)<span style="white-space:pre"></span>for(i=0;i<G->n;i++)<span style="white-space:pre"></span>for(j=0;j<G->n;j++)<span style="white-space:pre"></span>if(map[i][j]>map[i][k]+map[k][j])<span style="white-space:pre"></span>map[j][i]=map[i][j]=map[i][k]+map[k][j];<span style="white-space:pre"></span>int n,m;<span style="white-space:pre"></span>char a,b;<span style="white-space:pre"></span>getchar();<span style="white-space:pre"></span>printf("请输入要查询两点距离:");<span style="white-space:pre"></span>scanf("%c %c",&a,&b);<span style="white-space:pre"></span>for(i=0;i<G->n;i++)<span style="white-space:pre"></span>{<span style="white-space:pre"></span>if(G->vex[i]==a)<span style="white-space:pre"></span>n=i;<span style="white-space:pre"></span>if(G->vex[i]=b)<span style="white-space:pre"></span>m=i;<span style="white-space:pre"></span>}<span style="white-space:pre"></span>if(map[m][n]>=100000)<span style="white-space:pre"></span>printf("两点之间无最短距离\n");<span style="white-space:pre"></span>else<span style="white-space:pre"></span>printf("两点间最短距离为%d\n",map[n][m]);<span style="white-space:pre"></span> }void jiemian1(){<span style="white-space:pre"></span>printf("\t\t\t目录\n");    printf("\t\t1、邻接矩阵\n");<span style="white-space:pre"></span>printf("\t\t2、邻接表\n");<span style="white-space:pre"></span>printf("\t\t3、退出\n");<span style="white-space:pre"></span>printf("\t\t请输入操作选项: "); }void jiemian2(){   printf("\t\t\t目录\n");<span style="white-space:pre"></span>printf("\t\t1、创建无向图\n");<span style="white-space:pre"></span>printf("\t\t2、DFS搜索\n");<span style="white-space:pre"></span>printf("\t\t3、BFS搜索\n");<span style="white-space:pre"></span>printf("\t\t4、最短路径\n");<span style="white-space:pre"></span>printf("\t\t5、最小生成树\n");<span style="white-space:pre"></span>printf("\t\t6、拓扑排序\n");<span style="white-space:pre"></span>printf("\t\t7、退出\n"); <span style="white-space:pre"></span> }void init(graph *G){ int i;<span style="white-space:pre"></span>for(i=0;i<G->n;i++)<span style="white-space:pre"></span>vis[i]=0;}void topu(graph *G){     printf("构成一个有向图\n");   int i,j,k;<span style="white-space:pre"></span>char ch;<span style="white-space:pre"></span>printf("输入顶点数与边数\n");<span style="white-space:pre"></span>scanf("%d%d",&G->n,&G->e);<span style="white-space:pre"></span><span style="white-space:pre"></span>printf("输入顶点信息\n");    <span style="white-space:pre"></span>getchar();    for(i=0;i<G->n;i++)<span style="white-space:pre"></span>scanf("%c",&G->vex[i]);<span style="white-space:pre"></span>for(i=0;i<=G->n;i++)<span style="white-space:pre"></span>du[i]=0;<span style="white-space:pre"></span>for(i=0;i<=G->n;i++)<span style="white-space:pre"></span>for(j=0;j<=G->n;j++)<span style="white-space:pre"></span>{<span style="white-space:pre"></span>G->edge[i][j]=0;<span style="white-space:pre"></span>}<span style="white-space:pre"></span>printf("输入边的信息\n"); <span style="white-space:pre"></span>for(k=0;k<G->e;k++)<span style="white-space:pre"></span>{<span style="white-space:pre"></span>scanf("%d%d",&i,&j);<span style="white-space:pre"></span>G->edge[i][j]=G->edge[j][i]=1;<span style="white-space:pre"></span>du[j]++;<span style="white-space:pre"></span><span style="white-space:pre"></span>}<span style="white-space:pre"></span>printf("构建成功!\n");printf("拓扑排序结果如下:\n");for(j=0;j<G->n;j++){for(i=0;i<G->n;i++){<span style="white-space:pre"></span>if(du[i]==0)<span style="white-space:pre"></span>{<span style="white-space:pre"></span>du[i]=-1;<span style="white-space:pre"></span>k=i;<span style="white-space:pre"></span>printf("%c ",G->vex[i]);<span style="white-space:pre"></span>break;<span style="white-space:pre"></span><span style="white-space:pre"></span>}}for(i=0;i<=G->n;i++){<span style="white-space:pre"></span>if(G->edge[k][i]==1)<span style="white-space:pre"></span>du[i]--;}<span style="white-space:pre"></span>}}int main(){ALGraph *L;graph *G;  while(1)  {  <span style="white-space:pre"></span>int n;  <span style="white-space:pre"></span>jiemian1();  <span style="white-space:pre"></span>scanf("%d",&n);  <span style="white-space:pre"></span>if(n==1)  <span style="white-space:pre"></span>{<span style="white-space:pre"></span>  system("cls");<span style="white-space:pre"></span>  G=(graph*)malloc(sizeof(graph));   <span style="white-space:pre"></span>int m;  <span style="white-space:pre"></span>jiemian2();  <span style="white-space:pre"></span>while(1)  <span style="white-space:pre"></span>{  <span style="white-space:pre"></span>printf("\t\t请输入操作选项;");<span style="white-space:pre"></span>    scanf("%d",&m);<span style="white-space:pre"></span>    switch(m)<span style="white-space:pre"></span>    {<span style="white-space:pre"></span>    <span style="white-space:pre"></span>case 1:creat1(G);break;<span style="white-space:pre"></span>    <span style="white-space:pre"></span>case 2:init(G),DFS(G,0);break;<span style="white-space:pre"></span>    <span style="white-space:pre"></span>case 3:init(G),BFS(G,0);break;<span style="white-space:pre"></span>    <span style="white-space:pre"></span>case 4:init(G),prim(G,0);break;<span style="white-space:pre"></span>    <span style="white-space:pre"></span>case 5:init(G),floyd(G);break;<span style="white-space:pre"></span>    <span style="white-space:pre"></span>case 6:topu(G);break;<span style="white-space:pre"></span>    <span style="white-space:pre"></span>case 7:return 0;<span style="white-space:pre"></span>    }<span style="white-space:pre"></span><span style="white-space:pre"></span> <span style="white-space:pre"></span>  }<span style="white-space:pre"></span>  }<span style="white-space:pre"></span>  else if(n==2) <span style="white-space:pre"></span>  {<span style="white-space:pre"></span>  <span style="white-space:pre"></span>system("cls");<span style="white-space:pre"></span>  <span style="white-space:pre"></span>L= (ALGraph*)malloc(sizeof(ALGraph)); <span style="white-space:pre"></span>  <span style="white-space:pre"></span>printf("1、建立无向图\n");<span style="white-space:pre"></span>  <span style="white-space:pre"></span>printf("2、输出无向图\n");<span style="white-space:pre"></span>  <span style="white-space:pre"></span>printf("3、退出\n");<span style="white-space:pre"></span>  int m;<span style="white-space:pre"></span>  while(1)<span style="white-space:pre"></span>  {<span style="white-space:pre"></span>  <span style="white-space:pre"></span>printf("输入选择:");<span style="white-space:pre"></span>  <span style="white-space:pre"></span>scanf("%d",&m);<span style="white-space:pre"></span>  <span style="white-space:pre"></span>switch(m)<span style="white-space:pre"></span>  <span style="white-space:pre"></span>{<span style="white-space:pre"></span>  case 1:create(L);break;<span style="white-space:pre"></span>  case 2:shuchu(L);break;<span style="white-space:pre"></span>  case 3:return 0; <span style="white-space:pre"></span>     }<span style="white-space:pre"></span>     printf("%d ",L->n);          }       }    <span style="white-space:pre"></span>else  <span style="white-space:pre"></span>return 0;  }}
0 0