Dijikstra和Bellman_ford算法

算法實現(xiàn)思路:

Dijkstra算法

預(yù)處理:將所有的節(jié)點除開始節(jié)點的訪問位置為零表示沒有找到大該節(jié)點的最短路徑,用一個初始化為無窮大的距離數(shù)組存放到已經(jīng)找到節(jié)點到未找到節(jié)點的距離的最小值颗圣,具體為:剛開始時候存放起始節(jié)點到其相鄰節(jié)點的距離值,若節(jié)點不可達則記為無窮大,后續(xù)每次找到一個節(jié)點開始修改這個數(shù)組中的值,看看經(jīng)過這個節(jié)點中轉(zhuǎn)到達其余節(jié)點距離是不是更小焕济,修改節(jié)點的時候順便記錄修改前的前驅(qū)節(jié)點,這樣方便最后輸出找到的路徑盔几。每一次找到節(jié)點就修改距離數(shù)組中的值晴弃,再找距離數(shù)組中的最小的值,將最小值對應(yīng)的節(jié)點的訪問為置為一表示找到該節(jié)點的最短路徑,如此循環(huán)

bellmen_ford算法的實現(xiàn)思路:

第一上鞠,初始化所有點际邻。每一個點保存一個值,表示從原點到達這個點的距離芍阎,將原點的值設(shè)為0世曾,其它的點的值設(shè)為無窮大(表示不可達)。
第二谴咸,進行循環(huán)轮听,循環(huán)下標(biāo)為從1到n-1(n等于圖中點的個數(shù))。在循環(huán)內(nèi)部岭佳,遍歷所有的邊血巍,進行松弛計算。

算法實現(xiàn):

# include <stdio.h>

#define INFINITY 9999
#define MAX 10

typedef struct Edge {
    int s;
    int e;
    int v;
}Edge;

Bellman_ford算法實現(xiàn):

void bellmen_ford(Edge edge[MAX], int vnum, int edgenum, int startnode)
{
    int dist[MAX];
    int pred[MAX];
    int i, j;
    // 第一步初始化
    for (int i = 0; i < vnum; i++)
    {

        dist[i] = INFINITY;
        pred[i] = startnode;
    }
    dist[startnode] = 0;

    for (int k = 0; k < vnum - 1; k++)//循環(huán)k-1次 
    {
        for (int i = 0; i < edgenum; i++)//循環(huán)每條邊
        {
            if (dist[edge[i].e] > dist[edge[i].s] + edge[i].v)
            {//如果起點 s 的距離加上邊的權(quán)值 v 小于終點 e 的距離珊随,則更新終點 e 的距離值 d
                dist[edge[i].e] = dist[edge[i].s] + edge[i].v;
                pred[edge[i].e] = edge[i].s;//到e點經(jīng)過s點 
            }
        }
    }

    for (int i = 0; i < vnum; i++)
        if (i != startnode)
        {
            if (dist[i] == INFINITY)
                printf("\n到達V[%d]節(jié)點的路徑長度 = ∞", i);
            else
                printf("\n到達V[%d]節(jié)點的路徑長度 = %d", i, dist[i]);

            if (dist[i] != INFINITY)
            {
                printf("\n路徑 : V[%d]", i);
                j = i;
                do
                {
                    j = pred[j];
                    printf("  <<<<  V[%d]", j);
                } while (j != startnode);
            }
            else
            {
                printf("\n終點不可達");
            }
            printf("\n");
        }



}

Dijikstra算法實現(xiàn):

void dijikstra(int G[MAX][MAX], int n, int startnode)
{
    int cost[MAX][MAX], distance[MAX], pred[MAX];
    int visited[MAX], count, mindistance, nextnode, i, j;
    //對鄰接矩陣進行初步的處理述寡,將0變成無窮大
    for (i = 0; i < n; i++)
        for (j = 0; j < n; j++)
            if (G[i][j] == 0)
                cost[i][j] = INFINITY;
            else
                cost[i][j] = G[i][j];

    //初始化距離數(shù)組
    for (i = 0; i < n; i++)
    {
        distance[i] = cost[startnode][i];
        pred[i] = startnode;
        visited[i] = 0;
    }
    distance[startnode] = 0;
    visited[startnode] = 1;
    count = 1;
    while (count < n - 1)
    {
        mindistance = INFINITY;
        for (i = 0; i < n; i++)//找到相鄰的最小距離的哪個節(jié)點
            if (distance[i] < mindistance && !visited[i])
            {
                mindistance = distance[i];
                nextnode = i;
            }
        visited[nextnode] = 1;
        for (i = 0; i < n; i++)//修改存放最小距離的數(shù)組并修改前驅(qū)
            if (!visited[i])
                if (mindistance + cost[nextnode][i] < distance[i]) {
                    distance[i] = mindistance + cost[nextnode][i];
                    pred[i] = nextnode;
                }
        count++;
    }

    //輸出路徑
    for (i = 0; i < n; i++)
        if (i != startnode)
        {
            if (distance[i] == INFINITY)
                printf("\n到達V[%d]節(jié)點的路徑長度 = ∞", i);
            else
                printf("\n到達V[%d]節(jié)點的路徑長度 = %d", i, distance[i]);

            if (distance[i] != INFINITY)
            {
                printf("\n路徑 : V[%d]", i);
                j = i;
                do
                {
                    j = pred[j];
                    printf("  <<<<  V[%d]", j);
                } while (j != startnode);
            }
            else
            {
                printf("\n終點不可達");
            }
            printf("\n");
        }

}

主函數(shù):

int main()
{
    int vnum, edgenum, startnode;
    int G[MAX][MAX];
    int start, end, value;
    Edge edge[MAX];
    printf("輸入圖的 頂點數(shù) 和 邊數(shù):");
    scanf("%d %d", &vnum, &edgenum);

    for (int i = 0; i < vnum; i++)
        for (int j = 0; j < vnum; j++)
        {
            if (i == j)
                G[i][j] = 0;
            else
                G[i][j] = INFINITY;
        }

    printf("輸入每條變的 起點 終點 以及其 權(quán)重:\n");
    for (int k = 0; k < edgenum; k++)
    {
        printf("(%d): ", k + 1);
        scanf("%d %d %d", &start, &end, &value);
        printf("\n");
        G[start][end] = value;
        edge[k].s = start;
        edge[k].e = end;
        edge[k].v = value;
    }
    printf("鄰接矩陣是:\n");
    for (int i = 0; i < vnum; i++)
    {
        for (int j = 0; j < vnum; j++)
        {
            if (G[i][j] == INFINITY)
                printf("∞\t");
            else
                printf("%d\t", G[i][j]);
        }
        printf("\n");
    }
    printf("\n輸入起始的頂點\t");
    scanf("%d", &startnode);
    printf("\n##################Dijikstra######################\n");
    dijikstra(G, vnum, startnode);

    printf("\n################Bellmen_Ford#####################\n");
    bellmen_ford(edge, vnum, edgenum, startnode);
    system("pause");
}

輸入:

輸入?yún)?shù)

輸出鄰接矩陣:

鄰接矩陣

開始輸入起始節(jié)點:

這里選擇將零作為起始節(jié)點

輸出結(jié)果:

輸出結(jié)果

將所有代碼拷到一個文件中就可以運行

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市叶洞,隨后出現(xiàn)的幾起案子鲫凶,更是在濱河造成了極大的恐慌,老刑警劉巖京办,帶你破解...
    沈念sama閱讀 219,427評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件掀序,死亡現(xiàn)場離奇詭異,居然都是意外死亡惭婿,警方通過查閱死者的電腦和手機不恭,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,551評論 3 395
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來财饥,“玉大人换吧,你說我怎么就攤上這事≡啃牵” “怎么了沾瓦?”我有些...
    開封第一講書人閱讀 165,747評論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長谦炒。 經(jīng)常有香客問我贯莺,道長,這世上最難降的妖魔是什么宁改? 我笑而不...
    開封第一講書人閱讀 58,939評論 1 295
  • 正文 為了忘掉前任缕探,我火速辦了婚禮,結(jié)果婚禮上还蹲,老公的妹妹穿的比我還像新娘爹耗。我一直安慰自己耙考,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,955評論 6 392
  • 文/花漫 我一把揭開白布潭兽。 她就那樣靜靜地躺著倦始,像睡著了一般。 火紅的嫁衣襯著肌膚如雪山卦。 梳的紋絲不亂的頭發(fā)上鞋邑,一...
    開封第一講書人閱讀 51,737評論 1 305
  • 那天,我揣著相機與錄音账蓉,去河邊找鬼炫狱。 笑死,一個胖子當(dāng)著我的面吹牛剔猿,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播嬉荆,決...
    沈念sama閱讀 40,448評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼归敬,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了鄙早?” 一聲冷哼從身側(cè)響起汪茧,我...
    開封第一講書人閱讀 39,352評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎限番,沒想到半個月后舱污,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,834評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡弥虐,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,992評論 3 338
  • 正文 我和宋清朗相戀三年扩灯,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片霜瘪。...
    茶點故事閱讀 40,133評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡珠插,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出颖对,到底是詐尸還是另有隱情捻撑,我是刑警寧澤,帶...
    沈念sama閱讀 35,815評論 5 346
  • 正文 年R本政府宣布缤底,位于F島的核電站顾患,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏个唧。R本人自食惡果不足惜江解,卻給世界環(huán)境...
    茶點故事閱讀 41,477評論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望坑鱼。 院中可真熱鬧膘流,春花似錦絮缅、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,022評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至彭谁,卻和暖如春吸奴,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背缠局。 一陣腳步聲響...
    開封第一講書人閱讀 33,147評論 1 272
  • 我被黑心中介騙來泰國打工则奥, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人狭园。 一個月前我還...
    沈念sama閱讀 48,398評論 3 373
  • 正文 我出身青樓读处,卻偏偏與公主長得像,于是被迫代替她去往敵國和親唱矛。 傳聞我的和親對象是個殘疾皇子罚舱,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,077評論 2 355

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