国产亚洲精品福利在线无卡一,国产精久久一区二区三区,亚洲精品无码国模,精品久久久久久无码专区不卡

當(dāng)前位置: 首頁 > news >正文

寶安中心做網(wǎng)站網(wǎng)站公司網(wǎng)站建設(shè)

寶安中心做網(wǎng)站,網(wǎng)站公司網(wǎng)站建設(shè),洛陽小程序開發(fā)公司,深圳做分銷網(wǎng)站這個(gè)程序是一個(gè)圖的實(shí)現(xiàn),使用鄰接表來表示圖的結(jié)構(gòu): 1. 結(jié)構(gòu)定義部分: - AdjListNode 結(jié)構(gòu)定義了鄰接表中的節(jié)點(diǎn),每個(gè)節(jié)點(diǎn)包含一個(gè)名稱和一個(gè)指向下一個(gè)鄰接節(jié)點(diǎn)的指針。 - Node 結(jié)構(gòu)定義了圖中的節(jié)點(diǎn),每個(gè)節(jié)點(diǎn)…

這個(gè)程序是一個(gè)圖的實(shí)現(xiàn),使用鄰接表來表示圖的結(jié)構(gòu):

1. 結(jié)構(gòu)定義部分:
? ?- `AdjListNode` 結(jié)構(gòu)定義了
鄰接表中的節(jié)點(diǎn),每個(gè)節(jié)點(diǎn)包含一個(gè)名稱和一個(gè)指向下一個(gè)鄰接節(jié)點(diǎn)的指針。
? ?- `Node` 結(jié)構(gòu)定義了
圖中的節(jié)點(diǎn),每個(gè)節(jié)點(diǎn)包含一個(gè)名稱和一個(gè)指向鄰接表頭部的指針

鄰接表通常是用鏈表來實(shí)現(xiàn)的。在這個(gè)程序中,每個(gè)節(jié)點(diǎn)(Node)都有一個(gè)指向鄰接表頭部的指針(AdjListNode* head),而鄰接表中的每個(gè)節(jié)點(diǎn)(AdjListNode)也是鏈表中的一個(gè)節(jié)點(diǎn),通過指針連接起來。

2. 圖類的方法:
? ?- `addNode` 方法用于向圖中添加新的節(jié)點(diǎn)。它創(chuàng)建一個(gè)新的 `Node` 對象并將其添加到節(jié)點(diǎn)數(shù)組中。vector<Node> nodes; ?// 存儲(chǔ)圖中所有節(jié)點(diǎn)的數(shù)組
? ?- `addEdge` 方法用于向圖中添加邊。它首先查找源節(jié)點(diǎn)和目標(biāo)節(jié)點(diǎn)在數(shù)組中的索引,然后創(chuàng)建一個(gè)新的鄰接表節(jié)點(diǎn)表示目標(biāo)節(jié)點(diǎn),并將其插入到源節(jié)點(diǎn)的鄰接表頭部。
? ?- `printGraph` 方法用于打印圖的鄰接表。它遍歷節(jié)點(diǎn)數(shù)組,對于每個(gè)節(jié)點(diǎn),遍歷其鄰接表并打印節(jié)點(diǎn)名稱。

3. main函數(shù):
? ?- 在 `main` 函數(shù)中,首先創(chuàng)建了一個(gè) `Graph` 對象。
? ?- 然后通過調(diào)用 `addNode` 方法向圖中添加了幾個(gè)節(jié)點(diǎn)。
? ?- 接著通過調(diào)用 `addEdge` 方法向圖中添加了幾條邊。
? ?- 最后調(diào)用 `printGraph` 方法打印了圖的鄰接表。

總體來說,這個(gè)程序展示了如何使用 C++ 實(shí)現(xiàn)圖的基本操作,包括添加節(jié)點(diǎn)、添加邊和打印鄰接表。

vector<Node> nodes; ?// 存儲(chǔ)圖中所有節(jié)點(diǎn)的數(shù)組
這行代碼聲明了一個(gè)名為 nodes 的 vector,用于存儲(chǔ)圖中所有節(jié)點(diǎn)的數(shù)組。
在 C++ 中,vector 是一種動(dòng)態(tài)數(shù)組,可以自動(dòng)調(diào)整大小以容納更多的元素。
在這個(gè)程序中,nodes 向量存儲(chǔ)的是 Node 結(jié)構(gòu)的對象,即圖中的節(jié)點(diǎn)。
通過 vector 的特性,我們可以方便地添加、刪除和訪問圖中的節(jié)點(diǎn),而不需要手動(dòng)管理數(shù)組的大小和內(nèi)存。?

----------

// 這兩行代碼用于將一個(gè)新節(jié)點(diǎn)插入到源節(jié)點(diǎn)的鄰接表的頭部。
// 1. `newNode->next = nodes[sourceIndex].head;`:?
// 這行代碼將新節(jié)點(diǎn)的 `next` 指針指向源節(jié)點(diǎn)當(dāng)前的鄰接表頭部。
//
這確保了新節(jié)點(diǎn)在鏈表中插入的位置是在頭部,而新的頭部后面接著的是原來的鄰接表頭部。
// 簡單來說,這步操作是讓新節(jié)點(diǎn) "鏈接" 上了原來的鏈表。
// 2. `nodes[sourceIndex].head = newNode;`:?
// 這行代碼將源節(jié)點(diǎn)的鄰接表頭部指針更新為指向新節(jié)點(diǎn)。這步操作是將新節(jié)點(diǎn)設(shè)定為新的鏈表頭部,從而確保鏈表結(jié)構(gòu)的完整性。
// ****綜合來看,這兩行代碼的效果是將一個(gè)新節(jié)點(diǎn)插入到源節(jié)點(diǎn)的鄰接表的最前面。
// 在圖的鄰接表表示中,這意味著你在源節(jié)點(diǎn)的連接列表中增加了一個(gè)新的鄰接節(jié)點(diǎn)。通過這種方式,可以有效地管理和更新圖的數(shù)據(jù)結(jié)構(gòu)。?

#include <iostream>
#include <string>
#include <vector>using namespace std;// 鄰接表節(jié)點(diǎn)結(jié)構(gòu)
struct AdjListNode {string name;         // 節(jié)點(diǎn)名稱AdjListNode* next;   // 指向下一個(gè)鄰接節(jié)點(diǎn)的指針// 構(gòu)造函數(shù)AdjListNode(string name) {this->name = name;   // 初始化節(jié)點(diǎn)名稱this->next = nullptr; // 初始化指針為空}
};// 圖的節(jié)點(diǎn)結(jié)構(gòu)
struct Node {string name;        // 節(jié)點(diǎn)名稱AdjListNode* head;  // 指向鄰接表頭部的指針// 構(gòu)造函數(shù)Node(string name) {this->name = name;   // 初始化節(jié)點(diǎn)名稱this->head = nullptr; // 初始化指針為空}
};// 圖類
class Graph {
private:vector<Node> nodes;  // 存儲(chǔ)圖中所有節(jié)點(diǎn)的數(shù)組public:// 添加節(jié)點(diǎn)到圖中void addNode(string nodeName) {nodes.push_back(Node(nodeName)); // 將新節(jié)點(diǎn)添加到節(jié)點(diǎn)數(shù)組中}// 添加邊到圖中void addEdge(string source, string dest) {int sourceIndex = findNodeIndex(source); // 查找源節(jié)點(diǎn)在數(shù)組中的索引int destIndex = findNodeIndex(dest);     // 查找目標(biāo)節(jié)點(diǎn)在數(shù)組中的索引if (sourceIndex != -1 && destIndex != -1) { // 如果找到了源節(jié)點(diǎn)和目標(biāo)節(jié)點(diǎn)AdjListNode* newNode = new AdjListNode(dest); // 創(chuàng)建一個(gè)新的鄰接表節(jié)點(diǎn),表示目標(biāo)節(jié)點(diǎn)newNode->next = nodes[sourceIndex].head;      // 將新節(jié)點(diǎn)插入到源節(jié)點(diǎn)的鄰接表頭部, 新的頭部后面接著的是原來的鄰接表頭部。nodes[sourceIndex].head = newNode; //將源節(jié)點(diǎn)的鄰接表頭部指針更新為指向新節(jié)點(diǎn)。這步操作是將新節(jié)點(diǎn)設(shè)定為新的鏈表頭部// 這段代碼并沒有處理無向圖的情況,所以會(huì)有缺陷// 如果需要處理無向圖,需要額外添加一條邊,指向源節(jié)點(diǎn)// newNode = new AdjListNode(source);// newNode->next = nodes[destIndex].head;// nodes[destIndex].head = newNode;}}// 打印圖的鄰接表void printGraph() {for (const auto& node : nodes) {                   // 遍歷每個(gè)節(jié)點(diǎn)cout << node.name << " -> ";                   // 打印節(jié)點(diǎn)名稱AdjListNode* current = node.head;              // 獲取當(dāng)前節(jié)點(diǎn)的鄰接表頭部while (current) {                              // 遍歷鄰接表cout << current->name;                     // 打印鄰接節(jié)點(diǎn)的名稱if (current->next) cout << " -> ";         // 如果存在下一個(gè)節(jié)點(diǎn),打印箭頭else cout << " -> nullptr";                // 否則打印鏈表末尾current = current->next;                   // 移動(dòng)到下一個(gè)鄰接節(jié)點(diǎn)}if (node.head == nullptr) cout << "nullptr";   // 如果當(dāng)前節(jié)點(diǎn)沒有鄰接節(jié)點(diǎn),則輸出 nullptrcout << endl;                                  // 換行}}private:// 查找節(jié)點(diǎn)在數(shù)組中的索引int findNodeIndex(string nodeName) {for (size_t i = 0; i < nodes.size(); ++i) {   // 遍歷節(jié)點(diǎn)數(shù)組if (nodes[i].name == nodeName) {          // 如果找到節(jié)點(diǎn)名稱匹配的節(jié)點(diǎn)return i;                              // 返回節(jié)點(diǎn)在數(shù)組中的索引}}return -1;                                     // 如果沒找到,返回-1}
};int main() {Graph graph;           // 創(chuàng)建圖對象graph.addNode("A");    // 添加節(jié)點(diǎn)graph.addNode("B");graph.addNode("C");graph.addNode("D");graph.addNode("E");graph.addEdge("A", "B"); // 添加邊graph.addEdge("B", "C");graph.addEdge("C", "A");graph.addEdge("C", "D");graph.addEdge("D", "A");graph.printGraph();    // 打印圖的鄰接表return 0;
}// 該程序用于實(shí)現(xiàn)一個(gè)簡單的圖(Graph)的數(shù)據(jù)結(jié)構(gòu),圖中包含多個(gè)節(jié)點(diǎn),每個(gè)節(jié)點(diǎn)具有一個(gè)名稱,并且每個(gè)節(jié)點(diǎn)可以與其他節(jié)點(diǎn)相連,以表示圖中邊的關(guān)系。
// 節(jié)點(diǎn)(Node)和鄰接表(AdjListNode)
// Node:每個(gè) Node 對象具有兩個(gè)成員變量:一個(gè)字符串變量 name,用于保存節(jié)點(diǎn)的名稱,以及一個(gè)指針變量 head,用于指向該節(jié)點(diǎn)的鄰接表。
// AdjListNode:每個(gè) AdjListNode 對象具有兩個(gè)成員變量:一個(gè)字符串變量 name,用于保存鄰接節(jié)點(diǎn)的名稱,以及一個(gè)指針變量 next,用于指向下一個(gè)鄰接節(jié)點(diǎn)。// 這兩行代碼用于將一個(gè)新節(jié)點(diǎn)插入到源節(jié)點(diǎn)的鄰接表的頭部。
// 1. `newNode->next = nodes[sourceIndex].head;`: 
// 這行代碼將新節(jié)點(diǎn)的 `next` 指針指向源節(jié)點(diǎn)當(dāng)前的鄰接表頭部。
// 這確保了新節(jié)點(diǎn)在鏈表中插入的位置是在頭部,而新的頭部后面接著的是原來的鄰接表頭部。
// 簡單來說,這步操作是讓新節(jié)點(diǎn) "鏈接" 上了原來的鏈表。
// 2. `nodes[sourceIndex].head = newNode;`: 
// 這行代碼將源節(jié)點(diǎn)的鄰接表頭部指針更新為指向新節(jié)點(diǎn)。這步操作是將新節(jié)點(diǎn)設(shè)定為新的鏈表頭部,從而確保鏈表結(jié)構(gòu)的完整性。
// ****綜合來看,這兩行代碼的效果是將一個(gè)新節(jié)點(diǎn)插入到源節(jié)點(diǎn)的鄰接表的最前面。
// 在圖的鄰接表表示中,這意味著你在源節(jié)點(diǎn)的連接列表中增加了一個(gè)新的鄰接節(jié)點(diǎn)。通過這種方式,可以有效地管理和更新圖的數(shù)據(jù)結(jié)構(gòu)。// 這兩行代碼一起完成了將新創(chuàng)建的鄰接表節(jié)點(diǎn)插入到源節(jié)點(diǎn)的鄰接表的頭部的操作。讓我解釋一下:
// newNode->next = nodes[sourceIndex].head;:
// 這行代碼將新節(jié)點(diǎn) newNode 的 next 指針指向了源節(jié)點(diǎn)的鄰接表的頭部。這樣,新節(jié)點(diǎn)就被插入到了鄰接表的頭部位置。
// nodes[sourceIndex].head = newNode;:
// 接著,這行代碼將源節(jié)點(diǎn)的鄰接表的頭指針指向了新節(jié)點(diǎn) newNode。這樣,新節(jié)點(diǎn)就成為了鄰接表的新的頭部,而原來的鄰接表頭部節(jié)點(diǎn)成為了新節(jié)點(diǎn)的下一個(gè)節(jié)點(diǎn),從而完成了插入操作。// 當(dāng)你有一個(gè)指向?qū)ο蟮闹羔槙r(shí),你可以使用 -> 運(yùn)算符來訪問該對象的成員,
// 而不必先解引用指針再使用 . 運(yùn)算符。這在處理動(dòng)態(tài)分配的對象時(shí)特別有用,因?yàn)槟阃ǔ?huì)使用指針來引用它們。// -> 是 C++ 中用于訪問對象成員的運(yùn)算符,通常用于訪問類的成員或者指向?qū)ο蟮闹羔樀某蓡T。
// 在這個(gè)語境中,newNode->next 是指針 newNode 所指向的對象的成員 next。
// 也就是說,newNode->next 表示訪問 newNode 指向的鄰接表節(jié)點(diǎn)的下一個(gè)節(jié)點(diǎn)的指針。// -> 符號(hào)用于訪問指針的成員。在這里,newNode 是指向 AdjListNode 對象的指針,我們想訪問它的 next 成員。
// -> 符號(hào)與 .(->) 等價(jià),但它是一種簡寫方式來訪問指針的成員。
// 因此,newNode->next 等價(jià)于 (newNode)->next。它說的是“從 newNode 指向的對象中找出 next 成員”// 什么是 pair ?
// pair 是一個(gè)結(jié)構(gòu)體,可以存儲(chǔ)兩個(gè)對象的 key-value對。
// 每個(gè) pair 對象包含兩個(gè)成員:
// first:一個(gè)對象,存儲(chǔ)在 first 中。
// second:另一個(gè)對象,存儲(chǔ)在 second 中。
// 為什么使用 pair
// pair 可以用于存儲(chǔ) key-value對,可以將一個(gè)對象與一個(gè)哈希表一起使用。
// pair 可以用于存儲(chǔ)多個(gè)哈希表中的鍵,可以用于實(shí)現(xiàn)哈希表。// vector如何表示其他的容器類型?請?jiān)敿?xì)列出
// 在C++中,vector是一個(gè)能夠存儲(chǔ)任何類型元素的動(dòng)態(tài)數(shù)組。你可以使用模板來表示不同的容器類型。例如:
// #include <vector>
// #include <list>
// #include <deque>
// #include <set>
// int main() {
//     // 整型向量
//     std::vector<int> intVector;
//     // 字符串向量
//     std::vector<std::string> stringVector;
//     // 列表容器的向量
//     std::vector<std::list<int>> listOfIntsVector;
//     // 雙端隊(duì)列容器的向量
//     std::vector<std::deque<double>> dequeOfDoublesVector;
//     // 集合容器的向量
//     std::vector<std::set<std::string>> setOfStringVector;
//     // 你也可以創(chuàng)建自定義類型的向量
//     class MyClass {};
//     std::vector<MyClass> myClassVector;
//     return 0;
// }// // 聲明一個(gè)空的 vector 存儲(chǔ) int 類型
// std::vector<int> v1;
// // 聲明一個(gè)帶有初始大小的 vector,所有元素初始化為 0
// std::vector<int> v2(10);  // 10 個(gè)元素的 vector,全部初始化為 0
// // 聲明一個(gè)帶有初始大小和初始值的 vector
// std::vector<int> v3(5, 42);  // 5 個(gè)元素的 vector,全部初始化為 42
// // 通過列表初始化聲明并初始化 vector
// std::vector<int> v4 = {1, 2, 3, 4, 5};  // 直接使用列表初始化
// // 通過拷貝另一個(gè) vector 初始化
// std::vector<int> v5(v4);  // v5 是 v4 的拷貝
// // 從迭代器范圍初始化
// std::vector<int> v6(v4.begin(), v4.begin() + 3);  // 只取 v4 的前 3 個(gè)元素
// // 常用操作
// v1.push_back(10);  // 在 vector 尾部添加一個(gè)元素
// v1.push_back(20);  // 添加另一個(gè)元素// vector 是一個(gè)非常靈活和強(qiáng)大的容器,可以存儲(chǔ)基本數(shù)據(jù)類型(如整數(shù)、浮點(diǎn)數(shù)等)和自定義的對象。它支持存儲(chǔ)各種類型的數(shù)據(jù),包括:
// 在C++中,std::vector是一個(gè)序列容器,它可以存儲(chǔ)任何類型的對象,包括基本數(shù)據(jù)類型、標(biāo)準(zhǔn)庫中的容器類型,以及自定義類型。
// 在C++中,可以使用向量(vector)來表示其他容器類型,通過將其他容器類型作為向量的元素來實(shí)現(xiàn)。
// 這樣做的好處是可以靈活地存儲(chǔ)和管理不同類型的容器,使得數(shù)據(jù)結(jié)構(gòu)更加動(dòng)態(tài)和通用。// 基本數(shù)據(jù)類型:如整數(shù)、浮點(diǎn)數(shù)、布爾值等
// 自定義對象:可以創(chuàng)建自定義的對象,并將其存儲(chǔ)在 vector 中
// 其他容器類型:如 std::list、std::deque、std::set 等,可以將這些容器存儲(chǔ)在另一個(gè) vector 中
// vector 的這種靈活性和強(qiáng)大性,讓其成為 C++ 中最廣泛使用的容器之一。// 此外,vector 還提供了許多有用的成員函數(shù)和操作符,例如:
// push_back:將元素添加到 vector 的末尾
// push_front:將元素添加到 vector 的開頭
// insert:將元素插入到 vector 的指定位置
// erase:從 vector 中刪除指定的元素
// resize:將 vector 的大小更改為指定的值
// at:訪問 vector 中指定索引的元素
// operator[]:訪問 vector 中指定索引的元素
// 這些成員函數(shù)和操作符使得 vector 成為了 C++ 中一個(gè)非常有用的工具,可以用于各種情況下存儲(chǔ)和操作數(shù)據(jù)。// C++ 中的 vector 是一個(gè)非常有用的標(biāo)準(zhǔn)庫容器,用于存儲(chǔ)動(dòng)態(tài)大小的元素序列。它的功能類似于數(shù)組,但具有更強(qiáng)大的特性和靈活性。
// vector 是一個(gè)數(shù)組的容器,可以存儲(chǔ)多個(gè)對象。
// 可以存儲(chǔ)任何類型的對象,包括基本類型、對象和結(jié)構(gòu)體。// 特點(diǎn)和優(yōu)勢:
// 動(dòng)態(tài)大小: vector 的大小可以動(dòng)態(tài)增長或減小,不像靜態(tài)數(shù)組需要提前定義大小。
// 隨機(jī)訪問: 可以使用索引對 vector 中的元素進(jìn)行快速訪問,時(shí)間復(fù)雜度為 O(1)。
// 內(nèi)存管理: vector 會(huì)自動(dòng)處理內(nèi)存的分配和釋放,無需手動(dòng)管理內(nèi)存。
// 可變操作: 可以在任何位置插入、刪除元素,也可以修改元素的值。
// 迭代器支持: 支持迭代器,可以方便地對 vector 進(jìn)行遍歷和操作。// 常用方法和操作:
// push_back(element): 在末尾添加元素。
// pop_back(): 移除末尾元素。
// size(): 返回元素個(gè)數(shù)。
// empty(): 判斷是否為空。
// clear(): 清空所有元素。
// front(): 返回第一個(gè)元素的引用。
// back(): 返回最后一個(gè)元素的引用。
// insert(pos, element): 在指定位置插入元素。
// erase(pos): 移除指定位置的元素。
// begin(), end(): 返回迭代器,用于遍歷 vector。
// vector 的靈活性和方便的操作使其成為 C++ 中常用的容器之一,特別適用于需要?jiǎng)討B(tài)管理大小的情況。

A -> B -> nullptr
B -> C -> nullptr
C -> D -> A -> nullptr
D -> A -> nullptr
E -> nullptr
請按任意鍵繼續(xù). . .

// 該程序用于實(shí)現(xiàn)一個(gè)簡單的圖(Graph)的數(shù)據(jù)結(jié)構(gòu),圖中包含多個(gè)節(jié)點(diǎn),每個(gè)節(jié)點(diǎn)具有一個(gè)名稱,并且每個(gè)節(jié)點(diǎn)可以與其他節(jié)點(diǎn)相連,以表示圖中邊的關(guān)系
// 節(jié)點(diǎn)(Node)和鄰接表(AdjListNode)
// Node:每個(gè) Node 對象具有兩個(gè)成員變量:一個(gè)字符串變量 name,用于保存節(jié)點(diǎn)的名稱,以及一個(gè)指針變量 head,用于指向該節(jié)點(diǎn)的鄰接表。
// AdjListNode:每個(gè) AdjListNode 對象具有兩個(gè)成員變量:一個(gè)字符串變量 name,用于保存鄰接節(jié)點(diǎn)的名稱,以及一個(gè)指針變量 next,用于指向下一個(gè)鄰接節(jié)點(diǎn)。


// 這兩行代碼一起完成了將新創(chuàng)建的鄰接表節(jié)點(diǎn)插入到源節(jié)點(diǎn)的鄰接表的頭部的操作:
// newNode->next = nodes[sourceIndex].head;:
// 這行代碼將新節(jié)點(diǎn) newNode 的 next 指針指向了源節(jié)點(diǎn)的鄰接表的頭部。這樣,新節(jié)點(diǎn)就被插入到了鄰接表的頭部位置。
// nodes[sourceIndex].head = newNode;:
// 接著,這行代碼將源節(jié)點(diǎn)的鄰接表的頭指針指向了新節(jié)點(diǎn) newNode。這樣,新節(jié)點(diǎn)就成為了鄰接表的新的頭部,而原來的鄰接表頭部節(jié)點(diǎn)成為了新節(jié)點(diǎn)的下一個(gè)節(jié)點(diǎn),從而完成了插入操作。

---------

// 改進(jìn)后的代碼主要做了以下幾點(diǎn)改進(jìn):

// 引入了 unordered_map 哈希表來存儲(chǔ)節(jié)點(diǎn),以提高節(jié)點(diǎn)查找效率。
// 使用了智能指針 shared_ptr 來管理節(jié)點(diǎn)和鄰接表節(jié)點(diǎn)的內(nèi)存,避免了手動(dòng)內(nèi)存管理和可能的內(nèi)存泄漏問題。
// 對節(jié)點(diǎn)和邊的添加操作進(jìn)行了有效性檢查,防止添加不存在的節(jié)點(diǎn)之間的邊。
// 使用了范圍-based for 循環(huán)來遍歷節(jié)點(diǎn)哈希表,代碼更加簡潔。
// 增加了注釋以說明代碼的作用和改進(jìn)部分。

#include <iostream>
#include <string>
#include <vector>
#include <unordered_map> // 引入哈希表
#include <memory>        // 引入智能指針using namespace std;// 鄰接表節(jié)點(diǎn)結(jié)構(gòu)
struct AdjListNode {string name;             // 節(jié)點(diǎn)名稱shared_ptr<AdjListNode> next;  // 指向下一個(gè)鄰接節(jié)點(diǎn)的智能指針// 構(gòu)造函數(shù)AdjListNode(string name) : name(name), next(nullptr) {}
};// 圖的節(jié)點(diǎn)結(jié)構(gòu)
struct Node {string name;              // 節(jié)點(diǎn)名稱shared_ptr<AdjListNode> head;  // 指向鄰接表頭部的智能指針// 構(gòu)造函數(shù)Node(string name) : name(name), head(nullptr) {}
};// 圖類
class Graph {
private:unordered_map<string, shared_ptr<Node>> nodes; // 使用哈希表存儲(chǔ)節(jié)點(diǎn),提高節(jié)點(diǎn)查找效率public:// 添加節(jié)點(diǎn)到圖中void addNode(const string& nodeName) {// 檢查節(jié)點(diǎn)是否已存在if (nodes.find(nodeName) == nodes.end()) {nodes[nodeName] = make_shared<Node>(nodeName); // 使用智能指針管理節(jié)點(diǎn)}}// 添加邊到圖中void addEdge(const string& source, const string& dest) {// 檢查源節(jié)點(diǎn)和目標(biāo)節(jié)點(diǎn)是否存在if (nodes.find(source) != nodes.end() && nodes.find(dest) != nodes.end()) {// 創(chuàng)建新的鄰接表節(jié)點(diǎn),表示目標(biāo)節(jié)點(diǎn)shared_ptr<AdjListNode> newNode = make_shared<AdjListNode>(dest);//  這行代碼的作用是將新節(jié)點(diǎn)的 next 指針指向源節(jié)點(diǎn)的鄰接表的頭部節(jié)點(diǎn),即將新節(jié)點(diǎn)插入到鄰接表的頭部。// 代碼的目的是將新節(jié)點(diǎn) newNode 的 next 指針指向了原來的鏈表頭部節(jié)點(diǎn)(如果存在的話),以便在將新節(jié)點(diǎn)插入到鏈表頭部后,新節(jié)點(diǎn)的下一個(gè)節(jié)點(diǎn)是原來的鏈表頭部節(jié)點(diǎn)。newNode->next = nodes[source]->head; // 將新節(jié)點(diǎn)插入到源節(jié)點(diǎn)的-鄰接表頭部nodes[source]->head = newNode;// 如果要支持無向圖,還需添加下面這段代碼// newNode = make_shared<AdjListNode>(source);// newNode->next = nodes[dest]->head;// nodes[dest]->head = newNode;}}// 打印圖的鄰接表void printGraph() {for (const auto& pair : nodes) {                     // 遍歷節(jié)點(diǎn)哈希表cout << pair.first << " -> ";                     // 打印節(jié)點(diǎn)名稱shared_ptr<AdjListNode> current = pair.second->head; // 獲取當(dāng)前節(jié)點(diǎn)的鄰接表頭部while (current) {                                // 遍歷鄰接表cout << current->name;                       // 打印鄰接節(jié)點(diǎn)的名稱if (current->next) cout << " -> ";           // 如果存在下一個(gè)節(jié)點(diǎn),打印箭頭else cout << " -> nullptr";                  // 否則打印鏈表末尾current = current->next;                     // 移動(dòng)到下一個(gè)鄰接節(jié)點(diǎn)}if (!pair.second->head) cout << "nullptr";       // 如果當(dāng)前節(jié)點(diǎn)沒有鄰接節(jié)點(diǎn),則輸出 nullptrcout << endl;                                    // 換行}}
};int main() {Graph graph;           // 創(chuàng)建圖對象graph.addNode("A");    // 添加節(jié)點(diǎn)graph.addNode("B");graph.addNode("C");graph.addNode("D");graph.addNode("E");graph.addEdge("A", "B"); // 添加邊graph.addEdge("B", "C");graph.addEdge("C", "A");graph.addEdge("C", "D");graph.addEdge("D", "A");graph.printGraph();    // 打印圖的鄰接表return 0;
}
// 改進(jìn)后的代碼主要做了以下幾點(diǎn)改進(jìn):// 引入了 unordered_map 哈希表來存儲(chǔ)節(jié)點(diǎn),以提高節(jié)點(diǎn)查找效率。
// 使用了智能指針 shared_ptr 來管理節(jié)點(diǎn)和鄰接表節(jié)點(diǎn)的內(nèi)存,避免了手動(dòng)內(nèi)存管理和可能的內(nèi)存泄漏問題。
// 對節(jié)點(diǎn)和邊的添加操作進(jìn)行了有效性檢查,防止添加不存在的節(jié)點(diǎn)之間的邊。
// 使用了范圍-based for 循環(huán)來遍歷節(jié)點(diǎn)哈希表,代碼更加簡潔。
// 增加了注釋以說明代碼的作用和改進(jìn)部分。// 原有的鏈表頭部節(jié)點(diǎn)并沒有丟失或刪除,而是被重新連接到了新插入的節(jié)點(diǎn)后面。讓我用更詳細(xì)的方式解釋一下:
// 假設(shè)我們有一個(gè)鏈表,頭部節(jié)點(diǎn)是 A,它的下一個(gè)節(jié)點(diǎn)是 B,而我們要在 A 的前面插入一個(gè)新節(jié)點(diǎn) X。
// 初始狀態(tài):
// A -> B
// 現(xiàn)在我們要在 A 的前面插入 X:
// 我們先將 X 的 next 指針指向原來 A 的下一個(gè)節(jié)點(diǎn) B:
// X -> B
// 然后我們將 A 的 next 指針指向 X:
// A -> X -> B
// 這樣,我們成功地在鏈表的頭部插入了新的節(jié)點(diǎn) X,同時(shí)保留了原來的節(jié)點(diǎn)順序。
// 原來的頭部節(jié)點(diǎn) A 現(xiàn)在變成了新節(jié)點(diǎn) X 的下一個(gè)節(jié)點(diǎn),它沒有被丟失或刪除,只是它的位置改變了。// 理解指針的操作可以有一些技巧,特別是在涉及鏈表這樣的數(shù)據(jù)結(jié)構(gòu)時(shí)。讓我嘗試用更詳細(xì)的步驟來解釋這段代碼中指針的操作過程。
// 假設(shè)我們有一個(gè)圖的鄰接表,每個(gè)節(jié)點(diǎn) `nodes[i]` 都包含一個(gè)指向鏈表頭部的指針 `head`,其中鏈表的每個(gè)節(jié)點(diǎn)表示一個(gè)與節(jié)點(diǎn) `i` 相鄰的節(jié)點(diǎn)。
// 現(xiàn)在來看看這段代碼的每一步:
// 1. **新建節(jié)點(diǎn) `newNode`**:
//    shared_ptr<AdjListNode> newNode = make_shared<AdjListNode>(destination);
//    這行代碼創(chuàng)建了一個(gè)新的節(jié)點(diǎn) `newNode`,并將目標(biāo)節(jié)點(diǎn) `destination` 作為其參數(shù)。
// 2. **將新節(jié)點(diǎn)插入到鄰接表的頭部**:
//    newNode->next = nodes[source]->head;
//    nodes[source]->head = newNode;
//    - `nodes[source]->head` 表示源節(jié)點(diǎn) `source` 的鄰接表的頭部指針。初始時(shí),這個(gè)指針可能是 `nullptr`,即該節(jié)點(diǎn)的鄰接表為空。
//    - `newNode->next = nodes[source]->head;` 這行代碼將新節(jié)點(diǎn) `newNode` 的 `next` 指針指向了源節(jié)點(diǎn) `source` 的鄰接表的頭部節(jié)點(diǎn)。
//    這意味著新節(jié)點(diǎn) `newNode` 現(xiàn)在指向原先作為頭部的節(jié)點(diǎn)(如果存在的話,否則指向 `nullptr`)。
//    - `nodes[source]->head = newNode;` 這行代碼將源節(jié)點(diǎn) `source` 的鄰接表的頭部指針 `head` 指向了新插入的節(jié)點(diǎn) `newNode`。
//    現(xiàn)在,新節(jié)點(diǎn) `newNode` 成為了鄰接表的頭部節(jié)點(diǎn),而原來的頭部節(jié)點(diǎn)(如果存在的話)則成為了新節(jié)點(diǎn) `newNode` 的下一個(gè)節(jié)點(diǎn)。
// 所以,這段代碼的目的是將新節(jié)點(diǎn) `newNode` 插入到源節(jié)點(diǎn) `source` 的鄰接表的頭部位置,以構(gòu)建源節(jié)點(diǎn) `source` 的鄰接表鏈表。
// 這種操作是在圖的鄰接表表示中常見的方式,用于將新的鄰接節(jié)點(diǎn)添加到某個(gè)節(jié)點(diǎn)的鄰接表中。

http://m.aloenet.com.cn/news/45160.html

相關(guān)文章:

  • 《原始傳奇》官方網(wǎng)站seo推廣工具
  • 鐵嶺做網(wǎng)站信息網(wǎng)店推廣的渠道有哪些
  • 長治市人民政府門戶網(wǎng)站簡單的網(wǎng)站制作
  • 網(wǎng)站源碼推薦谷歌sem
  • 汽車網(wǎng)站更新怎么做口碑營銷的例子
  • 鄭州展廳設(shè)計(jì)制作公司seo綜合查詢什么意思
  • 旅游類網(wǎng)站如何做推廣百度推廣后臺(tái)
  • 目錄網(wǎng)站模板php搭建一個(gè)簡單的網(wǎng)站
  • iis7建立網(wǎng)站可以看封禁網(wǎng)站的瀏覽器
  • 做網(wǎng)站公司排名電話國際新聞快報(bào)
  • 外貿(mào)網(wǎng)站建設(shè)模板百度云客服人工電話
  • 企業(yè)網(wǎng)站注冊官網(wǎng)百度搜索結(jié)果優(yōu)化
  • 網(wǎng)站如何做微信支付寶支付寶支付社交網(wǎng)絡(luò)的推廣方法
  • 深圳云網(wǎng)站建站公司搜索引擎的設(shè)計(jì)與實(shí)現(xiàn)
  • 搜狐一開始把網(wǎng)站當(dāng)做什么來做站長之家官網(wǎng)
  • 校園網(wǎng)站建設(shè)招標(biāo)公告企業(yè)網(wǎng)站推廣方案
  • 網(wǎng)站建設(shè)實(shí)訓(xùn)過程報(bào)告有什么好的推廣平臺(tái)
  • 合肥高端網(wǎng)站開發(fā)做一個(gè)企業(yè)網(wǎng)站大概需要多少錢
  • thinkphp 網(wǎng)站根目錄地址免費(fèi)網(wǎng)絡(luò)推廣網(wǎng)站
  • o2o網(wǎng)站建設(shè)流程理發(fā)培訓(xùn)專業(yè)學(xué)校
  • 網(wǎng)站建設(shè)價(jià)值長沙seo優(yōu)化推廣
  • 沒有備案的網(wǎng)站 推廣牛排seo
  • 什么網(wǎng)站可以免費(fèi)做視頻的軟件有哪些免費(fèi)學(xué)生網(wǎng)頁制作成品代碼
  • 網(wǎng)站建設(shè)的目的分析國內(nèi)新聞最新消息今天簡短
  • 自己做網(wǎng)站賣閥門網(wǎng)絡(luò)營銷方案的制定
  • 找人建個(gè)網(wǎng)站多少錢semantic ui
  • 如何減少網(wǎng)站建設(shè)中的錯(cuò)誤廣東東莞疫情最新情況
  • wdcp裝wordpress502小時(shí)seo
  • 國內(nèi)b2b電商平臺(tái)seo專業(yè)課程
  • 醫(yī)療網(wǎng)站做藥品是干嘛搜索引擎營銷的案例有哪些