定義:

圖是由由頂點的有窮非空集合和頂點之間邊的集合組成,可以定義為:
G=(V, E)
其中,
V = {x|x∈某個數(shù)據(jù)元素集合}
E ={(x,y)|x,y∈V} 或
E = {<x, y>|x,y∈V并且Path(x, y)}

其中,(x,y)表示從 x到 y的一條雙向通路,即(x,y)是無方向的;Path(x,y)表示從 x到 y的一條單向通路,即Path(x,y)是有方向的。
簡單來說:G是圖,V是圖中頂點的集合,E是圖中邊的集合

特點:

在線性表中,每個元素之間只有一個直接前驅(qū)和一個直接后繼,
在樹形結(jié)構(gòu)中,數(shù)據(jù)結(jié)構(gòu)是層次關(guān)系,并且每一層上的數(shù)據(jù)可能和下一層中多個元素相關(guān),但只能和上一層中一個元素相關(guān)
非線性結(jié)構(gòu),是研究數(shù)據(jù)元素之間的多對多的關(guān)系。在這種結(jié)構(gòu)中,任意兩個元素之間可能存在關(guān)系。即結(jié)點之間的關(guān)系可以是任意的,圖中任意元素之間都可能相關(guān)

基本術(shù)語

\color{red}{頂點:}在圖中的數(shù)據(jù)元素,我們稱之為頂點(Vertex)
\color{red}{邊:}頂點之間的邏輯關(guān)系用邊來表示,邊集可以是空的
\color{red}{無向邊:}若頂點{V_i到V_j}之間的邊沒有方向,則稱這條邊為無向邊,用無序偶({V_i,V_j})來表示
\color{red}{無向圖:}圖中的每一條邊都是沒有方向的
\color{red}{有向邊:}若頂點{V_i到V_j}之間的邊有方向,則稱這條邊為有向邊,也稱為弧(Arc),用有序偶<{V_i,V_j}>來表示,{V_i}稱為弧尾,{V_j}稱為弧頭
\color{red}{有向圖:}圖中的每一條邊都是有方向的
\color{red}{簡單圖:}在圖結(jié)構(gòu)中,若不存在頂點到其自身的邊,且同一條邊不重復(fù)出現(xiàn),則稱這樣的圖為簡單圖
\color{red}{無向完全圖:}在無向圖中,如果任意兩個頂點之間都存在邊,則稱該圖為無向完全圖。含有n個頂點的無向完全圖有n(n-1)/2條邊。
\color{red}{有向完全圖:}在有向圖中,如果任意兩個頂點之間都存在互為相反的兩條弧,則稱該圖為有向完全圖。含有n個頂點的無向完全圖有n
(n-1)條邊。
\color{red}{稀疏圖和稠密圖:}通常認(rèn)為邊或弧數(shù)小魚n*logn(n是頂點的個數(shù))的圖稱為稀疏圖,反之稱為稠密圖。
\color{red}{權(quán):}有些邊或弧帶有與他相關(guān)的數(shù)字,這種與圖的邊或弧相關(guān)的數(shù)字,稱為權(quán)
\color{red}{網(wǎng):}帶權(quán)的圖稱為網(wǎng)
\color{red}{子圖:}假設(shè)有兩個圖,G1=(V1, E1) 和 G2=(V2, E2)。如果V2∈V1 且 E2∈E1,則稱G2為G1的子圖

鄰接矩陣

#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include <string.h>
#include <stdlib.h>
#define isLetter(a)  ((((a)>='a')&&((a)<='z')) || (((a)>='A')&&((a)<='Z')))
#define LENGTH(a)  (sizeof(a)/sizeof(a[0]))
typedef char vertexType;
typedef int edgeType;
typedef struct _GraphMatrix{
    int vertexNumber;// 頂點數(shù)
    int edgeNumber; // 邊數(shù)
    vertexType *vertex;// 頂點集合
    edgeType **edge;// 鄰接矩陣
}GraphMatrix;

void Printf_G(GraphMatrix *g){
    for(int i=0;i<g->vertexNumber;i++){
        for(int j=0;j<g->vertexNumber;j++){
            printf("%d\t",g->edge[i][j]);
        }
        printf("\n");
    }
}
void Printf_All(GraphMatrix *g){
    int flag=1;
    for(int i=0;i<g->vertexNumber;i++){
        if(flag){
            printf(" \t");
            flag=0;
        }
        printf("%c\t",g->vertex[i]);
    }
    printf("\n");
    for(int i=0;i<g->vertexNumber;i++){
        printf("%c\t",g->vertex[i]);
        for(int j=0;j<g->vertexNumber;j++){
            printf("%d\t",g->edge[i][j]);
        }
        printf("\n");
    }
}
/*
 * 返回ch在matrix矩陣中的位置
 */
int Get_Position(GraphMatrix g, char ch){
    int i;
    for(i=0; i<g.vertexNumber; i++){
        if(g.vertex[i]==ch)
            return i;
    }
    return -1;
}
/*
 * 讀取一個輸入字符
 */
char Read_Char(){
    char ch;
    do {
        ch = getchar();
    } while(!isLetter(ch));
    return ch;
}
void Init_GraphMatrix(GraphMatrix *g){
      //初始化圖
    int v,e;
    printf("請輸入頂點數(shù)量:");
    scanf("%d",&v);
    printf("請輸入邊數(shù)量:");
    scanf("%d",&e);
    if ( v < 1 || e < 1 || (e > (v * (v-1)))){
        printf("輸入?yún)?shù)有誤!\n");
        exit(0);
    }
    g->vertexNumber=v;
    g->edgeNumber=e;
    //分配空間
    g->vertex=(vertexType*)malloc(g->vertexNumber*sizeof(vertexType));
    // 初始化"邊"
    g->edge=(edgeType**)malloc(g->vertexNumber*sizeof(edgeType));
    for(int i=0;i<g->vertexNumber;i++){
        g->edge[i]=(edgeType*)malloc(g->vertexNumber*sizeof(edgeType));
        for(int j=0;j<g->vertexNumber;j++){
            g->edge[i][j]=0;
        }
    }
    printf("初始化完畢\n");
    Printf_G(g);
}


GraphMatrix* Create_GraphMatrix(){
    char c1, c2;
    int p1, p2;
    GraphMatrix *g;
    if ((g=(GraphMatrix*)malloc(sizeof(GraphMatrix))) == NULL )
    return NULL;
    memset(g, 0, sizeof(GraphMatrix));
    Init_GraphMatrix(g);
    for (int i = 0; i < g->vertexNumber; i++){
        printf("請輸入頂點(%d)的值: ", i);
        g->vertex[i] = Read_Char();
    }
    for (int i = 0; i < g->edgeNumber; i++){
        // 讀取邊的起始頂點和結(jié)束頂點
        printf("請輸入邊(%d)起始頂點和結(jié)束頂點:", i);
        c1 = Read_Char();
        c2 = Read_Char();
        p1=Get_Position(*g, c1);
        p2=Get_Position(*g, c2 );
        if (p1==-1 || p2==-1){
            printf("輸入有誤: 無效的邊!\n");
            free(g);
            exit(0);
        }
        g->edge[p1][p2]=1;
        g->edge[p2][p1]=1;
    }
    Printf_All(g);
    return g;
}


int main()
{
    GraphMatrix *gm=Create_GraphMatrix();

    return 0;
}

鄰接表

#include <stdio.h>
#include <stdlib.h>
typedef char vertexType;
typedef struct ListEdgeNode{
    int index;                  // 邊的下標(biāo)
    struct ListEdgeNode *next;          // 指向下一個節(jié)點的指針
}ListEdgeNode;

typedef struct ListVertexNode {
    vertexType vertex;          // 頂點
     ListEdgeNode *fistEdge;        // 指向第一條邊
} ListVertexNode;

typedef struct GraphList{
    int vertexNumber;           // 頂點的數(shù)量
    int edgeNumber;             // 邊的數(shù)量
    ListVertexNode *vertex;     // 頂點集合,動態(tài)數(shù)組
}GraphList;
void GraphList_create(GraphList *g){
    printf("請分別輸入圖的頂點數(shù)量和邊的數(shù)量,用空格隔開:");
    scanf("%d %d", &g->vertexNumber, &g->edgeNumber);       //將頂點數(shù)量和邊的數(shù)量存儲在結(jié)構(gòu)體g中相應(yīng)的變量
    //為動態(tài)數(shù)組申請空間
    g->vertex = (ListVertexNode*)malloc(g->vertexNumber * sizeof(ListVertexNode));
    //初始化頂點指的第一條邊
    for (int i = 0; i < g->edgeNumber; i++){
        g->vertex[i].fistEdge = NULL;
    }

    //輸入圖的信息
    ListEdgeNode *listEdgeNode;
    for (int k = 0; k < g->edgeNumber; k++){
        int i, j;
        printf("請輸入邊(vi,vj)的下標(biāo), i和j,用空格隔開:");
        scanf("%d%d", &i, &j);
        //始終將插入的節(jié)點放在頂點所指的地一條邊
        listEdgeNode = (ListEdgeNode *)malloc(sizeof(ListEdgeNode));
        listEdgeNode->index = j;
        listEdgeNode->next = g->vertex[i].fistEdge;
        g->vertex[i].fistEdge = listEdgeNode;

        listEdgeNode = (ListEdgeNode*)malloc(sizeof(ListEdgeNode));
        listEdgeNode->index = i;
        listEdgeNode->next = g->vertex[j].fistEdge;
        g->vertex[j].fistEdge = listEdgeNode;

    }

    //輸出圖的信息
    ListEdgeNode * len = NULL;
    for (int i = 0; i < g->vertexNumber; i++){
        
        if (g->vertex[i].fistEdge != NULL)
            len = g->vertex[i].fistEdge;
        while (len!= NULL){
            printf("%d --- %d\t", i,len->index);
            len = len->next;
        }
        printf("\n");
    }
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容