第二十七天(數據結構:圖)

圖:是一種非線性結構形式化的描述:   G={V,R}V:圖中各個頂點元素(如果這個圖代表的是地圖,這個頂點就是各個點的地址)R:關系集合,圖中頂點與頂點之間的關系(如果是地圖,這個關系集合可能就代表的是各個地點之間的距離)在頂點與頂點之間的關系上面加上一個權值(w),這種權值代表的意義可能會不一樣如果沒有權值,頂點與頂點之間可能只有是否能到達的情況,但是不知道到達它需要的"距離"圖是一個二元組:描述V(頂點的代號,我們需要一個"數組") 描述R(可能是兩點之間的距離,我們也需要一個"數組"去描述)圖分為兩種1 有向圖:關系是有方向的(你可以想象是一個單行道)有去不一定有來在畫圖的時候,關系是有箭頭指向的2 無向圖:關系是沒有方向的(你可以想象是小區的小道,你過去是走這一條,回來的時候也是走的這一條)有去一定有來在畫圖的時候,關系是沒有箭頭指向的網:帶權值的圖我們就叫網頂點的度:有出度也有入度如果圖是有向圖,這個頂點有出度不一定有入度,有入度不一定有出度如果圖是無向圖,這個頂點有出度一定有入度一般圖里面算度的數量的時候分別都要算入度和出度的數量出度:拓撲  --> 找一個沒有入度的頂點出發通過出度到達另外一個頂點,然后將這個點的入度全部刪除然后從下一個點繼續開始,如果最后能將圖里面的所有的頂點都遍歷一遍那個這個圖就叫拓撲有序,否則就叫拓撲無序入度:逆拓撲 -> 跟上面的是反的圖:里面主要要搞定一個叫路徑的問題1 最短路徑 --- 最短的那一條2 關鍵路徑 --- 在覆蓋所有的工作流程里面找最短的那些路徑這些路徑里面最長的那條路徑就叫關鍵路徑計算機里面描述圖圖是一個二元組,因此需要用至少兩個東西分別描述頂點元素集合,關系集合假設你的頂點是ABCDEFG -> 我們開一個char[]就可以描述了假設你的頂點是"長沙" "武漢"... -> char *[]描述假設你的關系集合為距離 -> int [][]我們有幾種方式去做圖的保存"數組表示法" -> 鄰接矩陣"鏈表表示法" -> 鄰接表(逆鄰接表) 十字鏈表 鄰接多重表鄰接矩陣:通過頂點元素數組和關系集合數組來描述通過畫圖可以看出,鄰接矩陣適合稠密圖鄰接表:通過頂點元素數組和關系鏈表來描述(有向圖無向圖都能做)十字鏈表:主要搞定有向圖(可以快速反應這個點的入度與出度)鄰接多重表:主要搞定無向圖(有去必有來,因此可以少建立很多的關系)通過畫圖可以看出,鏈表表示法適合稀松圖圖的遍歷1 深度優先DFS:樹里面的先序遍歷的擴展圖里面的任何一個頂點都可能是出發點從出發點開始,將其遍歷,然后以深度優先的方式繼續遍歷它的鄰接點(和它有直接關系的點在畫圖的時候有一根線和它連起來了,這個點就是它的鄰接點)鄰接點遍歷完畢繼續以深度優先遍歷它的鄰接點的鄰接點這個點有去也有可能有來,遍歷的時候就可能會遇到剛剛遍歷過點因此我們需要一個輔助向量來表明這個頂點是不是已經被遍歷過了char V[10];visit[10] -> visit[0]表示V[0]是不是已經被訪問 visit[1]表示V[1]是不是已經被訪問.....0沒有被遍歷,1表示遍歷過了if(visit[i] == 0){              訪問V[i]visit[i] = 1;//標記已經被訪問過DFS(V[i]的鄰接點) //以相同的規則去訪問這個鄰接點}訪問w;for(v = 從w第一個鄰接點開始;v鄰接點存在;v = w下一個鄰接點){if(visit[v] == 0){//訪問vvisit[v] == 1;DFS(v);}}2 廣度優先BFS:樹里面的層次遍歷的擴展利用隊列來進行每一層每一層的遍歷入隊訪問出隊訪問都可以從起點開始,將它入隊出隊,轉向它的下一輩(它所有的鄰接點(前面有可能已經被訪問過,訪問過的要排除))為了確保孤島也能被訪問,我們需要將每一個點都要以BFS的形式走一遍BFS(v){//將頂點入隊queue_push(v);while(隊列不為空){v = queue_front();queue_pop();for(i = v的所有鄰接點){if(visit[i] == 0) //這些鄰接點沒有被訪問你才需要去訪問{visit[i] = 1;queue_push(i);}}}}for(i < 頂點個數個數)//防止有孤島  所以每一個點都要試一次BFS{if(visit[i] == 0){BFS(i);}}//輸入格式
ABCDEFG ->所有的頂點元素
AB3     ->邊以及權值
BC5
...
##-1退出
//你的圖里面最多可以容納的頂點個數
#define VMaxNum 1000//這個值代表一個無法到達的權值
#define VERYBIG 65535//弄的是鄰接矩陣//你現在需要一個圖的類型
typedef struct 
{char _V[VMaxNum];//頂點元素的數組int _R[VMaxNum][VMaxNum];//頂點與頂點之間的關系集合int _vexnum;//真正頂點的個數int _arcnum;//邊(關系線)的個數  無向的叫邊  有向的叫弧
}Graph;
#include "Graph.h"//建立鄰接矩陣
Graph * GraphInit(void)
{return (Graph *)calloc(1,sizeof(Graph));
}//獲取頂點元素的下標 -1表示失敗
int GetVIndex(Graph * g,char v)
{for(int i = 0;i < g ->_vexnum;i++){if(v == g ->_V[i])return i;}return -1;
}//從鍵盤獲取頂點元素以及邊
void GetGraph(Graph * g)
{if(!g)return;printf("請輸入所有的頂點元素:");scanf("%s",g ->_V);getchar();g ->_vexnum = strlen(g ->_V);//實際頂點個數為這么多//關系集合里面什么玩意兒都沒有 不能是0for(int i = 0;i < g ->_vexnum;i++){for(int j = 0;j < g ->_vexnum;j++){g ->_R[i][j] = VERYBIG;//用VERYBIG將關系集合初始化一遍}}char start,stop;int w;while(1){printf("請輸入邊和權值(AB2):");if(scanf("%c%c%d",&start,&stop,&w) != 3){printf("\t\t輸入有誤,請重新輸入\n");char buf[1024];fgets(buf,1024,stdin);continue;}getchar();//輸入成功在后面會多一個\n 你需要拿走if('#' == start || '#' == stop || -1 == w){break;}//printf("%c  %c  %d\n",start,stop,w);int start_index = GetVIndex(g,start);int stop_index = GetVIndex(g,stop);if(-1 == start_index || -1 == stop_index){printf("\n邊有問題,請重新輸入\n");}//為了避免重復if(g ->_R[start_index][stop_index] == VERYBIG)g ->_arcnum++;g ->_R[start_index][stop_index] = w;//這個東西代表的是start到stop有w遠printf("%d   %d\n",start_index,stop_index);g ->_R[stop_index][start_index] = w;//無向圖就可以多這一步    }
}//打印鄰接矩陣
void PrintGraph(Graph * g)
{if(!g)return;for(int i = 0;i < g ->_vexnum;i++){printf("\t%c",g ->_V[i]);}printf("\n");for(int i = 0;i < g ->_vexnum;i++){printf("%c",g ->_V[i]);for(int j = 0;j < g ->_vexnum;j++){if(g ->_R[i][j] == VERYBIG)printf("\t\\");elseprintf("\t%d",g ->_R[i][j]);}printf("\n");}
}//獲取v的第一個鄰接點 v這一行里面第一個不是VERYBIG的
//失敗返回-1
int GetFirstIndex(Graph * g,int v)
{for(int i = 0;i < g ->_vexnum;i++){if(g ->_R[v][i] != VERYBIG)return i;}return -1;
}
//獲取v的w的下一個鄰接點 v這一行里面w列后面第一個不是VERYBIG的
//失敗返回-1
int GetNextIndex(Graph * g,int v,int w)
{for(int i = w + 1;i < g ->_vexnum;i++){if(g ->_R[v][i] != VERYBIG)return i;}return -1;
}//遍歷的向量
int visit[VMaxNum];//visit[i]表示頂點V[i]是否被訪問 0表示沒有  1表示訪問過了//這里用的v是下標
static void DFS(Graph * g,int v)
{if(!g || visit[v])//已經訪問過就不用訪問了return;printf("%c ",g ->_V[v]);visit[v] = 1;for(int w = GetFirstIndex(g,v);w > -1;w = GetNextIndex(g,v,w)){if(visit[w] == 0){DFS(g,w);}}
}//DFS 深度優先 從v開始進行DFS  v是頂點
void DFS_search(Graph * g,char v)
{//初始化visitmemset(visit,0,g ->_vexnum *sizeof(visit[0]));printf("DFS:");//先弄一個遍v開始的DFSDFS(g,GetVIndex(g,v));printf("\n");//所有再遍歷來一遍for(int i = 0;i < g ->_vexnum;i++){if(visit[i] == 0){DFS(g,i);printf("\n");}}
}//請你實現BFS
static void BFS(Graph * g,int v)
{if(!g || visit[v])//圖不存在或者v被訪問過都無需訪問return;//隊列要存在ArrayQueue * qu = ArrayQueue_init(100);//將頂點入隊ArrayQueue_push(qu,v);visit[v] = 1;while(!ArrayQueue_empty(qu)){v = ArrayQueue_front(qu);printf("%c ",g ->_V[v]);ArrayQueue_pop(qu);//for(int i = GetFirstIndex(g,v);i > -1;i = GetNextIndex(g,v,i))for(int i = 0;i < g ->_vexnum;i++){if(g ->_R[v][i] != VERYBIG){if(visit[i] == 0) //這些鄰接點沒有被訪問你才需要去訪問{visit[i] = 1;ArrayQueue_push(qu,i);}}}      }ArrayQueue_destory(&qu,NULL);
}//BFS 廣度優先 從v開始進行BFS  v是頂點
void BFS_search(Graph * g,char v)
{//初始化visitmemset(visit,0,g ->_vexnum *sizeof(visit[0]));printf("BFS:");//先弄一個遍v開始的BFSBFS(g,GetVIndex(g,v));printf("\n");//所有再遍歷來一遍for(int i = 0;i < g ->_vexnum;i++)//防止孤島{if(visit[i] == 0){BFS(g,i);printf("\n");}  }}

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/92149.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/92149.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/92149.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

數據賦能(386)——數據挖掘——迭代過程

概述重要性如下&#xff1a;提升挖掘效果&#xff1a;迭代過程能不斷優化數據挖掘模型&#xff0c;提高挖掘結果的準確性和有效性&#xff0c;從而更好地滿足業務需求。適應復雜數據&#xff1a;數據往往具有復雜性和多樣性&#xff0c;通過迭代可以逐步探索和適應數據的特點&a…

什么是鍵值緩存?讓 LLM 閃電般快速

一、為什么 LLMs 需要 KV 緩存&#xff1f;大語言模型&#xff08;LLMs&#xff09;的文本生成遵循 “自回歸” 模式 —— 每次僅輸出一個 token&#xff08;如詞語、字符或子詞&#xff09;&#xff0c;再將該 token 與歷史序列拼接&#xff0c;作為下一輪輸入&#xff0c;直到…

16.Home-懶加載指令優化

問題1&#xff1a;邏輯書寫位置不合理問題2&#xff1a;重復監聽問題已經加載完畢但是還在監聽

Day116 若依融合mqtt

MQTT 1.MQTT協議概述MQTT是一種基于發布/訂閱模式的輕量級消息傳輸協議&#xff0c;設計用于低帶寬、高延遲或不穩定的網絡環境&#xff0c;廣泛應用于物聯網領域1.1 MQTT協議的應用場景1.智能家居、車聯網、工業物聯網&#xff1a;MQTT可以用于連接各種家電設備和傳感器&#…

PyTorch + PaddlePaddle 語音識別

PyTorch PaddlePaddle 語音識別 目錄 概述環境配置基礎理論數據預處理模型架構設計完整實現案例模型訓練與評估推理與部署性能優化技巧總結 語音識別&#xff08;ASR, Automatic Speech Recognition&#xff09;是將音頻信號轉換為文本的技術。結合PyTorch和PaddlePaddle的…

施耐德 Easy Altivar ATV310 變頻器:高效電機控制的理想選擇(含快速調試步驟及常見故障代碼)

施耐德 Easy Altivar ATV310 變頻器&#xff1a;高效電機控制的理想選擇&#xff08;含快速調試步驟&#xff09;在工業自動化領域&#xff0c;變頻器作為電機控制的核心設備&#xff0c;其性能與可靠性直接影響整個生產系統的效率。施耐德電氣推出的 Easy Altivar ATV310 變頻…

搭建郵件服務器概述

一、電子郵件應用解析標準郵件服務器&#xff08;qq郵箱&#xff09;&#xff1a;1&#xff09;提供電子郵箱&#xff08;lvbuqq.com&#xff09;及存儲空間2&#xff09;為客戶端向外發送郵件給其他郵箱&#xff08;diaochan163.com&#xff09;3&#xff09;接收/投遞其他郵箱…

day28-NFS

1.每日復盤與今日內容1.1復盤Rsync:本地模式、遠程模式&#x1f35f;&#x1f35f;&#x1f35f;&#x1f35f;&#x1f35f;、遠程守護模式&#x1f35f;&#x1f35f;&#x1f35f;&#x1f35f;&#x1f35f;安裝、配置Rsync啟動、測試服務備份案例1.2今日內容NFS優缺點NFS服…

二叉搜索樹--通往高階數據結構的基石

目錄 前言&#xff1a; 1、二叉搜索樹的概念 2、二叉搜索樹性能分析 3、二叉搜索樹的實現 BinarySelectTree.h test.cpp 4、key 和 key / value&#xff08; map 和 set 的鋪墊 &#xff09; 前言&#xff1a; 又回到數據結構了&#xff0c;這次我們將要學習一些復雜的…

Profinet轉Ethernet IP網關接入五軸車床上下料機械手控制系統的配置實例

本案例為西門子1200PLC借助PROFINET轉EtherNet/IP網關與搬運機器人進行連接的配置案例。所需設備包括&#xff1a;西門子1200PLC、Profinet轉EtherNet/IP網關以及發那科&#xff08;Fanuc&#xff09;機器人。開啟在工業自動化控制領域廣泛應用、功能強大且專業的西門子博圖配置…

專題二_滑動窗口_長度最小的子數組

引入&#xff1a;滑動窗口首先&#xff0c;這是滑動窗口的第一道題&#xff0c;所以簡短的說一下滑動窗口的思路&#xff1a;當我們題目要求找一個滿足要求的區間的時候&#xff0c;且這個區間的left和right指針&#xff0c;都只需要同向移動的時候&#xff0c;就可以使用滑動窗…

解鎖高效開發:AWS 前端 Web 與移動應用解決方案詳解

告別繁雜的部署與運維&#xff0c;AWS 讓前端開發者的精力真正聚焦于創造卓越用戶體驗。在當今快速迭代的數字環境中&#xff0c;Web 與移動應用已成為企業與用戶交互的核心。然而&#xff0c;前端開發者常常面臨諸多挑戰&#xff1a;用戶認證的復雜性、后端 API 的集成難題、跨…

北京JAVA基礎面試30天打卡04

1. 單例模式的實現方式及線程安全 單例模式&#xff08;Singleton Pattern&#xff09;確保一個類只有一個實例&#xff0c;并提供一個全局訪問點。以下是常見的單例模式實現方式&#xff0c;以及如何保證線程安全&#xff1a; 單例模式的實現方式餓漢式&#xff08;Eager Init…

Redis 緩存三大核心問題:穿透、擊穿與雪崩的深度解析

引言在現代互聯網架構中&#xff0c;緩存是提升系統性能、降低數據庫壓力的核心手段之一。而 Redis 作為高性能的內存數據庫&#xff0c;憑借其豐富的數據結構、靈活的配置選項以及高效的網絡模型&#xff0c;已經成為緩存領域的首選工具。本文將從 Redis 的基本原理出發&#…

耘瞳科技國產化點云處理軟件,開啟智能化三維測量新時代

在現代工業制造領域&#xff0c;三維點云數據已成為推動生產效率提升、質量控制優化以及智能制造轉型的關鍵技術之一。三維點云數據能夠提供高精度的物體表面信息&#xff0c;廣泛應用于制造零件的質量檢測&#xff1b;通過點云數據與CAD模型的對比分析&#xff0c;可以快速檢測…

RabbitMQ面試精講 Day 8:死信隊列與延遲隊列實現

【RabbitMQ面試精講 Day 8】死信隊列與延遲隊列實現 文章標簽 RabbitMQ,消息隊列,死信隊列,延遲隊列,面試技巧,分布式系統 文章簡述 本文是"RabbitMQ面試精講"系列第8天&#xff0c;深入講解死信隊列與延遲隊列的實現原理與實戰應用。文章詳細解析死信隊列的觸發…

團結引擎 1.5.0 版本發布:Android App View 功能詳解

核心亮點 原生安卓應用支持 2D & 3D 雙形態呈現 編輯器全流程集成 靈活調控功能 多應用并行展示 智能座艙應用示例 快速入門指南 開發說明 功能支持 實驗性功能 資源鏈接 團結引擎 1.5.0 版本已于 4 月 14 日正式上線。本次更新中&#xff0c;車機版引入了一項突…

基于SpringBoot的OA辦公系統的設計與實現

文章目錄前言詳細視頻演示具體實現截圖后端框架SpringBoot持久層框架MyBaits成功系統案例&#xff1a;代碼參考數據庫源碼獲取前言 博主介紹:CSDN特邀作者、985高校計算機專業畢業、現任某互聯網大廠高級全棧開發工程師、Gitee/掘金/華為云/阿里云/GitHub等平臺持續輸出高質量…

知識隨記-----用 Qt 打造優雅的密碼輸入框:添加右側眼睛圖標切換顯示

Qt 技巧&#xff1a;通過 QLineEdit 右側眼睛圖標實現密碼可見性切換 文章目錄Qt 技巧&#xff1a;通過 QLineEdit 右側眼睛圖標實現密碼可見性切換概要整體架構流程技術名詞解釋技術細節實現效果展示概要 本文介紹如何使用 Qt 框架為 QLineEdit 控件添加一個右側的眼睛圖標&a…

Unity里的對象旋轉數值跳轉問題的原理與解決方案

文章目錄1. 問題描述2. 問題原因3. 解決方案3.1通過多個父子關系從而控制旋轉&#xff08;推薦&#xff09;3.2 使用四元數進行旋轉1. 問題描述 我們現在寫一個3D的Unity程序&#xff0c;我們現在設置了一個物體后&#xff0c;我們想旋轉使其改為我們想要的情況。但是我們如果…