數(shù)據(jù)結(jié)構(gòu)——圖的最短路徑 dijkstra算法

算法的思想如下:
規(guī)定一個 出發(fā)點宙攻,然后先初始化距離數(shù)組彻亲。數(shù)組中的每個下標(biāo)就對應(yīng)一個結(jié)點兵拢,每個數(shù)據(jù)項就是出發(fā)點到每個結(jié)點的距離翻斟。
1:將一個集合分為兩部分,一個是已經(jīng)找過的結(jié)點U卵佛,一個是沒有找到過的v

2:在距離的數(shù)組中杨赤,沒有訪問過的結(jié)點中找一個權(quán)重最小的邊敞斋,然后將這個結(jié)點添加到u中截汪,并且以這個結(jié)點作為中間結(jié)點,來更新數(shù)組植捎,判斷條件是i到temp+temp到j(luò) 的距離是不是小于i到j(luò)的距離衙解,若是,則就要更新焰枢。

3:直到u中的結(jié)點的個數(shù)=圖中的結(jié)點的個數(shù)
算法的實現(xiàn)其實還是比較簡單蚓峦,和prim算法圖的prim算法沒什么差別,都是維護(hù)一個距離數(shù)組济锄,來更新數(shù)組暑椰,不同的是只是添加一個判斷條件而已。荐绝,在這里就沒什么可說的一汽,不懂的分析程序,運行結(jié)果一兩遍就基本明白了
程序如下:

//
//  main.cpp
//  dijkstra
//
//  Created by 橘子和香蕉 on 2018/12/2.
//  Copyright ? 2018 橘子和香蕉. All rights reserved.
//
/*
 
 其實思想和之前的prim算法一樣,還是分為兩個集合召夹,一個是訪問過的u岩喷,一個是訪問過的v,找一個中間結(jié)點监憎,判斷 i到j(luò)的距離和i到temp+demp到j(luò)的距離那個短纱意,更新就好。
 還是要維護(hù)一個距離的數(shù)組鲸阔,在沒有訪問過的結(jié)點中每次找一個最小的邊偷霉,同時也就是找到了v的結(jié)點,添加到u中褐筛,然后以這個結(jié)點為中間結(jié)點來更新距離數(shù)組腾它,判斷i到j(luò)的距離和i到temp+demp到j(luò)的距離,
 f
 */
#include <iostream>
using namespace std;
#define MAX 9999//用9999來表示不可到達(dá)死讹。為什么不用之前的INT_MAX瞒滴,因為在之后的距離的更新會產(chǎn)生問題。INT_MAX是int的最大值赞警,在加就會導(dǎo)致胃負(fù)數(shù)妓忍,這就產(chǎn)生了問題
typedef struct node{
    char  data;//數(shù)據(jù)域
    int isAccess;//用來標(biāo)記是否被訪問過
}node;
#define VERTEXNUM 100
class Graph{
private:
    node  vertex[VERTEXNUM];//頂點表
    int edge[VERTEXNUM][VERTEXNUM];//邊表
    int vertexNum;//頂點個數(shù)
    int edgeNum;//邊的個數(shù)
    
    
    
    int locate(char  data);//在頂點表中找data的位置
    void initEdge();
    
public:
    Graph(int vertexNum,int edgeNum);
    void create();
    void dijkstra(char data);
    void printGraph();//輸出
};

void Graph::printGraph(){
    cout<<endl;
    cout<<endl;
    cout<<"頂點邊:\n";
    cout<<"vertexNum:"<<vertexNum<<" edgeNum:"<<edgeNum<<endl;
    for (int i = 0; i<vertexNum; i++) {
        cout<<vertex[i].data<<"\t";
    }
    cout<<endl;
    cout<<"邊表如下:\n";
    
    for (int j = 0; j<vertexNum; j++) {
        for (int k = 0; k<vertexNum ; k++) {
            cout<<edge[j][k]<<"\t";
        }
        cout<<endl;
    }
}

int Graph::locate(char  data){
    for (int i  = 0; i<vertexNum;i++) {
        if(vertex[i].data == data){
            return I;
        }
    }
    return -1;
}
Graph::Graph(int vertexNum,int edgeNum){
    this->vertexNum = vertexNum;
    this->edgeNum = edgeNum;
    initEdge();
}
void Graph::create(){
    cout<<"input Graph data\n";
    for (int i = 0; i<vertexNum; i++) {
        cin>>vertex[i].data;
        vertex[i].isAccess = false;
    }
    char start ,end;
    int wieght = -1;
    for (int j = 0; j<edgeNum; j++) {
        
        cout<<"input start and end of edge:\n";
        cin>>start>>end>>wieght;
        int startPosition = locate(start);
        int endPosition = locate(end);
        edge[startPosition][endPosition] = wieght;
        edge[endPosition][startPosition] = wieght;
    }
    
}
void Graph:: initEdge(){
    for (int i = 0;  i<vertexNum; i++) {
        for (int j =0 ; j<=i; j++) {
            edge[i][j] = MAX;
            edge[j][i] = MAX;
        }
    }
}
void Graph::dijkstra(char data){
    int distince[100];//定義一個中間數(shù)組
    int temp = -1;//定義中間結(jié)點
    
    int position = locate(data);
    
    vertex[position].isAccess = true;
    
    //初始化distince數(shù)組
    for (int i = 0; i<vertexNum; i++) {
        if( edge[position][i] < MAX ){
            distince[i] = edge[position][I];
        }else{
            distince[i] = MAX;
        }
    }
    
   
    
    int minVertexNum = 0;//定義結(jié)點個數(shù)
    while (minVertexNum != vertexNum-1) {
        int min = MAX;
        for (int i = 0; i<vertexNum; i++) {
            if( vertex[i].isAccess == false && distince[i] < min){
                min = distince[I];
                temp = I;
            }
        }
        vertex[temp].isAccess = true;
        for (int i = 0; i<vertexNum; i++) {
            if((vertex[i].isAccess == false) && ( distince[temp]+edge[temp][i] < distince[i]) ){
                distince[i] = distince[temp]+edge[temp][I];
            }
        }
        
        
        
        
        
        minVertexNum++;
    }
    cout<<"到每個結(jié)點的最短距離如下"<<endl;
    for (int i  = 0; i<vertexNum; i++) {
        cout<<vertex[i].data<<":"<<distince[i]<<"\n";
    }
    
    
}
int main(){
    Graph a(6,8);
    a.create();
    a.printGraph();
    cout<<endl;
    a.dijkstra('1');
    return 1;
}

測試的圖如下:
在這里用的是臨接矩陣來實現(xiàn)無向圖;


image.png

運行結(jié)果如下:


image.png
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末愧旦,一起剝皮案震驚了整個濱河市世剖,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌笤虫,老刑警劉巖旁瘫,帶你破解...
    沈念sama閱讀 212,718評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異琼蚯,居然都是意外死亡酬凳,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,683評論 3 385
  • 文/潘曉璐 我一進(jìn)店門遭庶,熙熙樓的掌柜王于貴愁眉苦臉地迎上來宁仔,“玉大人,你說我怎么就攤上這事峦睡◆嵘唬” “怎么了?”我有些...
    開封第一講書人閱讀 158,207評論 0 348
  • 文/不壞的土叔 我叫張陵榨了,是天一觀的道長煎谍。 經(jīng)常有香客問我,道長龙屉,這世上最難降的妖魔是什么呐粘? 我笑而不...
    開封第一講書人閱讀 56,755評論 1 284
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上事哭,老公的妹妹穿的比我還像新娘漫雷。我一直安慰自己,他們只是感情好鳍咱,可當(dāng)我...
    茶點故事閱讀 65,862評論 6 386
  • 文/花漫 我一把揭開白布降盹。 她就那樣靜靜地躺著,像睡著了一般谤辜。 火紅的嫁衣襯著肌膚如雪蓄坏。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 50,050評論 1 291
  • 那天丑念,我揣著相機(jī)與錄音涡戳,去河邊找鬼。 笑死脯倚,一個胖子當(dāng)著我的面吹牛渔彰,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播推正,決...
    沈念sama閱讀 39,136評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼恍涂,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了植榕?” 一聲冷哼從身側(cè)響起再沧,我...
    開封第一講書人閱讀 37,882評論 0 268
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎尊残,沒想到半個月后炒瘸,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,330評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡寝衫,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,651評論 2 327
  • 正文 我和宋清朗相戀三年顷扩,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片竞端。...
    茶點故事閱讀 38,789評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡屎即,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出事富,到底是詐尸還是另有隱情,我是刑警寧澤乘陪,帶...
    沈念sama閱讀 34,477評論 4 333
  • 正文 年R本政府宣布统台,位于F島的核電站,受9級特大地震影響啡邑,放射性物質(zhì)發(fā)生泄漏贱勃。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 40,135評論 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望贵扰。 院中可真熱鬧仇穗,春花似錦、人聲如沸戚绕。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,864評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽舞丛。三九已至耘子,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間球切,已是汗流浹背谷誓。 一陣腳步聲響...
    開封第一講書人閱讀 32,099評論 1 267
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留吨凑,地道東北人捍歪。 一個月前我還...
    沈念sama閱讀 46,598評論 2 362
  • 正文 我出身青樓,卻偏偏與公主長得像鸵钝,于是被迫代替她去往敵國和親费封。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,697評論 2 351

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