(原創(chuàng))不過如此的 DFS 深度優(yōu)先遍歷

DFS 深度優(yōu)先遍歷?


DFS算法用于遍歷圖結(jié)構(gòu)蹦疑,旨在遍歷每一個(gè)結(jié)點(diǎn)西雀,顧名思義,這種方法把遍歷的重點(diǎn)放在深度上歉摧,什么意思呢艇肴?就是在訪問過的結(jié)點(diǎn)做標(biāo)記的前提下,一條路走到天黑叁温,我們都知道當(dāng)每一個(gè)結(jié)點(diǎn)都有很多分支再悼,那么我們的小人就沿著每一個(gè)結(jié)點(diǎn)走,定一個(gè)標(biāo)準(zhǔn)券盅,比如優(yōu)先走右手邊的路帮哈,然后在到達(dá)下一個(gè)結(jié)點(diǎn)前先敲敲門,當(dāng)一個(gè)結(jié)點(diǎn)的所有門都被敲了個(gè)遍都標(biāo)記過锰镀,那么就走回頭路,再重復(fù)敲門咖刃,直到返回起點(diǎn)泳炉,這樣的方式我們叫做 DFS 深度優(yōu)先遍歷,本文以圖結(jié)構(gòu)講解嚎杨,例子取自《大話數(shù)據(jù)結(jié)構(gòu)》花鹅。

如我剛才所講,從A點(diǎn)出發(fā)枫浙,將路徑畫出來就是以下效果刨肃。

實(shí)線是走過的路程,虛線就是我們的小人敲門然后發(fā)現(xiàn)標(biāo)記過的一個(gè)過程箩帚,大家可以寄幾模擬一哈真友。一句話總結(jié)就是:

從圖中某個(gè)頂點(diǎn) v 出發(fā),訪問此頂點(diǎn)紧帕,然后從 v 的未被訪問的鄰接點(diǎn)出發(fā) 深度優(yōu)先遍歷圖結(jié)構(gòu)盔然,直至圖中所有和 v 有路徑相通的頂點(diǎn)都被訪問到桅打。


結(jié)構(gòu)定義代碼:

typedefchar VertexType;

typedef int EdgeType;#defineMAXVEX 10#defineINFINITY 65535typedef int boolean;

boolean visited[MAXVEX];

typedef struct{

? ? VertexType vexs[MAXVEX];

? ? EdgeType arc[MAXVEX][MAXVEX];

? ? intnumVertexes,numEdges;}MGraph;

鄰接矩陣創(chuàng)建:


voidCreateMGraph(MGraph *G)

{

? ? int i,j,k;

? ? printf("請(qǐng)輸入頂點(diǎn)數(shù)和邊數(shù)(空格隔開)\n");

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

? ? printf("請(qǐng)依次輸入每個(gè)頂點(diǎn)的內(nèi)容:\n");

? ? for(i =0;i < G->numVertexes;i++)

? ? {

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

? ? }

? ? for(i =0;i < G->numVertexes;i++)

? ? {

? ? ? ? for(j =0;j < G->numVertexes;j++)

? ? ? ? {

? ? ? ? ? ? G->arc[i][j] = INFINITY;

? ? ? ? }

? ? }

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

? ? {

? ? ? ? printf("輸入邊(vi,vj)上的下標(biāo)i,下標(biāo)j:\n");

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

? ? ? ? G->arc[i][j] =1;

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

? ? }

}

DFS算法


voidDFS(MGraph G,int i) //深度優(yōu)先遞歸算法

{

? ? int j;

? ? visited[i] =1;

? ? printf("%c",G.vexs[i]);

? ? for(j =0;j < G.numVertexes;j++)

? ? {

? ? ? ? if(G.arc[i][j] ==1&& !visited[j])

? ? ? ? ? ? DFS(G,j);

? ? }

}void DFStraverse(MGraph G)? //深度遍歷

{

? ? int i;

? ? for(i =0;i < G.numVertexes;i++)

? ? visited[i] =0;

? ? for(i =0;i < G.numVertexes;i++)

? ? {

? ? ? ? if(!visited[i])

? ? ? ? ? ? DFS(G,i);

? ? }

}

這種方法比較好理解在于使用循環(huán)進(jìn)入函數(shù)再遞歸愈案,可以保證以鄰接矩陣為儲(chǔ)存單位的每一個(gè)格子都被遍歷到挺尾,且做好標(biāo)注,那么用鄰接矩陣的DFS算法時(shí)間復(fù)雜度可以想見是 O(n2)

我們來看下一種實(shí)現(xiàn)方式站绪,這次我們使用的是鄰接單鏈表

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


typedefint boolean;

boolean visited[MAXVEX];

typedef char VertexType;

typedef int EdgeType;#defineMAXVEX 10#defineINFINITY 65535typedef struct EdgeNode //邊表結(jié)構(gòu)點(diǎn)

{

? ? int adjvex;

? ? structEdgeNode *next;

}EdgeNode;

typedef struct VertexNode //頂點(diǎn)表結(jié)構(gòu)點(diǎn)

{

? ? VertexType data;

? ? EdgeNode *firstedge;

}VertexNode,AdjList[MAXVEX];

typedef struct //總表結(jié)構(gòu)

{

? ? AdjList adjList;

? ? int numVertexes,numEdges;

}GraphAdjList;

比鄰接矩陣復(fù)雜一點(diǎn)遭铺,但是其結(jié)構(gòu)只有三種,總表恢准、定點(diǎn)表和邊表

創(chuàng)建:


voidCreateALGraph(GraphAdjList *G)

{

? ? int i,j,k;

? ? EdgeNode *e;

? ? printf("請(qǐng)輸入頂點(diǎn)數(shù)和邊數(shù)(空格隔開)\n");

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

? ? for(i =0;i < G->numVertexes;i++)

? ? {

? ? ? ? scanf("%c",&G->adjList[i].data);

? ? ? ? G->adjList[i].firstedge = NULL;

? ? }

? ? for(k =0;k < G->numVertexes;k++)

? ? {

? ? ? ? printf("輸入邊(vi,vj)上的下標(biāo)i魂挂,下標(biāo)j:\n");

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

? ? ? ? e = (EdgeNode*)malloc(sizeof(EdgeNode));

? ? ? ? e->adjvex=i;

? ? ? ? e->next = adjList[j].firstedge;

? ? ? ? adjList[j].firstedge = e;


? ? ? ? e = (EdgeNode*)malloc(sizeof(EdgeNode));

? ? ? ? e->adjvex=j;

? ? ? ? e->next = adjList[i].firstedge;

? ? ? ? adjList[i].firstedge = e;

? ? }

}

DFS算法實(shí)現(xiàn):


voidDFS(GraphAdjList GL,int i)

{

? ? EdgeNode *p;

? ? visited[i] =1;

? ? printf("%c",GL->adjList[i].data);

? ? while(p)

? ? {

? ? ? ? if(!visited[p->adjvex])

? ? ? ? ? ? DFS(GL,p->adjvex);

? ? ? ? p = p->next;

? ? }

}void DFStraverse(GraphAdjList GL)

{

? ? int i;

? ? for(i =0;i < GL->numVertexes;i++)

? ? visited[i] =0;

? ? for(i =0;i < GL->numVertexes;i++)

? ? {

? ? ? ? if(!visited[i])

? ? ? ? ? ? DFS(GL,i);

? ? }

}

利用鄰接表的方式能夠?qū)崿F(xiàn)相同效果的遍歷,同時(shí)這種方法的算法時(shí)間復(fù)雜度為 O(n+e)

顯然對(duì)于點(diǎn)多邊少的稀疏圖來說顷歌,鄰接表結(jié)構(gòu)使得算法在時(shí)間效率上大大提高锰蓬。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市眯漩,隨后出現(xiàn)的幾起案子芹扭,更是在濱河造成了極大的恐慌,老刑警劉巖赦抖,帶你破解...
    沈念sama閱讀 222,865評(píng)論 6 518
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件舱卡,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡队萤,警方通過查閱死者的電腦和手機(jī)轮锥,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,296評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來要尔,“玉大人舍杜,你說我怎么就攤上這事≌栽” “怎么了既绩?”我有些...
    開封第一講書人閱讀 169,631評(píng)論 0 364
  • 文/不壞的土叔 我叫張陵,是天一觀的道長还惠。 經(jīng)常有香客問我饲握,道長,這世上最難降的妖魔是什么蚕键? 我笑而不...
    開封第一講書人閱讀 60,199評(píng)論 1 300
  • 正文 為了忘掉前任救欧,我火速辦了婚禮,結(jié)果婚禮上锣光,老公的妹妹穿的比我還像新娘笆怠。我一直安慰自己,他們只是感情好嫉晶,可當(dāng)我...
    茶點(diǎn)故事閱讀 69,196評(píng)論 6 398
  • 文/花漫 我一把揭開白布骑疆。 她就那樣靜靜地躺著田篇,像睡著了一般。 火紅的嫁衣襯著肌膚如雪箍铭。 梳的紋絲不亂的頭發(fā)上泊柬,一...
    開封第一講書人閱讀 52,793評(píng)論 1 314
  • 那天,我揣著相機(jī)與錄音诈火,去河邊找鬼兽赁。 笑死,一個(gè)胖子當(dāng)著我的面吹牛冷守,可吹牛的內(nèi)容都是我干的刀崖。 我是一名探鬼主播,決...
    沈念sama閱讀 41,221評(píng)論 3 423
  • 文/蒼蘭香墨 我猛地睜開眼拍摇,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼亮钦!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起充活,我...
    開封第一講書人閱讀 40,174評(píng)論 0 277
  • 序言:老撾萬榮一對(duì)情侶失蹤蜂莉,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后混卵,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體映穗,經(jīng)...
    沈念sama閱讀 46,699評(píng)論 1 320
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,770評(píng)論 3 343
  • 正文 我和宋清朗相戀三年幕随,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了蚁滋。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,918評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡赘淮,死狀恐怖辕录,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情梢卸,我是刑警寧澤踏拜,帶...
    沈念sama閱讀 36,573評(píng)論 5 351
  • 正文 年R本政府宣布,位于F島的核電站低剔,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏肮塞。R本人自食惡果不足惜襟齿,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,255評(píng)論 3 336
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望枕赵。 院中可真熱鬧猜欺,春花似錦、人聲如沸拷窜。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,749評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至赋荆,卻和暖如春笋妥,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背窄潭。 一陣腳步聲響...
    開封第一講書人閱讀 33,862評(píng)論 1 274
  • 我被黑心中介騙來泰國打工春宣, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人嫉你。 一個(gè)月前我還...
    沈念sama閱讀 49,364評(píng)論 3 379
  • 正文 我出身青樓月帝,卻偏偏與公主長得像,于是被迫代替她去往敵國和親幽污。 傳聞我的和親對(duì)象是個(gè)殘疾皇子嚷辅,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,926評(píng)論 2 361

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

  • 圖的定義與術(shù)語 1、圖按照有無方向分為無向圖和有向圖距误。無向圖由頂點(diǎn)和邊構(gòu)成簸搞,有向圖由頂點(diǎn)和弧構(gòu)成∩盍龋弧有弧尾和弧頭之...
    unravelW閱讀 411評(píng)論 0 0
  • 在C語言中,五種基本數(shù)據(jù)類型存儲(chǔ)空間長度的排列順序是: A)char B)char=int<=float C)ch...
    夏天再來閱讀 3,352評(píng)論 0 2
  • 第1章 第一個(gè)C程序第2章 C語言基礎(chǔ)第3章 變量和數(shù)據(jù)類型第4章 順序結(jié)構(gòu)程序設(shè)計(jì)第5章 條件結(jié)構(gòu)程序設(shè)計(jì)第6章...
    小獅子365閱讀 10,681評(píng)論 3 71
  • 在溧陽的書店偶遇了一本小書惋鹅,書名叫《遇上砰然心動(dòng)的書店》则酝。書中的書店或個(gè)性張揚(yáng),或激情四射闰集,或靜如處子沽讹,或害羞待放...
    古宏昌閱讀 160評(píng)論 0 0
  • 原創(chuàng): 銳老師加油 銳語空間 昨天 學(xué)生最愛是假期爽雄,假期悠游,假期歡愉沐鼠,假期更應(yīng)充實(shí)有收獲挚瘟。銳老師是出了名...
    銳小哥閱讀 343評(píng)論 0 1