大战熟女丰满人妻av-荡女精品导航-岛国aaaa级午夜福利片-岛国av动作片在线观看-岛国av无码免费无禁网站-岛国大片激情做爰视频

專注Java教育14年 全國咨詢/投訴熱線:400-8080-105
動力節(jié)點LOGO圖
始于2009,口口相傳的Java黃埔軍校
首頁 hot資訊 數(shù)據(jù)結(jié)構(gòu)-圖的存儲方式

數(shù)據(jù)結(jié)構(gòu)-圖的存儲方式

更新時間:2020-12-25 17:37:22 來源:動力節(jié)點 瀏覽1526次

在線性表中,數(shù)據(jù)元素之間是被串起來的,僅有線性關系,每個數(shù)據(jù)元素只有一個直接前驅(qū)和一個直接后繼;在樹形結(jié)構(gòu)中,數(shù)據(jù)元素之間有著明顯的層次關系,并且每一層上的數(shù)據(jù)元素可能和下一層中多個元素相關,但只能和上一層中一個元素相關;在圖形結(jié)構(gòu)中,是由頂點的有窮非空集合和頂點之間邊的集合組成,如果兩個頂點之間存在一條邊,那么就表示這兩個頂點具有相鄰關系。通常表示為:G(V,E)。其中G表示一個圖,V是圖G中的頂點集合,E是圖G中邊的集合。那么如何存儲圖呢?下面我們一起從源碼出發(fā),解析數(shù)據(jù)結(jié)構(gòu)中圖的存儲方式。其實數(shù)據(jù)結(jié)構(gòu)中圖的存儲方式分為兩種:利用鄰接矩陣,利用鄰接表。下面我們詳細看一下關于這兩種圖的存儲方式

 

 

一、利用鄰接矩陣

由定義我們可以知道,圖是由兩部分組成,頂點和邊,頂點和邊的連接,確定了圖的邏輯關系,所以圖的存儲,其中它的頂點需要存儲,邊與邊的連接信息也要存儲。頂點的信息,可以使用一維數(shù)組進行存儲。邊的信息,存在這多對多的邏輯關系,那么可以使用二維數(shù)據(jù)進行存儲。鄰接矩陣的存儲,其實就是順序存儲的方式。

鄰接矩陣存儲實現(xiàn)思路:

1.確定頂點數(shù)

2.讀取頂點信息

3.初始化鄰接矩陣

4.讀入邊的信息

5.循環(huán)打印

鄰接矩陣存儲圖的數(shù)據(jù)結(jié)構(gòu):

#define OK 1

#define ERROR 0

#define TRUE 1

#define FALSE 0

#define MAXVEX 100 /* 最大頂點數(shù),應由用戶定義 */

#define INFINITYC 0

 

typedef int Status;    /* Status是函數(shù)的類型,其值是函數(shù)結(jié)果狀態(tài)代碼,如OK等 */

typedef char VertexType; /* 頂點類型應由用戶定義  */

typedef int EdgeType; /* 邊上的權(quán)值類型應由用戶定義 */

typedef struct

{

    VertexType vexs[MAXVEX]; /* 頂點表 */

    EdgeType arc[MAXVEX][MAXVEX];/* 鄰接矩陣,可看作邊表 */

    int numNodes, numEdges; /* 圖中當前的頂點數(shù)和邊數(shù)  */

}MGraph;

 

存儲部分

void CreateMGraph(MGraph *G){

    

    int i,j,k,w;

    printf("輸入頂點數(shù)和邊數(shù)\n");

    scanf("%d,%d",&G->numNodes,&G->numEdges);

    printf("頂點數(shù):%d,邊數(shù):%d\n",G->numNodes,G->numEdges);

    

    

    // 輸入頂點信息,組成頂點表

    for (i = 0; i<=G->numNodes; i++) {

        scanf("%c",&G->vexs[i]);

    }

    

    // 初始化鄰接矩陣

    for (i = 0; i<=G->numNodes; i++) {

        for (j = 0; j<=G->numNodes; j++) {

            G->arc[i][j] = INFINITYC; // 初始化0

        }

    }

    

    // 輸入邊表數(shù)據(jù)

    for (k = 0; k<G->numEdges; k++) {

        printf("輸入邊(vi,vj)上的下標i,下標j,權(quán)w\n");

        scanf("%d,%d,%d",&i,&j,&w);

        G->arc[i][j] = w;

        //如果是無向圖的話 矩陣對陣

        G->arc[j][i] = w;

    }

    

    // 打印鄰接矩陣

    printf("矩陣結(jié)果\n");

       for (int i = 0; i < G->numNodes; i++) {

           printf("\n");

           for (int j = 0; j < G->numNodes; j++) {

               printf("%d ",G->arc[i][j]);

           }

       }

       printf("\n");

    

}

 

/**

        輸入頂點數(shù)和邊數(shù)

         4,5

         頂點數(shù):4,邊數(shù):5

         abcd

         輸入邊(vi,vj)上的下標i,下標j,權(quán)w

         0,1,1

         輸入邊(vi,vj)上的下標i,下標j,權(quán)w

         0,2,1

         輸入邊(vi,vj)上的下標i,下標j,權(quán)w

         0,3,1

         輸入邊(vi,vj)上的下標i,下標j,權(quán)w

         1,2,1

         輸入邊(vi,vj)上的下標i,下標j,權(quán)w

         2,3,1

         矩陣結(jié)果

         0 1 1 1

         1 0 1 0

         1 1 0 1

         1 0 1 0

*/

 

二、利用鄰接表

同樣的,鄰接矩陣(順序存儲)的方式,可能會產(chǎn)生一些空白的空間,會造成空間的浪費,那么,我們嘗試使用鏈式的存儲。

 

鄰接表中首先有一個一維數(shù)組,在這個一維數(shù)組中的某一個頂點數(shù)據(jù),指向了一個鏈表。一維數(shù)組中的數(shù)據(jù),類似鏈表中的表頭。鏈表中的數(shù)據(jù)都是與其有著頂點的連接邏輯關系的。

假如邊有權(quán)重,那么鄰接表的節(jié)點可以添加一個權(quán)重。

 

鄰接表存儲的數(shù)據(jù)結(jié)構(gòu)設計:

#define M 100

#define true 1

#define false 0

 

typedef char Element;

typedef int BOOL;

//鄰接表的節(jié)點

typedef struct Node{

    int adj_vex_index;  //弧頭的下標,也就是被指向的下標

    Element data;       //權(quán)重值

    struct Node * next; //邊指針

}EdgeNode;

 

//頂點節(jié)點表

typedef struct vNode{

    Element data;          //頂點的權(quán)值

    EdgeNode * firstedge;  //頂點下一個是誰?

}VertexNode, Adjlist[M];

 

//總圖的一些信息

typedef struct Graph{

    Adjlist adjlist;       //頂點表

    int arc_num;           //邊的個數(shù)

    int node_num;          //節(jié)點個數(shù)

    BOOL is_directed;      //是不是有向圖

}Graph, *GraphLink;

 

 

存儲部分

void creatGraph(GraphLink *g){

    int i,j,k;

    EdgeNode *p;

    

    //1. 頂點,邊,是否有向

    printf("輸入頂點數(shù)目,邊數(shù)和有向?:\n");

    scanf("%d %d %d", &(*g)->node_num, &(*g)->arc_num, &(*g)->is_directed);

    

    //2.頂點表

     printf("輸入頂點信息:\n");

    for (i = 0; i < (*g)->node_num; i++) {

        getchar();

        scanf("%c", &(*g)->adjlist[i].data);

        (*g)->adjlist[i].firstedge = NULL;

    }

    

    //3.錄入數(shù)據(jù)

    printf("輸入邊信息:\n");

    for (k = 0; k < (*g)->arc_num; k++){

        getchar();

        scanf("%d %d", &i, &j);

        

        //①新建一個節(jié)點

        p = (EdgeNode *)malloc(sizeof(EdgeNode));

        //②弧頭的下標

        p->adj_vex_index = j;

        //③頭插法插進去,插的時候要找到弧尾,那就是頂點數(shù)組的下標i

        p->next = (*g)->adjlist[i].firstedge;

        //④將頂點數(shù)組[i].firstedge 設置為p

        (*g)->adjlist[i].firstedge = p;

        

        //j->i

        if(!(*g)->is_directed)

        {

            // j -----> i

            //①新建一個節(jié)點

            p = (EdgeNode *)malloc(sizeof(EdgeNode));

            //②弧頭的下標i

            p->adj_vex_index = i;

            //③頭插法插進去,插的時候要找到弧尾,那就是頂點數(shù)組的下標i

            p->next = (*g)->adjlist[j].firstedge;

            //④將頂點數(shù)組[i].firstedge 設置為p

            (*g)->adjlist[j].firstedge = p;

        }

    }

}

 

圖作為一種非線性數(shù)據(jù)結(jié)構(gòu),圖的存儲方式相對于線性數(shù)據(jù)結(jié)構(gòu)的存儲是比較復雜的,弄懂圖的存儲對我們掌握圖的數(shù)據(jù)結(jié)構(gòu)有著重要意義,沒有看明白的小伙伴可以到本站的數(shù)據(jù)結(jié)構(gòu)和算法教程中觀看更加詳細的講解。


提交申請后,顧問老師會電話與您溝通安排學習

免費課程推薦 >>
技術文檔推薦 >>
主站蜘蛛池模板: 国产精品久久久99 | 99久久影院| 欧美激情视频一区 | 国产精品免费大片一区二区 | 在线精品国产 | 亚洲精品国产精品乱码视色 | 亚洲欧美日韩一区二区在线观看 | 日韩欧美亚洲每的更新在线 | 亚洲qingse| 久久国产精品亚洲一区二区 | 狠狠操图片 | 图片区亚洲| 国产免费高清视频 | 国产在线98福利播放视频免费 | 女色综合 | 女人18级毛片久久 | 日本a一级毛片免费观看 | 国产你懂得| 三级aa久久 | 亚洲六月丁香色婷婷综合久久 | 99久热在线精品视频播 | 国产亚洲精品一区二区三区 | 在线色av | 国产伦精品一区三区视频 | 国产大片中文字幕 | 黄片a级毛片| 天天摸天天操免费播放小视频 | 成人a毛片在线看免费全部播放 | 五月激情久久 | 久青草国产在线 | 国产精品久久久久久久y | 中国性孕妇xxxxxxxx孕交 | 国产福利不卡视频在免费播放 | 国产网友自拍 | 国产综合久久久久影院 | 国产乱人伦av在线a 国产乱人伦精品一区二区 国产乱人伦偷精品视频不卡 | 久久国内精品 | 在线成人aa在线看片 | 天天爽夜夜爽天天做夜夜做 | 成人免费国产欧美日韩你懂的 | 国产亚洲日本 |