拓撲排序

先上一波圖看看效果

image

image

DAG與AOV双饥?

DAG(Directed Acyclic Grap)指的是“有向無環(huán)圖”,通常也稱為“流程圖”迂苛。

當我們要完成一個工程的時候禁悠,我們可以先將大的工程分成幾個獨立的子工程欧啤,將子工程d當作“活動”睛藻,每個活動之間有先決條件的關系(時間上有著相互制約的關系),就是說活動的執(zhí)行有一定的順序邢隧。將“活動”看成頂點店印,以弧表示活動之間的優(yōu)先關系,這樣的圖稱為“AOV”網(wǎng)(Activity On Vertex NetWork)倒慧。

拓撲排序是什么吱窝,有什么用?

如果要執(zhí)行活動A迫靖,必須執(zhí)行活動B院峡,執(zhí)行B就要執(zhí)行C,要執(zhí)行C就要執(zhí)行A系宜,這樣形成一個環(huán)的話照激,就陷入了死循環(huán),那我們怎么知道到底有沒有環(huán)呢盹牧?這時候就出現(xiàn)了拓撲排序俩垃,也就是說拓撲排序?qū)z測AOV圖中是否有環(huán)励幼,求一個有向圖拓撲排序序列的過程就是拓撲排序。

實現(xiàn)拓撲排序?qū)嵗?/h2>

先來看看用到的結(jié)構(gòu)體吧

#include <stdlib.h>
#include<stdio.h>
#define MAXVEX 20
#define NON -1
typedef char VexType;
typedef float AdjType;

/* 邊表中的結(jié)點 */
typedef struct EdgeNode {
    int endvex;         // 相鄰頂點字段 ,一條邊的另一個頂點
    AdjType weight;     //邊的權(quán)口柳,非帶權(quán)圖可以省略 
    struct EdgeNode *nextedge;  // 鏈字段 ,連接到下一條邊
}*PEdgeNode, *EdgeList;

/*頂點中的信息*/
typedef struct {
    VexType vertex;     // 頂點信息 
    EdgeList edgelist;  //后面所有的邊和組成的邊
} VexNode;  // 頂點表中的結(jié)點 

/*點的集合和邊表中鏈接信息構(gòu)成了圖*/                     
typedef struct {
    int n;              // 圖的頂點個數(shù) 
    VexNode vexs[MAXVEX];
} GraphList;

拓撲排序只需3步:

  1. 輸出頂點入度為0的值
  2. 讓這個點消失(刪除點及由它發(fā)出的邊)
  3. 重復執(zhí)行1和2直到輸出無連接邊的頂點

當然執(zhí)行這些之前苹粟,你得有個圖啊(攤手)跃闹,已經(jīng)有圖的童鞋請?zhí)^這一步嵌削。(下面是插入方法的主要代碼)

/*插入頂點及連接的信息*/
void insert(GraphList* p, int a, int b) {//a,b是將要連接的兩個頂點
    EdgeList pp;//鏈接邊 
    
    //給頂點賦值
    p->vexs[a].vertex = a;
    //如果指向NON望艺,則說明是最后一個節(jié)點
    if (b == NON)
    {
        p->vexs[a].edgelist = NULL;
        return;
    }

    PEdgeNode temp;//邊的節(jié)點
    temp = (PEdgeNode)malloc(sizeof(EdgeNode));
    temp->endvex = b;
    temp->nextedge = NULL;
    pp = p->vexs[a].edgelist;//將連接邊復制給pp

    if (pp == NULL)//連接兩個頂點
        p->vexs[a].edgelist = temp;
    else {//將新邊連接到后邊
        while (pp->nextedge != NULL)
            pp = pp->nextedge;
        pp->nextedge = temp;
    }
}

咳咳苛秕,現(xiàn)在開始拓撲排序了。

  1. 輸出頂點入度為0的值
    首先你得找到哪些點入度為0(統(tǒng)計入度)
    /*統(tǒng)計入度*/
    Indegree = (int *)malloc(GL->n * sizeof(int));//存儲入度
    for (i = 0; i<GL->n; i++)
        Indegree[i] = 0;
    for (i = 0; i < GL->n; i++)
    {
        EdgeList p = GL->vexs[i].edgelist;
        while (p != NULL)
        {
            Indegree[p->endvex]++;
            p = p->nextedge;
        }
    }//所有點的入度已經(jīng)存儲完畢
        ```
  然后就把入度為0的頂點揪出來吧**(入度為0的揪出來放到stack里面)**

for (j = 0; j < GL->n; j++)//初始化stack棧
{
stack[j] = -1;
}
/*
*將入度為0的節(jié)點入棧
*/
for (i = 0; i < GL->n; i++)
{
if (Indegree[i] == 0)
{
stack[top] = i;
top++;
}
}
top--;//top在執(zhí)行完之后多加了一個

終于可以輸出入度為0的點了吧找默。

printf("%d ", GL->vexs[gettop].vertex);//輸出頂點自身

只有一句話嗎艇劫?
2. 讓已經(jīng)輸出的頂點就消失吧。

//輸出頂點信息以后減少相應鏈接點的入度惩激,標志著這個點從此消失
Indegree[GL->vexs[gettop].edgelist->endvex]--;
e = GL->vexs[gettop].edgelist->nextedge;
while (e != NULL)
{
Indegree[e->endvex]--;
e = e->nextedge;
}

當看到這里的時候店煞,就應該想如果最后一個頂點也這樣輸出的話,就會出現(xiàn)內(nèi)存泄露了风钻,所以當?shù)阶詈笠粋€頂點的時候浅缸,就特殊處理吧。

####然后通過循環(huán)就可以進行拓撲排序啦魄咕,別忘了用一個計數(shù)器來記錄輸出的個數(shù),最后通過輸出的個數(shù)來判斷是否能進行拓撲排序蚌父。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末哮兰,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子苟弛,更是在濱河造成了極大的恐慌喝滞,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,324評論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件膏秫,死亡現(xiàn)場離奇詭異右遭,居然都是意外死亡,警方通過查閱死者的電腦和手機缤削,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,356評論 3 392
  • 文/潘曉璐 我一進店門窘哈,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人亭敢,你說我怎么就攤上這事滚婉。” “怎么了帅刀?”我有些...
    開封第一講書人閱讀 162,328評論 0 353
  • 文/不壞的土叔 我叫張陵让腹,是天一觀的道長远剩。 經(jīng)常有香客問我,道長骇窍,這世上最難降的妖魔是什么瓜晤? 我笑而不...
    開封第一講書人閱讀 58,147評論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮腹纳,結(jié)果婚禮上痢掠,老公的妹妹穿的比我還像新娘。我一直安慰自己只估,他們只是感情好志群,可當我...
    茶點故事閱讀 67,160評論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著蛔钙,像睡著了一般锌云。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上吁脱,一...
    開封第一講書人閱讀 51,115評論 1 296
  • 那天桑涎,我揣著相機與錄音,去河邊找鬼兼贡。 笑死攻冷,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的遍希。 我是一名探鬼主播等曼,決...
    沈念sama閱讀 40,025評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼凿蒜!你這毒婦竟也來了禁谦?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,867評論 0 274
  • 序言:老撾萬榮一對情侶失蹤废封,失蹤者是張志新(化名)和其女友劉穎州泊,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體漂洋,經(jīng)...
    沈念sama閱讀 45,307評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡遥皂,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,528評論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了刽漂。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片演训。...
    茶點故事閱讀 39,688評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖贝咙,靈堂內(nèi)的尸體忽然破棺而出仇祭,到底是詐尸還是另有隱情,我是刑警寧澤颈畸,帶...
    沈念sama閱讀 35,409評論 5 343
  • 正文 年R本政府宣布乌奇,位于F島的核電站没讲,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏礁苗。R本人自食惡果不足惜爬凑,卻給世界環(huán)境...
    茶點故事閱讀 41,001評論 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望试伙。 院中可真熱鬧嘁信,春花似錦、人聲如沸疏叨。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,657評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽蚤蔓。三九已至卦溢,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間秀又,已是汗流浹背单寂。 一陣腳步聲響...
    開封第一講書人閱讀 32,811評論 1 268
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留吐辙,地道東北人宣决。 一個月前我還...
    沈念sama閱讀 47,685評論 2 368
  • 正文 我出身青樓,卻偏偏與公主長得像昏苏,于是被迫代替她去往敵國和親尊沸。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,573評論 2 353