數據結構之圖的儲存,搜索

實驗目的:掌握圖的鄰接矩陣和鄰接表兩個存儲結構及表示。

          掌握圖的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;
  }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章