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

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

          掌握图的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;
  }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值