圖的鄰接矩陣存儲結構基本操作的實現

主要代碼:

/****************************************************
  @Title: 數據結構實驗
  @Name: <實驗7-1> 圖的遍歷
  @Object:
      [實驗目的]
          實現圖的存儲結構;
          實現圖的深度優先和廣度優先遍歷
      [實驗提示]
          1. 在 graph.h 中實現圖的基本操作
          2. 在 graph.h 中實現圖的深度優先遍歷和廣度
             優先遍歷           
  @Include:
      ds.h
          類C通用模塊
      graph.h [*]
          圖的實現
  @Usage:
      請查看"TO-DO列表",根據要求完成代碼
  @Copyright: BTC 2004, Zhuang Bo
  @Author: Zhuang Bo
  @Date: 2004
  @Description:
*****************************************************/

#include <stdio.h>
#include <stdlib.h> //for system()
#include "ds.h"
#include "graph.h"

Status printvex(VexType val); //訪問頂點的函數 
void main()
{
    MGraph g;

    //建立圖
    CreateGraph(g);
    //printf("\n鄰接矩陣:\n"); 
    PrintAdjMatrix(g); //打印鄰接矩陣 

    //深度優先和廣度優先遍歷圖
    printf("\n深度優先遍歷:\n"); 
    DFSTraverse(g,0,printvex); //從頂點0開始
    printf("\n廣度優先遍歷:\n"); 
    BFSTraverse(g,0,printvex);

    //銷燬圖
    DestroyGraph(g);    

    system("pause"); //暫停
}

//打印頂點 
Status printvex(VexType val)
{
    write(val);
    return OK;
}

/*
  Name: 圖的鄰接矩陣存儲結構 
  Copyright: BTC 2004
  Author: Zhuang Bo
  Date: 2004
  Description: 
*/

#ifndef GRAPH_H_INCLUDED
#define GRAPH_H_INCLUDED
#define MAXQSIZE 64 
#include <stdio.h>
#include "ds.h"

///////////////////////////////////////////////////////////
//圖的鄰接矩陣表示
#define MAX_VERTEX_NUM 20 //最大頂點數
#define VexType char //頂點類型
#define ArcType int
#define INFINITY INT_MAX  //無窮大 
#define ElemType int
typedef struct {
    VexType  vexs[MAX_VERTEX_NUM]; //頂點向量 
    ArcType  arcs[MAX_VERTEX_NUM][MAX_VERTEX_NUM]; //鄰接矩陣 
    int      vexnum,arcnum;   //頂點,邊個數
} MGraph;
typedef struct Sq{
    /* TODO (#1#): 這裏完成循環隊列的類型定義 */
    ElemType *base;
    int front;
    int rear;
    //....................................
} SqQueue;
int   visited[100];
/* 循環隊列的最大容量 */

///////////////////////////////////////////////////////////
//圖的基本操作聲明 

//輸入頂點和弧的信息,建立圖
Status CreateGraph(MGraph &G); 
//銷燬圖的結構
Status DestroyGraph(MGraph &G);

//取頂點
VexType GetVex(MGraph G, int v);
//更新頂點信息 
Status PutVex(MGraph &G, int v, VexType val);
//插入弧(v,w)
Status InsertArc(MGraph &G, int v, int w, ArcType arc);
//刪除弧(v,w)
Status DeleteArc(MGraph &G, int v, int w);
//插入頂點v
Status InsertVex(MGraph &G, VexType val);
//刪除頂點v
Status DeleteVex(MGraph &G, int v);

//圖G中頂點v的第一個鄰接點
int FirstAdjVex(MGraph G, int v);
//圖G中頂點v在w之後的下一個鄰接點
int NextAdjVex(MGraph G, int v, int w);

//深度優先遍歷圖
void  DFSTraverse(MGraph G, int v, Status(*Visit)(VexType));
//廣度優先遍歷圖 
Status BFSTraverse(MGraph G, int v, Status(*Visit)(VexType));

//打印鄰接矩陣(調試用)
void PrintAdjMatrix(MGraph G);
int locateVex(MGraph G, VexType v);
void PrintAdjMatrix(MGraph G) ;
void DFS (MGraph G, int v);
Status InitQueue(SqQueue &Q);
EnQueue(SqQueue &Q, ElemType e);
Status QueueEmpty(SqQueue Q);
Status DeQueue(SqQueue &Q, ElemType &e);
///////////////////////////////////////////////////////////
//基本操作的實現
//刪除隊列Q的隊頭元素,並用e返回 
//  前提:隊列Q存在且非空 
Status DeQueue(SqQueue &Q, ElemType &e)
{
    /* TODO (#9#): 出隊列存入e */
    if(Q.front==Q.rear){
        return ERROR;
    }
    e=Q.base[Q.front];
    Q.front=(Q.front+1)%MAXQSIZE;
    return OK ;//返回操作狀態(成功:OK,失敗:ERROR)
    //....................................
}
//若隊列Q爲空,則返回TRUE,否則FALSE 
//  前提:隊列Q已存在
Status QueueEmpty(SqQueue Q)
{
    /* TODO (#5#): 判斷隊列是否爲空 */
    if(Q.rear==Q.front){
        return TRUE; 
    }
    return FALSE;
    //....................................
}

//構造一個空隊列Q
Status InitQueue(SqQueue &Q)
{
    /* TODO (#2#): 構造空隊列 */
    Q.base=(ElemType*)malloc(MAXQSIZE*sizeof(ElemType));
    if(!Q.base){
        exit(0);
    }
    Q.front=Q.rear=0;
    return OK; //TODO: 替換這行代碼,以下同
    //....................................
}
//入隊列
Status EnQueue(SqQueue &Q, ElemType e)
{
    /* TODO (#8#): 元素e入隊列 */
    if((Q.rear+1)%MAXQSIZE==Q.front){
        return ERROR;
    }
    Q.base[Q.rear]=e;
    Q.rear=(Q.rear+1)%MAXQSIZE;
    return OK;//返回操作狀態(成功:OK,失敗:ERROR)
    //....................................
}
int locateVex(MGraph G, VexType v){
    for(int i = 0; i < G.vexnum; i++){
        if(G.vexs[i] == v)
            return i;
    }
    return -1;//圖中沒有該頂點
}

//輸入頂點和弧的信息,建立圖
Status CreateGraph(MGraph &G)
{
    //-------------------------------------
    // TODO (#1#): 先輸入頂點個數和頂點數據,然後輸入弧,建立圖 
    printf("輸入頂點數和弧數如:(5,3):");
    scanf("%d,%d", &G.vexnum, &G.arcnum);

    printf("輸入%d個頂點(以空格隔開如:v1 v2 v3):", G.vexnum);
    getchar();//吃掉換行符
    for(int m = 0; m < G.vexnum; m++){
        scanf("%c", &G.vexs[m]);
        getchar();//吃掉空格符
    }
    for( m = 0; m < G.vexnum; m++){
        printf("%c", G.vexs[m]);
        printf("\n");
    //  getchar();//吃掉空格符
    }
//初始化鄰接矩陣
    int i=0, j=0;
    for(i = 0; i < G.vexnum; i++){
        for(j = 0; j < G.vexnum; j++)
            G.arcs[i][j] = 0;
    }
//打印初始化的鄰接矩陣

/*  for(i = 0; i < G.vexnum; i++){
        for(j = 0; j < G.vexnum; j++)
        printf( "%5d\n",G.arcs[i][j]);
    }*/
    VexType v1, v2;//分別是一條弧的弧尾和弧頭(起點和終點)
    int w;//對於無權圖或網,用0或1表示相鄰否;對於帶權圖或網,則爲相應權值    
    printf("\n每行輸入一條弧依附的頂點(先弧尾後弧頭)和權值(如:v1 v2 3):\n");
    fflush(stdin);//清除殘餘後,後面再讀入時不會出錯
   for(int k = 0; k < G.arcnum; k++){
        scanf("%c %c %d",&v1, &v2, &w);
        fflush(stdin);//清除殘餘後,後面再讀入時不會出錯
        i = locateVex(G, v1);
        j = locateVex(G, v2);
        G.arcs[i][j] = w;
    }

    return OK;
    //-------------------------------------
}

//銷燬圖的結構
Status DestroyGraph(MGraph &G)
{
    return OK;//什麼也不做
} 

//取頂點
Status GetVex(MGraph G, int v, VexType &val)
{
    if(v<0||v>=G.vexnum) return ERROR;
    val = G.vexs[v];
    return OK;
}

//更新頂點信息 
Status PutVex(MGraph &G, int v, VexType val)
{
    if(v<0||v>=G.vexnum) return ERROR;
    G.vexs[v] = val;
    return OK;
}

//插入弧(v,w)
Status InsertArc(MGraph &G, int v, int w, ArcType arc)
{
    if(v<0||v>=G.vexnum||w<0||w>=G.vexnum) return ERROR;
    G.arcs[v][w] = arc;
    return OK;
}

//刪除弧(v,w)
Status DeleteArc(MGraph &G, int v, int w)
{
    if(v<0||v>=G.vexnum||w<0||w>=G.vexnum) return ERROR;
    G.arcs[v][w] = 0; //刪除弧 
    return OK;
}

//插入頂點v
Status InsertVex(MGraph &G, VexType val)
{
    //-------------------------------------
    // TODO (#1#): 插入頂點v,注意對鄰接矩陣的影響

    return ERROR;
    //-------------------------------------
}

//刪除頂點v
Status DeleteVex(MGraph &G, int v)
{
    //-------------------------------------
    // TODO (#1#): 刪除頂點v,注意對鄰接矩陣的修改

    return ERROR;
    //-------------------------------------
}

//圖G中頂點v的第一個鄰接點,不存在時返回 -1 
int FirstAdjVex(MGraph G, int v)
{
    //-------------------------------------
    // TODO (#1#): 返回頂點v的第一個鄰接點
    int i;
    for(i=0;i<G.vexnum;i++){
        if(G.arcs[v][i]){
            return i;
        }
    }
    return -1;
    //-------------------------------------
}

//圖G中頂點v在w之後的下一個鄰接點,不存在時返回 -1
int NextAdjVex(MGraph G, int v, int w)
{
    //-------------------------------------
    // TODO (#1#): 返回頂點v在w之後的下一個鄰接點
    int i;
    for(i=w+1;i<G.vexnum;i++){
        if(G.arcs[v][i]){
            return i;
        }
    }
    return -1;
    //-------------------------------------
}
//深度優先遍歷圖
void DFSTraverse(MGraph G, int v, Status(*Visit)(VexType))
{

    //-------------------------------------
    // TODO (#1#): 從v出發,深度優先遍歷圖
    for(v=0;v<G.vexnum;++v){
     visited[v]=FALSE;
    }
    for(v=0;v<G.vexnum;++v){
        if(!visited[v]){
           DFS (G, v);
        }
    }
    //-------------------------------------
}
void DFS (MGraph G, int v){
        visited[v]= TRUE;
        write (v);
           for(int w=FirstAdjVex(G, v);w>0;w=NextAdjVex(G, v, w)){
               if(!visited[w])
                    DFS (G, w);
           }
}
//廣度優先遍歷圖 
Status BFSTraverse(MGraph G, int v, Status(*Visit)(VexType))
{
    //-------------------------------------
    // TODO (#1#): 從v出發,廣度優先遍歷圖
    int u;
    SqQueue Q;
    for(v=0;v<G.vexnum;++v){
        visited[v]= FALSE;
    }
    InitQueue(Q);
    for(v=0;v<G.vexnum;++v)
        if(!visited[v]){
            visited[v]=TRUE;
            write (v);
            EnQueue(Q, v);
            while(!QueueEmpty(Q)){
                DeQueue(Q, u);
                for(int w=FirstAdjVex(G, u);w>=0;w=NextAdjVex(G, u, w))
                    if(!visited[w]){
                        visited[w]=TRUE;
                        write (w);
                        EnQueue(Q, w);
                    }

                }


    }
    //-------------------------------------
    return 1;
}

//打印鄰接矩陣
void PrintAdjMatrix(MGraph G) 
{
    int i,j;
    for(i=0; i<G.vexnum; i++) {
        write(G.vexs[i]);
        for(j=0; j<G.vexnum; j++)
            printf("%5d", G.arcs[i][j]);
        printf("\n");
    }
}

#endif //GRAPH_H_INCLUDED

演示效果圖:

這裏寫圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章