20172316 2018-2019-1《程序設計與數據結構》第九周學習總結

20172316 2018-2019-1《程序設計與數據結構》第九周學習總結

教材學習內容總結

第十五章 圖

圖:

圖一樣是一種數據結構,和樹同樣是非線性的,我以爲能夠理解爲它是沒有父子概念、結點能夠鏈接多個結點的樹html

圖的分類:

無向圖(undirected graph),形如上圖,兩個結點之間的邊沒有方向,僅表示兩結點存在關係。git

有向圖(directed graph),兩結點之間的邊擁有箭頭來指示方向,在表述兩點關係時,不能顛倒順序(如上圖,B→A,但不能夠A→B)算法

連通圖(connected graph),圖中任意兩結點都存在一條路徑,稱爲連通。對於無向圖和有向圖定義都相同,但要注意若在有向圖中存在沒有入度的結點,那就是不連通的。數組

網絡(加權圖),每條邊上都有權重或代價的圖,網絡

其餘定義:

出度、入度,對於有向圖中的A來講,A→B與B→A一個是出一個是入,二者有所區分,定義由A指向其餘結點的邊的數量是A的出度,反之是入度。數據結構

鄰接矩陣:使用二維數組存儲兩頂點之間的鏈接狀況,因此無向圖的矩陣始終是對稱的,有向圖則不必定。
圖一的鄰接矩陣:
| | A | B | C | D | E |
|:-----:|:-----:|:-----:|:-----:|:------:|:------:|
| A | F | T | T | F | T |
|B | T | F | T | T | F |
|C | T | T | F | T | F |
|D | F | T | T | F | T |
|E | T | F | F | T | F |學習

經常使用圖的算法

遍歷:圖的遍歷分類兩類:廣度遍歷和深度遍歷
對於如圖所使的圖咱們選定A爲起始頂點:廣度遍歷會以A爲中心輻射狀遍歷:A BCEF IDG H;
而深度遍歷會沿着一條一條的路徑分別遍歷直到全部路徑走完:A B CIDH EGF。
(具體遍歷過程可能並不是如此,但規律不變)測試

測試連通性:既有連通圖又有不連通圖,如何測試一個圖的連通性呢?
若是一個圖的遍歷結果的頂點個數少於圖中全部結點個數,那就說明有一些頂點不存在和其餘結點相連的路徑,也就是缺乏連通性了。設計

最小生成樹:樹是圖的一種,生成樹是一個含有圖中全部頂點和部分邊(可能不是全部邊)的樹。而最小生成樹是對於加權圖而言的,一棵生成樹的邊的權重總和小於等於同一個圖中其餘任意一棵生成樹的,就是最小生成樹。3d

教材學習中的問題和解決過程

既然經過遍歷的完整性來測試圖的連通性,對於一個不連通的圖,如何完整地遍歷出它來呢?

書本上測試連通性時,使用了廣度優先遍歷的方法,將每個頂點都做爲起始頂點遍歷了一次,雖然每次遍歷都不是完整的,個人想法是:取它們結果的並集就能夠獲得全部頂點了。

找到一段C語言的代碼,重點在BFS1方法上,它確實遍歷了n遍,和個人想法差的很少

#include <stdio.h>
#include <malloc.h>
#include "graph.h"
int visited[MAXV];     //定義存放節點的訪問標誌的全局數組
void BFS(ALGraph *G, int v)
{
    ArcNode *p;
    int w;
    int queue[MAXV],front=0,rear=0; //定義循環隊列
    printf("%2d",v);            //輸出被訪問頂點的編號
    visited[v]=1;                       //置已訪問標記
    rear=(rear+1)%MAXV;
    queue[rear]=v;              //v進隊
    while (front!=rear)         //若隊列不空時循環
    {
        front=(front+1)%MAXV;
        w=queue[front];             //出隊並賦給w
        p=G->adjlist[w].firstarc;   //找w的第一個的鄰接點
        while (p!=NULL)
        {
            if (visited[p->adjvex]==0)
            {
                printf("%2d",p->adjvex); //訪問之
                visited[p->adjvex]=1;
                rear=(rear+1)%MAXV; //該頂點進隊
                queue[rear]=p->adjvex;
            }
            p=p->nextarc;       //找下一個鄰接頂點
        }
    }
    printf("\n");
}

//採用廣度優先搜索遍歷非連通無向圖
void BFS1(ALGraph *G)
{
   int i;
   for (i=0;i<G->n;i++)
      if (visited[i]==0)
           BFS(G,i);
}

int main()
{
    int i;
    ALGraph *G;
    int A[8][8]=
    {
        {0,1,0,1,0,0,0,0},
        {1,0,1,0,0,0,0,0},
        {0,1,0,1,1,0,0,0},
        {1,0,1,0,1,0,0,0},
        {0,0,1,1,0,0,0,0},
        {0,0,0,0,0,0,1,0},
        {0,0,0,0,0,1,0,1},
        {0,0,0,0,0,0,1,0},
    };
    ArrayToList(A[0], 8, G);
    for (i=0; i<G->n; i++)
        visited[i]=0; //訪問標誌數組初始化
    printf(" 非連通圖的廣度優先遍歷:\n");
    BFS1(G);
    return 0;
}

代碼調試中的問題和解決過程

建立了一個圖,發現結果並不對勁

創建了0-1,0-2,0-4,1-2,1-3,2-3的聯繫,可是鄰接矩陣中沒有true,可見創建失敗了。

利用索引的addEdge()很差用,試試對象直接add

直接蹦出異常

找到下列幾個嫌疑人:getIndex()indexIsValid()addEdge()

後來發現indexIsValid()確實發生錯誤,也不知道當時怎麼就把大於小於搞錯了。

錯誤消滅。


代碼託管

(statistics.sh腳本的運行結果截圖)


上週考試錯題總結


學習進度條

代碼行數(新增/累積) 博客量(新增/累積) 學習時間(新增/累積) 重要成長
目標 5000行 30篇 400小時
第一週 0/0 1/1 6/6
第二週 771/771 1/2 16/22
第三週 562/1233 1/3 15/37
第四周 1503/2736 2/5 15/52
第五週 1152/3888 1/6 10/62
第六週 787/4675 1/7 10/72
第七週 1214/5889 1/8 9/81
第八週 1534/7423 1/9 9/90
第九周 1240/8663 2/11 10/100

結對互評

唐才銘19:本次博客中記述問題較少,可是教材內容表述詳細,理解到位。
王文彬29:本次博客引用了許多書本原話,很是充實,也提出了好幾個本身的問題而且及時解決了。

參考資料

相關文章
相關標籤/搜索