1. 程式人生 > IOS開發 >資料結構與演演算法之圖的認識與儲存

資料結構與演演算法之圖的認識與儲存

認識圖

  • 圖的定義:由頂點的有窮非空集合和頂點之間的邊的集合組成。通常表示為G[V,E],其中G表示一個圖,V是圖G中的頂點集合,E是圖G中邊的集合
  • 各種圖:
  1. 無向圖:圖中頂點與頂點連線沒有方向;無向邊:圖中邊沒有方向


  2. 有向圖:圖中頂點與頂點之間有方向;有向邊:圖中邊具有方向


  3. 完全圖:頂點與頂點之間完全連線


  4. 網:當圖的邊加上權重後就是網。


圖的儲存

鄰接矩陣儲存

  • 無向圖的鄰接矩陣
  • 有向圖的鄰接矩陣


  • 網的臨界矩陣


  • 程式碼實現:

    #include <stdio.h>
    #include <stdlib.h>
    #include <math.h>
    #include <time.h> #define OK 1 #define ERROR 0 #define TRUE 1 #define FALSE 0 #define MAXVEX 100 /* 最大頂點數,應由使用者定義 */ #define INFINITYC 0 typedef int Status; /* Status是函式的型別,其值是函式結果狀態程式碼,如OK等 */ typedef char VertexType; /* 頂點型別應由使用者定義 */ typedef int EdgeType; /* 邊上的權值型別應由使用者定義 */ typedef struct { VertexType vexs[MAXVEX]; /* 頂點表 */ EdgeType arc[MAXVEX][MAXVEX];/* 鄰接矩陣,可看作邊表 */ int numNodes,numEdges; /* 圖中當前的頂點數和邊數 */ }MGraph; void CreatMGraph(MGraph *Map){ VertexType top[] = {"A"
    ,"B","C","D"}; Map->numNodes = 4; Map->numEdges = 5; for (int i = 0; i<Map->numNodes; i++) { Map->vexs[i] = top[i]; } for (int i = 0; i<Map->numNodes; i++) { for (int j = 0; j<Map->numNodes; j++) { //表示邊沒有連線 Map->arc[i][j] = INFINITYC; } } int i,j,k,w; //01,02,03,12,23 for
    (k = 0; k < Map->numEdges;k++){ printf("輸入邊(vi,vj)上的下標i,下標j,權w\n"); scanf("%d,%d,%d",&i,&j,&w); Map->arc[i][j] = w; //如果無向圖,矩陣對稱; Map->arc[j][i] = Map->arc[i][j]; } printf("鄰接矩陣是:\n"); for (i = 0; i<Map->numNodes; i++) { printf("\n"); for (j = 0; j<Map->numNodes; j++) { printf("%3d",Map->arc[i][j]); } } printf("\n"); } int main(int argc,const char * argv[]) { // insert code here... printf("Hello,World!\n"); MGraph map; CreatMGraph(&map); return 0; } 複製程式碼

鄰接表

  • 無向圖鄰接表


  • 有向圖鄰接表


  • 鄰接表的資料結構設計


  • 鄰接表的程式碼實現思路


  • 鄰接表的程式碼實現

    #include <stdio.h>
    #include "stdlib.h"
    #include "math.h"
    #include "time.h"
    
    #define M 100
    #define true 1
    #define false 0
    
    typedef char Element;
    typedef int BOOL;
    //鄰接表的節點
    typedef struct Node{
        int adj_vex_index;  //弧頭的下標,也就是被指向的下標
        Element data;       //權重值
        struct Node * next; //邊指標
    }EdgeNode;
    
    //頂點節點表
    typedef struct vNode{
        Element data;          //頂點的權值
        EdgeNode * firstedge;  //頂點下一個是誰?
    }VertexNode,Adjlist[M];
    
    //總圖的一些資訊
    typedef struct Graph{
        Adjlist adjlist;       //頂點表
        int arc_num;           //邊的個數
        int node_num;          //節點個數
        BOOL is_directed;      //是不是有向圖
    }Graph,*GraphLink;
    #pragma mark - 鄰接表的儲存
    void SaveGraph(GraphLink *Grap){
        int i,k;
        EdgeNode *p;
        printf("輸入頂點數目,邊數和有向?:\n");
        scanf("%d %d %d",&(*Grap)->node_num,&(*Grap)->arc_num,&(*Grap)->is_directed);
        for (i = 0; i<(*Grap)->node_num; i++) {
            getchar();
            scanf("%c",&(*Grap)->adjlist[i].data);
            (*Grap)->adjlist[i].firstedge = NULL;
        }
        printf("輸入邊資訊\n");
        for (k = 0; k<(*Grap)->arc_num; k++) {
            getchar();
            scanf("%d %d",&j);
            //建立結點
            p = (EdgeNode *)malloc(sizeof(EdgeNode));
            //設定弧頭下標
            p->adj_vex_index = j;
            //使用頭插法
            p->next = (*Grap)->adjlist[i].firstedge;
            (*Grap)->adjlist[i].firstedge = p;
            if (!(*Grap)->is_directed) {//無向圖時
                //t無向圖是對稱的,所以程式碼給上面一致,唯一的區別是座標變為j,j變為i
                //建立結點
                p = (EdgeNode *)malloc(sizeof(EdgeNode));
                //設定弧頭下標
                p->adj_vex_index = i;
                //使用頭插法
                p->next = (*Grap)->adjlist[j].firstedge;
                (*Grap)->adjlist[j].firstedge = p;
            }
        }
    }
    #pragma mark - 輸出鄰接表資料
    void putGraph(GraphLink g){
        int i;
        printf("鄰接表中儲存資訊:\n");
        //遍歷一遍頂點座標,每個再進去走一次
        for (i = 0; i < g->node_num; i++) {
            EdgeNode * p = g->adjlist[i].firstedge;
            while (p) {
                printf("%c->%c ",g->adjlist[i].data,g->adjlist[p->adj_vex_index].data);
                p = p->next;
            }
            printf("\n");
        }
    }
    
    int main(int argc,World!\n");
        GraphLink Grap = (GraphLink)malloc(sizeof(Graph));
        SaveGraph(&Grap);
        putGraph(Grap);
        return 0;
    }
    
    
    複製程式碼