国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

dijkstra迪杰斯特拉算法(鄰接表法)

這篇具有很好參考價(jià)值的文章主要介紹了dijkstra迪杰斯特拉算法(鄰接表法)。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

算法簡易過程:

  •  迪杰斯特拉算法(樸素) O(n^2)
    G={V,E}   V:點(diǎn)集合   E:邊集合
    初始化時(shí) 令 S={某源點(diǎn)ear}, T=V-S= {其余頂點(diǎn)},T中頂點(diǎn)對應(yīng)的距離(ear, Vi)值
              若存在,d(ear,Vi)為弧上的權(quán)值, dist【i】
              若不存在,d(ear,Vi)為 無窮大, dist【i】
     循環(huán) n - 1次(n個(gè)點(diǎn)):
      1、從T中選取一個(gè)與S中頂點(diǎn) 有關(guān)聯(lián)邊 且 權(quán)值最小 的頂點(diǎn) pos,加入到 S中
          (這里使用 flag數(shù)組來確定 是否屬于 S集合,true為屬于)
          (等于是 每次 選取 T點(diǎn)集中 dist最小的頂點(diǎn) 作為 pos 加入 S,既 flag置為 true)
      2、對其余T中頂點(diǎn)Vi的距離值進(jìn)行修改:若加進(jìn) pos 作中間頂點(diǎn),從ear -> pos -> Vi 的距離值縮短,則 ??更新dist
          (等于是 找出所有 pos -> Vi 邊(有邊連接的), 再加上原來源ear -> pos 權(quán)重,對比dist數(shù)組,如果權(quán)重更小則更新 => 更新dist最短路徑長度,更新prev數(shù)組 更新前驅(qū)頂點(diǎn)為pos)

求單源有向圖最短路徑

使用鄰接表法來存儲頂點(diǎn)和邊,錄入有向圖。

(當(dāng)然也可以無向圖,不過錄入時(shí)要錄入兩次,比如 a b 3? ? ? ? b a 3)

dijkstra迪杰斯特拉算法(鄰接表法)

?代碼如下:

//
// Created by Giperx on 2022/11/27.
//
#include <iostream>
#include <vector>
#include <stack>
using namespace std;
#define INFINE 99999 // 定義最大
// 鄰接表
struct ArcNode // 邊信息
{
    int adjvex;//有向邊的 目標(biāo)頂點(diǎn) 下標(biāo)(從1開始)
    int weight;//邊的權(quán)值
    struct ArcNode *next; //鄰接表,指向下一個(gè)鄰接邊信息
};

struct VertexNode // 頂點(diǎn)
{
    int vertex;//頂點(diǎn)下標(biāo)(1 ~)
    ArcNode *firstedge;// 有向邊信息節(jié)點(diǎn)指針(源為vertex)
};

struct AdjList // 圖
{
    vector<VertexNode> adjlist;//頂點(diǎn)數(shù)組
    int vexnum;  //頂點(diǎn)數(shù) 
    int arcnum;  //邊數(shù)
};

// 圖的初始化
void createGraph(AdjList& G){
    cout << "輸入頂點(diǎn)數(shù) 邊數(shù):" << endl;
    cin >> G.vexnum >> G.arcnum;
    // 初始化G的頂點(diǎn)數(shù)組
    for(int i = 0; i <= G.vexnum; i ++){ // 下標(biāo)從1開始,所以初始化vexnum + 1個(gè)頂點(diǎn)(0無作用)
        VertexNode* tmp = new VertexNode;
        tmp->vertex = i, tmp->firstedge = nullptr;
        G.adjlist.emplace_back(*tmp);
    }
    //邊信息
    // n1:源頂點(diǎn)     n2:目標(biāo)頂點(diǎn)   we:權(quán)重(距離)
    int n1, n2, we;
    cout << "輸入邊信息:(a b we):" << endl; // a -> b  weight: we
    for(int i = 0; i < G.arcnum; i ++){
        cin >> n1 >> n2 >> we;
        // 初始化一個(gè)邊節(jié)點(diǎn),目標(biāo)頂點(diǎn)為n2
        ArcNode* tmp = new ArcNode;
        tmp->adjvex = n2, tmp->weight = we;
        // 頭插法 將邊信息節(jié)點(diǎn)插入
        // 節(jié)約時(shí)間(尾插要一直遍歷到尾部插入)
        tmp->next = G.adjlist[n1].firstedge;
        G.adjlist[n1].firstedge = tmp;
    }
}

// 獲取兩頂點(diǎn)之間權(quán)重weight(距離)
int getWeight(AdjList& G, int n1, int n2){
    if(n1 == n2) return 0;

    ArcNode* tmp = G.adjlist[n1].firstedge;
    while(tmp){
        if(tmp->adjvex == n2) return tmp->weight;
        tmp = tmp->next;
    }
    // 兩點(diǎn)之間沒有邊,返回INFINE
    return INFINE;
}

// 迪杰斯特拉算法(樸素)
//G={V,E}   V:點(diǎn)集合   E:邊集合
//初始化時(shí) 令 S={某源點(diǎn)ear}, T=V-S= {其余頂點(diǎn)},T中頂點(diǎn)對應(yīng)的距離(ear, Vi)值
//          若存在,d(ear,Vi)為弧上的權(quán)值, dist【i】
//          若不存在,d(ear,Vi)為 無窮大, dist【i】
// 循環(huán) n - 1次(n個(gè)點(diǎn)):
//  從T中選取一個(gè)與S中頂點(diǎn) 有關(guān)聯(lián)邊 且 權(quán)值最小 的頂點(diǎn) pos,加入到 S中
//      (這里使用 flag數(shù)組來確定 是否屬于 S集合,true為屬于)
//      (等于是 每次 選取 T點(diǎn)集中 dist最小的頂點(diǎn) 作為 pos 加入 S,既 flag置為 true)
//  對其余T中頂點(diǎn)Vi的距離值進(jìn)行修改:若加進(jìn) pos 作中間頂點(diǎn),從ear -> pos -> Vi 的距離值縮短,則 更新dist
//      (等于是 找出所有 pos -> Vi 邊(有邊連接的), 再加上原來源ear -> pos 權(quán)重,
//      對比dist數(shù)組,如果權(quán)重更小則更新 => 更新dist最短路徑長度,更新prev數(shù)組 更新前驅(qū)頂點(diǎn)為pos)
void Dijkstra(AdjList& G, int ear, vector<int>& prev, vector<int>& dist){
    // 初始化
    // flag數(shù)組記錄 某點(diǎn)是否納入已找到點(diǎn)集合
    // prev數(shù)組記錄 前驅(qū)頂點(diǎn)下標(biāo)
    // dist數(shù)組記錄 從源頂點(diǎn)ear 到 i頂點(diǎn)的最短路徑
    vector<bool> flag (G.adjlist.size() + 1, false);
    for(int i = 1; i <= G.vexnum; i ++) dist[i] = getWeight(G, ear, i), prev[i] = ear;
    flag[ear] = true, prev[ear] = 0;
    // 開始
    for(int i = 2; i <= G.vexnum; i ++){
        int pos = 1; // 未納入的距離最小的頂點(diǎn)
        int weiMin = INFINE;
        for(int j = 1; j <= G.vexnum; j ++){
            if(!flag[j] && dist[j] < weiMin){
                weiMin = dist[j], pos = j;
            }
        }

        flag[pos] = true;
        for(int j = 1; j <= G.vexnum; j ++){
            if(!flag[j]){ // 未納入點(diǎn)集中,找到pos到這些點(diǎn)的距離,與dist數(shù)組比較是否更新
                int tmpWei = getWeight(G, pos, j);
                if(tmpWei != INFINE) tmpWei = tmpWei + weiMin; // 兩點(diǎn)距離應(yīng)該為ear -> pos -> j
                if(tmpWei < dist[j]) {
                    dist[j] = tmpWei; // 距離更小則更新dist
                    prev[j] = pos; // 前頂點(diǎn)更新為pos
                }
            }
        }
    }

}

// 找路徑
void pathDist(vector<int>& prev, vector<int>& dist, int ear){
    // prev數(shù)組中為1有2種情況(djikstra初始化過程的時(shí)候全賦值為1,后續(xù)一直未改變):
    // 1:從ear到 頂點(diǎn) 只有 ear -> 頂點(diǎn) 這一條路最短
    // 2:無法從ear到達(dá)的頂點(diǎn)
    for(int i = 1; i <= prev.size() - 1; i ++){
        stack<int> trace;
        if(ear == i) continue;
        cout << ear << " 到 " << i ;
        // 無連通
        if(dist[i] == INFINE) {
            cout << "無連通" << endl;
            continue;
        }
        cout << "最短距離:" << dist[i] << "  最短路徑:";
        int tmp = i;
        while(tmp){ //  源頂點(diǎn)prev是0
            trace.push(tmp);
            tmp = prev[tmp];
        }
        // 開始出棧, 棧頂一定是ear源頂點(diǎn)
        cout << trace.top();
        trace.pop();
        while(!trace.empty()){
            cout << " -> " << trace.top();
            trace.pop();
        }
        cout << endl;
    }
}
int main(){
    AdjList G;
    createGraph(G);
    // prev數(shù)組記錄 前驅(qū)頂點(diǎn)下標(biāo)
    vector<int> prev (G.vexnum + 1, 0);
    // dist數(shù)組記錄 從源頂點(diǎn)ear 到 i頂點(diǎn)的最短路徑
    vector<int> dist (G.vexnum + 1, INFINE);
    // 從源點(diǎn)ear 出發(fā),到達(dá)其余所有點(diǎn)的最短路徑
    cout << "輸入源頂點(diǎn)ear:";
    int ear;
    cin >> ear;
    Dijkstra(G, ear,prev, dist);
    pathDist(prev, dist, ear);
//    for(int &x:prev) cout << x << ' ';
//    for(int &x:dist) cout << x << ' ';
    return 0;
}

測試如下:

dijkstra迪杰斯特拉算法(鄰接表法)

dijkstra迪杰斯特拉算法(鄰接表法)dijkstra迪杰斯特拉算法(鄰接表法)?文章來源地址http://www.zghlxwxcb.cn/news/detail-465239.html

到了這里,關(guān)于dijkstra迪杰斯特拉算法(鄰接表法)的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • C語言 最短路徑 迪杰斯特拉(Dijkstra)算法

    C語言 最短路徑 迪杰斯特拉(Dijkstra)算法

    迪杰斯特拉(Dijkstra)算法是由荷蘭計(jì)算機(jī)科學(xué)家狄克斯特拉于1959年提出的,因此又叫狄克斯特拉算法。是從一個(gè)頂點(diǎn)到其余各頂點(diǎn)的最短路徑算法,解決的是有權(quán)圖中單源最短路徑問題。迪杰斯特拉算法主要特點(diǎn)是從起始點(diǎn)開始,采用貪心算法的策略,每次遍歷到始點(diǎn)距離最

    2024年02月03日
    瀏覽(31)
  • 堆優(yōu)化版迪杰斯特拉(Dijkstra)算法簡單分析

    堆優(yōu)化版迪杰斯特拉(Dijkstra)算法簡單分析

    優(yōu)化原理: 上面的樸素版迪杰斯特拉算法主要缺陷是,每當(dāng)找到一個(gè)最短路徑,如果需要找下一個(gè)最短路徑,就需要在完成松弛操作之后,遍歷dist數(shù)組,尋找其中的最小值。遍歷dist數(shù)組的時(shí)間復(fù)雜度為O(n)。(dist數(shù)組儲存源點(diǎn)到各個(gè)點(diǎn)的當(dāng)前最短距離) 如果圖的邊數(shù)為n*(

    2023年04月08日
    瀏覽(24)
  • 【數(shù)據(jù)結(jié)構(gòu)】圖解:迪杰斯特拉算法(Dijkstra)最短路徑

    【數(shù)據(jù)結(jié)構(gòu)】圖解:迪杰斯特拉算法(Dijkstra)最短路徑

    目錄 一、方法描述 二、例題一 ??編輯 三、例題二 ?有圖如上,用迪杰斯特拉算法求頂點(diǎn)A到其余各頂點(diǎn)的最短路徑,請問1.第一步求出的最短路徑是A到C的最短路徑2.第二步求出的是頂點(diǎn)A到頂點(diǎn)B/F的最短路徑3.頂點(diǎn)A到D的最短路徑長度是__25___ (填數(shù)字)4.頂點(diǎn)A到頂點(diǎn)F的最短路

    2024年02月12日
    瀏覽(20)
  • java實(shí)現(xiàn)迪杰斯特拉(Dijkstra)算法求解最短路問題

    java實(shí)現(xiàn)迪杰斯特拉(Dijkstra)算法求解最短路問題

    迪杰斯特拉(Dijkstra)算法是由荷蘭計(jì)算機(jī)科學(xué)家狄克斯特拉于1959年提出的。是尋找從一個(gè)頂點(diǎn)到其余各頂點(diǎn)的最短路徑算法,可用來解決最短路徑問題。 迪杰斯特拉算法采用貪心算法的策略,將所有頂點(diǎn)分為已標(biāo)記點(diǎn)和未標(biāo)記點(diǎn)兩個(gè)集合,從起始點(diǎn)開始,不斷在未標(biāo)記點(diǎn)中尋

    2024年02月12日
    瀏覽(30)
  • 大話數(shù)據(jù)結(jié)構(gòu)-迪杰斯特拉算法(Dijkstra)和弗洛伊德算法(Floyd)

    大話數(shù)據(jù)結(jié)構(gòu)-迪杰斯特拉算法(Dijkstra)和弗洛伊德算法(Floyd)

    ??最短路徑,對于圖來說,是兩頂點(diǎn)之間經(jīng)過的邊數(shù)最少的路徑;對于網(wǎng)來說,是指兩頂點(diǎn)之間經(jīng)過的邊上權(quán)值之和最小的路徑。路徑上第一個(gè)頂點(diǎn)為源點(diǎn),最后一個(gè)頂點(diǎn)是終點(diǎn)。 ??以如下無向圖為例: ??我們來計(jì)算下標(biāo)為0的頂點(diǎn),到其他頂點(diǎn)的最短路徑,首先定義

    2024年02月06日
    瀏覽(26)
  • 迪杰斯特拉(Dijkstra's )算法——解決帶權(quán)有向無向圖最短路徑

    迪杰斯特拉(Dijkstra's )算法——解決帶權(quán)有向無向圖最短路徑

    迪杰斯特拉算法(Dijkstra\\\'s Algorithm),又稱為狄克斯特拉算法,是一種用于解決帶權(quán)重有向圖或無向圖最短路徑問題的算法。該算法由荷蘭計(jì)算機(jī)科學(xué)家艾茲赫爾·狄克斯特拉在1956年發(fā)明,是一種廣泛應(yīng)用于網(wǎng)絡(luò)路由和其他領(lǐng)域的算法。 在 2001 年的一次采訪中,Dijkstra 博士透露

    2024年02月03日
    瀏覽(25)
  • 數(shù)據(jù)結(jié)構(gòu) -最短路徑dijkstra(迪杰斯特拉)算法講解及代碼實(shí)現(xiàn)

    數(shù)據(jù)結(jié)構(gòu) -最短路徑dijkstra(迪杰斯特拉)算法講解及代碼實(shí)現(xiàn)

    ? ? ? ? 迪杰斯特拉算法是一種廣義的貪心算法,求出局部最優(yōu)解,再去求全局最優(yōu)解 舉例圖:(起始點(diǎn)為1) 輔助數(shù)組: s:記錄了目標(biāo)頂點(diǎn)到其他頂點(diǎn)的最短路徑是否求得(求得為1,否則為0) p:目標(biāo)頂點(diǎn)到其他頂點(diǎn)的最短路徑的前驅(qū)節(jié)點(diǎn) (如,求得1-7-5的最短路徑,那

    2024年02月11日
    瀏覽(26)
  • MATLAB輕松繪制地圖路線——Dijkstra(迪杰斯特拉)算法最短路徑規(guī)劃

    MATLAB輕松繪制地圖路線——Dijkstra(迪杰斯特拉)算法最短路徑規(guī)劃

    利用MATLAB繪制地圖需要三個(gè)基本數(shù)據(jù): 節(jié)點(diǎn) 節(jié)點(diǎn)坐標(biāo) 節(jié)點(diǎn)間相通的路線 以11B交通巡警平臺調(diào)度問題中的A區(qū)數(shù)據(jù)為例: (數(shù)據(jù)及工程文件下載鏈接見文末) Demo1: 可通過已知節(jié)點(diǎn)的坐標(biāo),計(jì)算出各節(jié)點(diǎn)之間的距離,有Matlab基礎(chǔ)的同學(xué)可以嘗試Demo2, 也可通過Excel自行實(shí)現(xiàn);

    2023年04月21日
    瀏覽(23)
  • 數(shù)據(jù)結(jié)構(gòu)與算法 —— 最短路徑Dijkstra算法(迪杰斯特拉)詳細(xì)圖解以及python實(shí)現(xiàn)

    數(shù)據(jù)結(jié)構(gòu)與算法 —— 最短路徑Dijkstra算法(迪杰斯特拉)詳細(xì)圖解以及python實(shí)現(xiàn)

    目錄 前言 1. 介紹 2. 加權(quán)圖 2.1 概念 3. 最短路徑 -- Dijkstra 算法 3.1 歷史 3.2 Dijkstra 算法的基本思路 3.3?Dijkstra 算法圖解 4.? python中dijkstra算法的實(shí)現(xiàn) 5. 總結(jié)? 前兩章我們講到了關(guān)于圖的基本知識,和廣度/深度優(yōu)先搜索。 本章,我們將介紹 加權(quán)圖 和 最短路徑 的相關(guān)知識。 最

    2024年02月12日
    瀏覽(22)
  • 使用omp并行技術(shù)加速最短路徑算法-迪杰斯特拉(Dijkstra)算法(記錄最短路徑和距離)

    使用omp并行技術(shù)加速最短路徑算法-迪杰斯特拉(Dijkstra)算法(記錄最短路徑和距離)

    原理: Dijkstra算法是解決**單源最短路徑**問題的**貪心算法** 它先求出長度最短的一條路徑,再參照該最短路徑求出長度次短的一條路徑 ? ? 直到求出從源點(diǎn)到其他各個(gè)頂點(diǎn)的最短路徑。 首先假定源點(diǎn)為u,頂點(diǎn)集合V被劃分為兩部分:集合 S 和 V-S。 初始時(shí)S中僅含有源點(diǎn)u,

    2024年02月10日
    瀏覽(55)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包