圖的鄰接表創(chuàng)建與遍歷

對(duì)比矩陣創(chuàng)建圖##

如果圖的邊數(shù)拳氢,比較少募逞,使用矩陣,會(huì)有大量空間浪費(fèi)馋评;
這個(gè)時(shí)候放接,考慮另外一種存儲(chǔ)結(jié)構(gòu)方式,將數(shù)組和鏈表結(jié)合起來來存儲(chǔ)留特;
鄰接表的處理:

  1. 圖中的頂點(diǎn)用一個(gè)一維數(shù)組存儲(chǔ)纠脾;
  2. 圖中每個(gè)頂點(diǎn)Vi的所有鄰接點(diǎn)構(gòu)成一個(gè)線性表(單鏈表)

實(shí)現(xiàn)代碼

結(jié)構(gòu):

#define MAX_SIZE 20

// ========= 鄰接表  無向 Start ================

// 鏈表結(jié)點(diǎn) Node
typedef struct LinkNode {
    int array_index;            // 數(shù)組下標(biāo)
    int weight;                 // 權(quán)重
    struct LinkNode *next;     // 下一個(gè)頂點(diǎn)
} LinkNode;

// 圖結(jié)點(diǎn)
typedef struct GraphNode {
    char data;                  // 結(jié)點(diǎn)數(shù)據(jù)
    struct LinkNode *first;     // 頂點(diǎn)鏈表
} GraphNode;

// 圖
typedef struct GraphTable {
    GraphNode nodes[MAX_SIZE];
    int vertexNum, edgeNum;     // 頂點(diǎn)數(shù),變數(shù)
} GraphTable, *P_GraphTable;

創(chuàng)建表:

// ==== 使用鄰接表 來創(chuàng)建圖  無向     start ====
void printTable(P_GraphTable *G) {
    int i;
    LinkNode *node;
    // 輸出鄰接表
    printf("------------ 無向鄰接表 ----------\n");
    
    for(i=0; i<(*G)->vertexNum; i++) {
        node = NULL;
        node = (*G)->nodes[i].first;
        printf("%d-%c|-",i, (*G)->nodes[i].data);
        while( node != NULL && node->array_index >= 0) {
            printf("%d-",node->array_index);
            node = node->next;
        }
        printf("\n");   // 換行
    }
    
}

void createTable(P_GraphTable *G) {
    (*G) = (P_GraphTable) malloc(sizeof(GraphTable));
    
    int m,n,i;
    printf("請(qǐng)輸入圖的頂點(diǎn)數(shù)與邊數(shù):");
    scanf("%d %d", &m, &n);
    getchar();
    
    (*G)->vertexNum = m;
    (*G)->edgeNum = n;
    
    
    // 創(chuàng)建頂點(diǎn)數(shù)組 GraphNode
    for(m = 0; m<(*G)->vertexNum; m++) {
        printf("請(qǐng)輸入第 %d 個(gè)頂點(diǎn):", (m+1));
        scanf("%c", &(*G)->nodes[m].data);
        getchar();
        (*G)->nodes[m].first = NULL;    // 初始化為空表
    }
    
    // 創(chuàng)建邊
    for(i = 0; i<(*G)->edgeNum; i++) {
        printf("請(qǐng)輸入第%d條邊(Vi,Vj)上的下標(biāo)i,下標(biāo)j:\n", (i+1));
        scanf("%d %d", &m, &n);     // 下標(biāo)對(duì)應(yīng)頂點(diǎn)
        getchar();
        
    
        LinkNode *e1 = (LinkNode *)malloc(sizeof(LinkNode));
        e1->array_index = n;                // 設(shè)置鄰接點(diǎn)下標(biāo)
        e1->next = (*G)->nodes[m].first;    // 第一次時(shí)蜕青,first為NULL苟蹈,后面會(huì)被替換掉
        (*G)->nodes[m].first = e1;          // 放入圖中數(shù)組
        
        LinkNode *e2 = (LinkNode *)malloc(sizeof(LinkNode));
        e2->array_index = m;                // 設(shè)置鄰接點(diǎn)下標(biāo)
        e2->next = (*G)->nodes[n].first;
        (*G)->nodes[n].first = e2;
    }
    
    printTable(G);
}

int main(int argc, const char * argv[]) {
    P_GraphTable table;
    createTable(&table);
    return 0;
}

輸出如下

請(qǐng)輸入圖的頂點(diǎn)數(shù)與邊數(shù):4 5
請(qǐng)輸入第 1 個(gè)頂點(diǎn):A
請(qǐng)輸入第 2 個(gè)頂點(diǎn):B
請(qǐng)輸入第 3 個(gè)頂點(diǎn):C
請(qǐng)輸入第 4 個(gè)頂點(diǎn):D
請(qǐng)輸入第1條邊(Vi,Vj)上的下標(biāo)i,下標(biāo)j:
0 1
請(qǐng)輸入第2條邊(Vi,Vj)上的下標(biāo)i,下標(biāo)j:
0 2
請(qǐng)輸入第3條邊(Vi,Vj)上的下標(biāo)i,下標(biāo)j:
1 2
請(qǐng)輸入第4條邊(Vi,Vj)上的下標(biāo)i,下標(biāo)j:
2 3
請(qǐng)輸入第5條邊(Vi,Vj)上的下標(biāo)i,下標(biāo)j:
1 3
------------ 無向鄰接表 ----------
0-A|-2-1-
1-B|-3-2-0-
2-C|-3-1-0-
3-D|-1-2-

深度優(yōu)先遍歷(不斷訪問鏈表)##

直接訪問鏈表即可;

// 清空已訪問過得頂點(diǎn)數(shù)組
void clearVisit(P_GraphTable G) {
    int i;
    for(i=0; i<G->vertexNum; i++) {
        visited[i] = FALSE;
    }
}

void dfs(P_GraphTable G, int i) {
    visited[i] = TRUE;
    printf("%c ", G->nodes[i].data);
    
    LinkNode *node = G->nodes[i].first;
    while(node) {
        if(!visited[node->array_index]) {
            dfs(G, node->array_index);
        }
        node = node->next;
    }
}

void dfs_g(P_GraphTable G) {
    clearVisit(G);
    
    int i;
    for(i=0; i<G->vertexNum; i++) {
        if(!visited[i]) {       // 連通圖右核,只會(huì)執(zhí)行一次
            dfs(G, i);
        }
    }
}

廣度優(yōu)先遍歷 實(shí)現(xiàn)代碼##

//========= 廣度 Start ===================

typedef struct {
    int array[MAX_SIZE];
    int front;
    int rear;
} Queue;

void initQueue(Queue *que) {
    que->front = 0;
    que->rear = -1;
}

int isQueueEmpty(Queue *que) {
    return (que->rear + 1 == que->front || que->front == MAX_SIZE);
}

void insertQueue(Queue *que, int x) {
    if(que->rear != MAX_SIZE - 1) { // 未滿
        que->array[++que->rear] = x;
    }
}

int removeQueue(Queue *que) {
    return que->array[que->front++];
}

void bfs(P_GraphTable G) {
    Queue *que = (Queue *)malloc(sizeof(Queue));
    initQueue(que);
    
    clearVisit(G);
    int i;
    int v;
    
    for(i=0; i<G->vertexNum; i++) {
        if(!visited[i]) {   // 選取一個(gè)未訪問的頂點(diǎn),如果圖是連通圖,則只執(zhí)行一次
            printf("%c ", G->nodes[i].data);
            visited[i] = TRUE;
            insertQueue(que, i);
            
            while(!isQueueEmpty(que)) {
                v = removeQueue(que);
                LinkNode *node = G->nodes[v].first;
                while(node) {
                    if(!visited[node->array_index]) {
                        insertQueue(que, node->array_index);
                        visited[node->array_index] = TRUE;
                        printf("%c ", G->nodes[node->array_index].data);
                    }
                    node = node->next;
                }
            }
        }
    }
}

//========= 廣度 End ===================
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末慧脱,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子贺喝,更是在濱河造成了極大的恐慌菱鸥,老刑警劉巖宗兼,帶你破解...
    沈念sama閱讀 218,284評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異氮采,居然都是意外死亡殷绍,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,115評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門鹊漠,熙熙樓的掌柜王于貴愁眉苦臉地迎上來主到,“玉大人,你說我怎么就攤上這事躯概〉窃浚” “怎么了?”我有些...
    開封第一講書人閱讀 164,614評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵楞陷,是天一觀的道長怔鳖。 經(jīng)常有香客問我,道長固蛾,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,671評(píng)論 1 293
  • 正文 為了忘掉前任度陆,我火速辦了婚禮艾凯,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘懂傀。我一直安慰自己趾诗,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,699評(píng)論 6 392
  • 文/花漫 我一把揭開白布蹬蚁。 她就那樣靜靜地躺著恃泪,像睡著了一般。 火紅的嫁衣襯著肌膚如雪犀斋。 梳的紋絲不亂的頭發(fā)上贝乎,一...
    開封第一講書人閱讀 51,562評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音叽粹,去河邊找鬼览效。 笑死,一個(gè)胖子當(dāng)著我的面吹牛虫几,可吹牛的內(nèi)容都是我干的锤灿。 我是一名探鬼主播,決...
    沈念sama閱讀 40,309評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼辆脸,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼但校!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起啡氢,我...
    開封第一講書人閱讀 39,223評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤状囱,失蹤者是張志新(化名)和其女友劉穎州刽,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體浪箭,經(jīng)...
    沈念sama閱讀 45,668評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡穗椅,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,859評(píng)論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了奶栖。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片匹表。...
    茶點(diǎn)故事閱讀 39,981評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖宣鄙,靈堂內(nèi)的尸體忽然破棺而出袍镀,到底是詐尸還是另有隱情,我是刑警寧澤冻晤,帶...
    沈念sama閱讀 35,705評(píng)論 5 347
  • 正文 年R本政府宣布苇羡,位于F島的核電站,受9級(jí)特大地震影響鼻弧,放射性物質(zhì)發(fā)生泄漏设江。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,310評(píng)論 3 330
  • 文/蒙蒙 一攘轩、第九天 我趴在偏房一處隱蔽的房頂上張望叉存。 院中可真熱鬧,春花似錦度帮、人聲如沸歼捏。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,904評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽瞳秽。三九已至,卻和暖如春率翅,著一層夾襖步出監(jiān)牢的瞬間练俐,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,023評(píng)論 1 270
  • 我被黑心中介騙來泰國打工安聘, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留痰洒,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,146評(píng)論 3 370
  • 正文 我出身青樓浴韭,卻偏偏與公主長得像丘喻,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子念颈,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,933評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容

  • 圖是一種比線性表和樹更復(fù)雜的數(shù)據(jù)結(jié)構(gòu),在圖中嗡靡,結(jié)點(diǎn)之間的關(guān)系是任意的跺撼,任意兩個(gè)數(shù)據(jù)元素之間都可能相關(guān)。圖是一種多對(duì)...
    Alent閱讀 2,306評(píng)論 1 22
  • 第一章 緒論 什么是數(shù)據(jù)結(jié)構(gòu)讨彼? 數(shù)據(jù)結(jié)構(gòu)的定義:數(shù)據(jù)結(jié)構(gòu)是相互之間存在一種或多種特定關(guān)系的數(shù)據(jù)元素的集合歉井。 第二章...
    SeanCheney閱讀 5,771評(píng)論 0 19
  • 1 序 2016年6月25日夜,帝都哈误,天下著大雨哩至,拖著行李箱和同學(xué)在校門口照了最后一張合照,搬離寢室打車去了提前租...
    RichardJieChen閱讀 5,103評(píng)論 0 12
  • 圖是由頂點(diǎn)的有窮非空集合和頂點(diǎn)之間邊的集合組成蜜自,通常表示為:G(V,E)菩貌,其中,G表示一個(gè)圖重荠,V是圖G中頂點(diǎn)的集合...
    開心糖果的夏天閱讀 829評(píng)論 0 9
  • 憂郁陰暗的一部電影 兩岸還是一起的兩岸 男女文化很是接近…
    孤獨(dú)的小魚閱讀 385評(píng)論 0 1