最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C++圖論基本概念與存儲(chǔ)結(jié)構(gòu)

 更新時(shí)間:2026年02月23日 11:11:25   作者:落羽的落羽  
這篇文章主要介紹了C++圖論基本概念與存儲(chǔ)結(jié)構(gòu),圖是由頂點(diǎn)集合及頂點(diǎn)間的關(guān)系組成的一種數(shù)據(jù)結(jié)構(gòu),一個(gè)圖既有頂點(diǎn)也有邊,圖的存儲(chǔ)結(jié)構(gòu)中就需要保存它們,下面將進(jìn)行詳細(xì)的介紹,需要的朋友可以參考下

一、圖的基本概念

圖是由頂點(diǎn)集合及頂點(diǎn)間的關(guān)系組成的一種數(shù)據(jù)結(jié)構(gòu):G = (V, E);

  • V是頂點(diǎn)集合
  • E是頂點(diǎn)間關(guān)系的集合,也叫做邊的集合
  • 圖中的結(jié)點(diǎn)稱為頂點(diǎn)。如果兩個(gè)頂點(diǎn) vi 和 vj 之間相關(guān)聯(lián),稱有一條邊記<vi, vj>

圖分為有向圖和無(wú)向圖:在有向圖中,<x, y>稱為頂點(diǎn)x到頂點(diǎn)y的一條邊,<x, y>和<y, x>是兩條不同的邊。而在無(wú)向圖中,<x, y>和<y, x>是同一條邊。

圖中邊的數(shù)量與頂點(diǎn)數(shù)量的關(guān)系,可以用稠密和稀疏形容。

完全圖:設(shè)一張圖有n個(gè)頂點(diǎn)。對(duì)于無(wú)向圖,若有n*(n-1)/2條邊,即任意兩點(diǎn)之間都有一條邊,則稱此圖為無(wú)向完全圖,也是最稠密的圖;對(duì)于有向圖,若有n*(n-1)條邊,即任意兩點(diǎn)之間都有兩條方向相反的邊,則稱此圖為有向完全圖。

頂點(diǎn)的度:頂點(diǎn)v的度是指與它相關(guān)聯(lián)的邊的條數(shù),記作deg(v)。在有向圖中,頂點(diǎn)v的度等于該頂點(diǎn)的入度與出度之和,入度是指以v為終點(diǎn)的有向邊的條數(shù),出度是指以v為起點(diǎn)的有向邊的條數(shù)。在無(wú)向圖中,頂點(diǎn)v的度等于出度等于入度。

路徑:在圖中,若從頂點(diǎn) vi 出發(fā)有一組邊可以使其到達(dá)頂點(diǎn) vj,則稱頂點(diǎn) vi 到 vj 的頂點(diǎn)序列為頂點(diǎn) vi 到 vj 的路徑。

權(quán)值:邊附帶的數(shù)據(jù)信息,比如:長(zhǎng)度,價(jià)值,親密度

路徑長(zhǎng)度:對(duì)于不帶權(quán)的圖,一條路徑的路徑長(zhǎng)度是該路徑上的邊數(shù)量;對(duì)于帶權(quán)的圖,一條路徑的路徑長(zhǎng)度是該路徑上的所有邊的權(quán)總和。

簡(jiǎn)單路徑與回路:若一條路徑上的各頂點(diǎn)都不重復(fù),則稱這樣的路徑為簡(jiǎn)單路徑。若路徑上的第一個(gè)頂點(diǎn)和最后一個(gè)頂點(diǎn)重合,則稱這樣的路徑為回路或環(huán)。

子圖:設(shè)圖G = {V, E}、G1 = {V1, E1},若V1屬于V且E1屬于E,則稱G1是子圖。即一個(gè)圖的子圖,所有的頂點(diǎn)和邊都在原圖中出現(xiàn)過(guò)。

連通圖:對(duì)于無(wú)向圖,若頂點(diǎn)v1到v2有路徑,則稱v1和v2是連通的。如果圖中任意兩個(gè)頂點(diǎn)都是連通的,則稱此圖為連通圖。

強(qiáng)連通圖:對(duì)于有向圖,如果任意兩頂點(diǎn)vi和vj之間,都存在一條vi到vj的路徑和vj到vi的路徑,則稱此圖為強(qiáng)連通圖。

生成樹:生成樹是連通圖(無(wú)向圖)的一個(gè)子圖,是一棵樹,包含原圖所有頂點(diǎn)且保持連通,有n個(gè)頂點(diǎn)的連通圖的生成樹有n個(gè)頂點(diǎn)和n-1條邊。

二、圖的存儲(chǔ)結(jié)構(gòu)

一個(gè)圖既有頂點(diǎn)也有邊,圖的存儲(chǔ)結(jié)構(gòu)中就需要保存它們。頂點(diǎn)保存比較簡(jiǎn)單,只需要一個(gè)數(shù)組即可,關(guān)系邊該怎么保存呢?

保存邊的方式,有領(lǐng)接矩陣和領(lǐng)接表兩種方式!

1. 領(lǐng)接矩陣

頂點(diǎn)與頂點(diǎn)之間是否連通,可以用0或1表示。領(lǐng)接矩陣就是一個(gè)二維數(shù)組,用矩陣來(lái)表示頂點(diǎn)之間的關(guān)系

每個(gè)結(jié)點(diǎn)可以用數(shù)組下標(biāo)代表。例如,頂點(diǎn)A的下標(biāo)是x,頂點(diǎn)B的下標(biāo)是y。領(lǐng)接矩陣中[x][y]代表從A到B的邊的權(quán)值,如果是無(wú)權(quán)圖就用01表示該邊是否存在即可,如果是有權(quán)圖則填入權(quán)值或默認(rèn)值(表示邊不存在,一般可以用INT_MAX代表)。
注意,對(duì)于無(wú)向圖,領(lǐng)接矩陣是左下右上對(duì)稱的,即[x][y][y][x]內(nèi)容一樣!有向圖則不是,[x][y][y][x]內(nèi)容不一定相同。

// 圖
namespace Matrix
{
	// V頂點(diǎn)類型 W邊權(quán)值類型 MAX_W表示邊不存在的值 Direction表示圖是否有向
	template<class V, class W, W MAX_W = INT_MAX, bool Direction = false>
	class Graph
	{
	public:
		Graph(const V* vertexs, size_t n)
		{
			_vertexs.reserve(n);
			for (size_t i = 0; i < n; ++i)
			{
				_vertexs.push_back(vertexs[i]);
				_vIndexMap[vertexs[i]] = i;
			}
			// MAX_W 作為不存在邊的標(biāo)識(shí)值
			// 初始化時(shí)默認(rèn)沒(méi)有邊,邊需要一條一條手動(dòng)添加,用AddEdge函數(shù)
			_matrix.resize(n);
			for (auto& e : _matrix)
			{
				e.resize(n, MAX_W);
			}
		}
		// 找到一個(gè)頂點(diǎn)的映射下標(biāo)
		size_t GetVertexIndex(const V& v)
		{
			auto ret = _vIndexMap.find(v);
			if (ret != _vIndexMap.end())
			{
				return ret->second;
			}
			else
			{
				throw invalid_argument("不存在的頂點(diǎn)");
				return -1;
			}
		}
		// 添加一條邊,src和dst代表兩端頂點(diǎn),w是權(quán)值
		void AddEdge(const V& src, const V& dst, const W& w)
		{
			size_t srci = GetVertexIndex(src);
			size_t dsti = GetVertexIndex(dst);
			_matrix[srci][dsti] = w;
			//如果是無(wú)向圖,則[dsti][srci]也需添加邊
			if (Direction == false)
			{
				_matrix[dsti][srci] = w;
			}
		}
	private:
		map<V, size_t> _vIndexMap;   // 頂點(diǎn)到下標(biāo)的映射
		vector<V> _vertexs;			 // 頂點(diǎn)集合
		vector<vector<W>> _matrix;   // 領(lǐng)接矩陣 存儲(chǔ)邊
	};
}

領(lǐng)接矩陣適合存儲(chǔ)稠密圖,能O(1)判斷兩個(gè)頂點(diǎn)的關(guān)系,得到權(quán)值。但是如果要查找一個(gè)頂點(diǎn)連接的所有邊,效率是O(n)

2. 領(lǐng)接表

領(lǐng)接表是一個(gè)鏈表數(shù)組。數(shù)組表示頂點(diǎn)的集合,鏈表表示邊的關(guān)系。

領(lǐng)接表適合存儲(chǔ)稀疏圖,適合查找一個(gè)頂點(diǎn)連接出去的邊,但是相對(duì)不適合判斷兩個(gè)點(diǎn)是否有邊及其權(quán)值。

// 臨接表
namespace LinkTable
{
	// 定義邊結(jié)構(gòu), W是權(quán)值類型
	template<class W>
	struct LinkEdge
	{
		int _srcIndex;
		int _dstIndex;
		W _w;
		LinkEdge<W>* _next;
		LinkEdge(const W& w)
			: _srcIndex(-1)
			, _dstIndex(-1)
			, _w(w)
			, _next(nullptr)
		{ }
	};
	template<class V, class W, bool Direction = false>
	class Graph
	{
		typedef LinkEdge<W> Edge;
	public:
		Graph(const V* vertexs, size_t n)
		{
			_vertexs.reserve(n);
			for (size_t i = 0; i < n; ++i)
			{
				_vertexs.push_back(vertexs[i]);
				_vIndexMap[vertexs[i]] = i;
			}
			_linkTable.resize(n, nullptr);
		}
		size_t GetVertexIndex(const V& v)
		{
			auto ret = _vIndexMap.find(v);
			if (ret != _vIndexMap.end())
			{
				return ret->second;
			}
			else
			{
				throw invalid_argument("不存在的頂點(diǎn)");
				return -1;
			}
		}
		// 添加邊
		void AddEdge(const V& src, const V& dst, const W& w)
		{
			size_t srcindex = GetVertexIndex(src);
			size_t dstindex = GetVertexIndex(dst);
			Edge* sd_edge = new Edge(w);
			sd_edge->_srcIndex = srcindex;
			sd_edge->_dstIndex = dstindex;
			sd_edge->_next = _linkTable[srcindex];
			_linkTable[srcindex] = sd_edge;
			// 如果是無(wú)向圖,還要反過(guò)來(lái)添加一次
			if (Direction == false)
			{
				Edge* ds_edge = new Edge(w);
				ds_edge->_srcIndex = dstindex;
				ds_edge->_dstIndex = srcindex;
				ds_edge->_next = _linkTable[dstindex];
				_linkTable[dstindex] = ds_edge;
			}
		}
	private:
		map<string, int> _vIndexMap; // 頂點(diǎn)到下標(biāo)的映射
		vector<V> _vertexs;			 // 頂點(diǎn)集合
		vector<Edge*> _linkTable;    // 邊的集合的領(lǐng)接表
	};
}

以上就是C++圖論基本概念與存儲(chǔ)結(jié)構(gòu)的詳細(xì)內(nèi)容,更多關(guān)于C++圖的概念與存儲(chǔ)的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • C++算法之在無(wú)序數(shù)組中選擇第k小個(gè)數(shù)的實(shí)現(xiàn)方法

    C++算法之在無(wú)序數(shù)組中選擇第k小個(gè)數(shù)的實(shí)現(xiàn)方法

    這篇文章主要介紹了C++算法之在無(wú)序數(shù)組中選擇第k小個(gè)數(shù)的實(shí)現(xiàn)方法,涉及C++數(shù)組的遍歷、判斷、運(yùn)算等相關(guān)操作技巧,需要的朋友可以參考下
    2017-03-03
  • C/C++通過(guò)IP獲取局域網(wǎng)網(wǎng)卡MAC地址

    C/C++通過(guò)IP獲取局域網(wǎng)網(wǎng)卡MAC地址

    這篇文章主要為大家詳細(xì)介紹了C++如何通過(guò)Win32API函數(shù)SendARP從IP地址獲取局域網(wǎng)內(nèi)網(wǎng)卡的MAC地址,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2025-02-02
  • C++中utf8字符串和gbk字符串的轉(zhuǎn)換方法

    C++中utf8字符串和gbk字符串的轉(zhuǎn)換方法

    文章介紹了C++中UTF-8字符串和GBK字符串之間的轉(zhuǎn)換,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),感興趣的朋友跟隨小編一起看看吧
    2025-02-02
  • OpenCV利用霍夫變換實(shí)現(xiàn)交通車道線檢測(cè)

    OpenCV利用霍夫變換實(shí)現(xiàn)交通車道線檢測(cè)

    經(jīng)典霍夫變換用來(lái)檢測(cè)圖像中的直線,后來(lái)霍夫變換經(jīng)過(guò)擴(kuò)展可以進(jìn)行任意形狀物體的識(shí)別,例如圓和橢圓。本文就來(lái)利用霍夫變換實(shí)現(xiàn)交通車道線檢測(cè),需要的可以參考一下
    2022-09-09
  • C語(yǔ)言實(shí)現(xiàn)隨機(jī)發(fā)牌

    C語(yǔ)言實(shí)現(xiàn)隨機(jī)發(fā)牌

    這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言實(shí)現(xiàn)隨機(jī)發(fā)牌,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-04-04
  • C語(yǔ)言多功能動(dòng)態(tài)通訊錄實(shí)現(xiàn)示例

    C語(yǔ)言多功能動(dòng)態(tài)通訊錄實(shí)現(xiàn)示例

    這篇文章主要為大家介紹了C語(yǔ)言多功能動(dòng)態(tài)通訊錄實(shí)現(xiàn)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-01-01
  • 單詞小助手C語(yǔ)言版

    單詞小助手C語(yǔ)言版

    這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言版的單詞小助手,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-10-10
  • 嵌入式QT移植的實(shí)現(xiàn)

    嵌入式QT移植的實(shí)現(xiàn)

    本文主要介紹了嵌入式QT移植的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2022-05-05
  • 學(xué)習(xí)C++編程的必備軟件

    學(xué)習(xí)C++編程的必備軟件

    本文給大家分享的是作者在學(xué)習(xí)使用C++進(jìn)行編程的時(shí)候所用到的一些常用的軟件,這里推薦給大家
    2017-04-04
  • C語(yǔ)言實(shí)現(xiàn)三子棋的步驟和代碼詳解

    C語(yǔ)言實(shí)現(xiàn)三子棋的步驟和代碼詳解

    這篇文章主要介紹了C語(yǔ)言實(shí)現(xiàn)三子棋的步驟和代碼詳解,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-12-12

最新評(píng)論

日土县| 南宫市| 林口县| 尼勒克县| 泸西县| 习水县| 衡阳县| 彩票| 通城县| 灵石县| 慈利县| 鄂托克前旗| 昆山市| 新龙县| 定兴县| 长沙县| 元阳县| 三穗县| 云林县| 平舆县| 达州市| 深水埗区| 长岛县| 田林县| 武威市| 专栏| 定襄县| 西平县| 东平县| 永兴县| 龙州县| 包头市| 密云县| 肃南| 博乐市| 阿克陶县| 普定县| 临泉县| 永济市| 金阳县| 公安县|