數據結構實驗報告-實驗四 圖的構造與遍歷


實驗四   圖的構造與遍歷

 

實驗目的

1、圖的的定義和遍歷

(1)掌握圖的鄰接矩陣、鄰接表的表示方法。

(2)掌握建立圖的鄰接矩陣的算法。

(3)掌握建立圖的鄰接表的算法。

(4)加深對圖的理解,逐步培養解決實際問題的能力。

實驗內容

1、圖的定義和遍歷

(一)基礎題

1、編寫圖基本操作函數:

(1)CreateALGraph(ALGraph &G) 建立無向圖的鄰接表表示;

(2)LocateVex(ALGraph &G,char v)圖查找信息;

(3)DFSTraverse(ALGraph &G)圖的深度遍歷操作

(4)BFSTraverse(ALGraph &G)圖的廣度優先遍歷

(5)Create(MGraph &G)鄰接矩陣的創建

2、調用上述函數實現下列操作:

(1)建立一個圖的鄰接矩陣和圖的鄰接表;

(2)采用遞歸深度優先遍歷輸出圖的鄰接矩陣;

(3)采用遞歸深度優先輸出圖的鄰接表;

(4)采用圖的廣度優先遍歷輸出圖的鄰接表;

(5)采用圖的廣度優先遍歷輸出圖的鄰接表。

(二)提高題-

【問題描述】設某城市有n個車站,並有m條公交線路連接這些車站。假設這些公交車站都是單向的,這n個車站被順序編號為0~n-1。在本程序中輸入該城市的公交線路數,車站個數以及各公交線路上各站的編號。

【實現要求】求得從站0出發乘公交車至站n-1的最少換車次數。

 

實驗結果

1、圖的定義和遍歷

(一)基礎題

(1)畫出數據結構基本運算的流程圖

 
   

 

 

 

 

 

 

 

 

 

(2)程序運行主要結果截圖

 

(3)程序源代碼

#include<stdio.h>

#include<stdlib.h>

typedef struct ArcNode

{

    int adjvex;  //鄰接點域

    struct ArcNode *nextarc; //指向下一個鄰接點的指針域

    int weight;

}ArcNode;//邊結點

typedef struct VNode

{

    char vertex;   //頂點域

    ArcNode *firstarc;//第一條邊的指針

}VNode,AdjList[10];//頂點結點向量

typedef struct

{

    AdjList adjlist;

    int vexnum,arcnum;

}ALGraph;

//圖的鄰接矩陣

typedef struct

{

    int adj;

}AdjMatrix[10][10];

typedef struct

{

    int vexs[10];

    AdjMatrix arcs;

    int vexnum,arcnum;

}MGraph;

int LocateVex(ALGraph &G,char v)//查找頂點信息

{

    int k,j=0;

    for(k=0;k<G.vexnum;k++)

      if(G.adjlist[k].vertex==v)

      {

          j=k;

          break;

      }

      return j;

}

void CreateALGraph(ALGraph &G)

{//建立無向圖的鄰接表表示

    int i,j,k,w;

    char v1,v2;

    ArcNode *s;

    printf("請輸入頂點數和邊數(vexnum,arcnum):");

    scanf("%d,%d",&G.vexnum,&G.arcnum);

    for(i=0;i<G.vexnum;i++)

    {//建立頂點表

        getchar();

        printf("請輸入第%d頂點信息:",i+1);

        scanf("%c",&G.adjlist[i].vertex);//讀入頂點信息

        G.adjlist[i].firstarc=NULL;//邊表置為空表

    }

    for(k=0;k<G.arcnum;k++)

    {//建立邊表

        getchar();

        printf("請輸入第%d邊的頂點對序號和邊的權值(v1,v2,w):",k+1);

        scanf("%c,%c,%d",&v1,&v2,&w);

        j=LocateVex(G,v2);

        i=LocateVex(G,v1);

        s=(ArcNode*)malloc(sizeof(ArcNode)); //生成邊表結點

        s->adjvex=j;//鄰接點序號為j

        s->weight=w;//權值

        s->nextarc=G.adjlist[i].firstarc;

        G.adjlist[i].firstarc=s; //將新結點*s插入頂點vi的邊表頭部

        //若圖為無向圖則加上下面的四句代碼,若圖為有向圖則注釋下面的四句代碼

        s=(ArcNode*)malloc(sizeof(ArcNode));

        s->adjvex=i;

        s->weight=w;

        s->nextarc=G.adjlist[j].firstarc;

        G.adjlist[j].firstarc=s;

    }

}

bool visited[20];

int v;

void DFS(ALGraph &G,int v)//深度遍歷輸出

{

    visited[v]=true;

    printf("%c ",G.adjlist[v].vertex);

    ArcNode *w;

    for(w=G.adjlist[v].firstarc;w!=NULL;w=w->nextarc)

        if(!visited[w->adjvex])

        DFS(G,w->adjvex);

}

void DFSTraverse(ALGraph &G)//圖的深度遍歷操作

{

    for(v=0;v<G.vexnum;v++)

        visited[v]=false;

    for(v=0;v<G.vexnum;v++)

        if(!visited[v])

        DFS(G,v);

}

//隊列

typedef struct QNode

{

    int data;

    struct QNode *next;

}QNode,*QueuePtr;

typedef struct

{

    QueuePtr front;

    QueuePtr rear;

}LinkQueue;

void InitQueue(LinkQueue &Q)//構造一個空隊列 Q 

{

    Q.rear=Q.front=(QueuePtr)malloc(sizeof(QNode));

    Q.front->next=NULL;

}

void EnQueue(LinkQueue &Q,int e)//入隊

{

    QNode *p;

    p=(QueuePtr)malloc(sizeof(QNode));

    p->data=e;

    p->next=NULL;

    Q.rear->next=p;

    Q.rear=p;

}

void DeQueue(LinkQueue &Q,int &e2)

{//出隊

    QNode *p;

    p=Q.front->next;

    e2=p->data;

    Q.front->next=p->next;

    if(Q.rear==p)

        Q.rear=Q.front;

    free(p);

}

bool visited1[20];

 

void BFSTraverse(ALGraph &G)//圖的廣度優先遍歷

{

 

    for(v=0;v<G.vexnum;v++)

        visited1[v]=false;

    LinkQueue Q;

    InitQueue(Q);

    for(v=0;v<G.vexnum;v++)

        if(!visited1[v])

    {

        visited1[v]=true;

        printf("%c ",G.adjlist[v].vertex);

        EnQueue(Q,v);

        int u;

        ArcNode *w;

        while(Q.front!=Q.rear)

        {

            DeQueue(Q,u);

            for(w=G.adjlist[u].firstarc;w!=NULL;w=w->nextarc)

                if(!visited1[w->adjvex])

            {

                visited1[w->adjvex]=true;

                printf("%c ",G.adjlist[w->adjvex].vertex);

                EnQueue(Q,w->adjvex);

            }

        }

    }

}

void display(ALGraph &G)//輸出圖的頂點信息

{

    printf("建立的鄰接表位:\n");

    int i;

    for(i=0;i<G.vexnum;i++)

    {

        if(G.adjlist[i].firstarc!=NULL)

        {

            printf("%c->",G.adjlist[i].vertex);

            ArcNode *p;

            p=G.adjlist[i].firstarc;

            while(p!=NULL)

            {

                printf("%d->",p->adjvex);

                p=p->nextarc;

            }

            printf("NULL\n");

        }

        else

        {

            printf("%c->NULL\n",G.adjlist[i].vertex);

        }

    }

}

 

int LocateVex(MGraph &G,int v)

{

    int k,j=0;

    for(k=0;k<G.vexnum;k++)

        if(G.vexs[k]==v)

    {

        j=k;

        break;

    }

    return j;

}

void Create(MGraph &G)

{

    int i,j,k;

    int v1=0,v2=0,w=0;

    printf("請輸入圖的頂點數:");

    scanf("%d",&G.vexnum);

    printf("請輸入圖的邊數:");

    scanf("%d",&G.arcnum);

    for(i=0;i<G.vexnum;i++)

        G.vexs[i]=i+1;

    for(i=0;i<G.vexnum;i++)

        for(j=0;j<G.vexnum;j++)

        G.arcs[i][j].adj=0;

    for(k=0;k<G.arcnum;k++)

    {

        printf("請輸入一條邊依附的頂點v1,v2及權值(v1,v2,w):");

        scanf("%d,%d,%d",&v1,&v2,&w);

        i=LocateVex(G,v1);

        j=LocateVex(G,v2);

        G.arcs[i][j].adj=w;

    }

}

void display(MGraph &G)

{

 

    int i,j;

    for(i=0;i<G.vexnum;i++)

    {

        for(j=0;j<G.vexnum;j++)

            printf("%d",G.arcs[i][j].adj);

        printf("\n");

    }

}

 

int main()

{

    int z;

    printf("請輸入選擇:\n-1-建立圖的鄰接矩陣\n-2-建立圖的鄰接表\n");

    scanf("%d",&z);

    if(z==1)

    {

         MGraph G;

         Create(G);

         display(G);

         scanf("%d",&z);

    }

    if(z==2)

    {

    ALGraph G;

    CreateALGraph(G);//建立無向圖鄰接表

    display(G);//輸出圖的的頂點信息

    printf("\n\n");

    printf("圖的深度遍歷為:\n");

    DFSTraverse(G);

    printf("\n");

    printf("\n\n");

    printf("圖的廣度遍歷為:");

    BFSTraverse(G);

    printf("\n");

    }

}

 

(二)提高題

(1)畫出數據結構基本運算的流程圖

 

 
   

 

 

 

 

 

 

 

 

(2)程序運行主要結果截圖

 

 

(3)程序源代碼

  1 #include<stdio.h>
  2 
  3 #define M 20
  4 
  5 #define N 50
  6 
  7 int a[N+1];
  8 
  9 int g[N][N];
 10 
 11 int dist[N];
 12 
 13 int m=0,n=0;
 14 
 15 void buildG()//建圖
 16 
 17 {
 18 
 19     int i,j,k,sc,dd;
 20 
 21     while(1)
 22 
 23     {
 24 
 25         printf("輸入公交線路數[1-%d],公交站數[1-%d]\n",M,N);
 26 
 27         scanf("%d %d",&m,&n);
 28 
 29         if(m>=1&&m<=M&&n>=1&&n<=N)
 30 
 31             break;
 32 
 33     }
 34 
 35     for(i=0;i<n;i++)
 36 
 37         for(j=0;j<n;j++)
 38 
 39         g[i][j]=0;
 40 
 41     for(i=0;i<m;i++)
 42 
 43     {
 44 
 45         printf("沿第%d條公交車線路前進方向的各站編號(0<=編號<=%d,-1結束):\n",i+1,n-1);
 46 
 47         sc=0;
 48 
 49         while(1)
 50 
 51         {
 52 
 53             scanf("%d",&dd);
 54 
 55             if(dd==-1)
 56 
 57                 break;
 58 
 59             if(dd>=0&&dd<n)
 60 
 61                 a[sc++]=dd;
 62 
 63         }
 64 
 65         a[sc]=-1;
 66 
 67         for(k=1;a[k]>=0;k++)
 68 
 69             for(j=0;j<k;j++)
 70 
 71             g[a[j]][a[k]]=1;
 72 
 73 }
 74 
 75 }
 76 
 77 int minLen()
 78 
 79 {
 80 
 81     int j,k;
 82 
 83     for(j=0;j<n;j++)
 84 
 85         dist[j]=g[0][j];
 86 
 87     dist[0]=1;
 88 
 89     while(1)
 90 
 91     {
 92 
 93         for(k=-1,j=0;j<n;j++)
 94 
 95             if(dist[j]>0&&(k==-1||dist[j]<dist[k]))
 96 
 97             k=j;
 98 
 99         if(k<0||k==n-1)
100 
101             break;
102 
103         dist[k]=-dist[k];
104 
105         for(j=1;j<n;j++)
106 
107             if(g[k][j]==1&&(dist[j]==0||-dist[k]+1<dist[j]))
108 
109             dist[j]=-dist[k]+1;
110 
111     }
112 
113     j=dist[n-1];
114 
115     return(k<0?-1:j-1);
116 
117 }
118 
119 int main()
120 
121 {
122 
123     int t;
124 
125     buildG();
126 
127     t=minLen();
128 
129     if(t<0)
130 
131         printf("無解!\n");
132 
133     else
134 
135         printf("從0號站到%d站需換車%d次\n",n-1,t);
136 
137 }
View Code

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM