C++读图txt文件,并将数据结构 图显示出来
生活随笔
收集整理的這篇文章主要介紹了
C++读图txt文件,并将数据结构 图显示出来
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
目錄
整個代碼展示
下面分別是圖的兩個txt文件,現在用C++讀取這個文件,并將圖顯示出來
第一行分別表示圖的節點數和邊數
13 13 0 5 4 3 0 1 9 12 6 4 5 4 0 2 11 12 9 10 0 6 7 8 9 11 5 3 6 8 0 1 0 2 0 5 1 2 1 3 1 4 3 4 3 5
?
代碼中模板Graph,可以是稀疏圖或者稠密的實現,參考連接:https://blog.csdn.net/SHAOYEZUIZUISHAUI/article/details/103079932
下列代碼需要聲明庫
#include <fstream> #include <sstream>//適用于稀疏圖和稠密圖的泛型讀圖編程實現 template <typename Graph> class ReadGraph { public:ReadGraph(Graph &g,const string &filetxt){//讀取文件ifstream file(filetxt);//存儲文件每行的數據string line;int V, E;//確認文件是否打開assert(file.is_open());//將文件的第一行讀取到line中,確認是否讀取成功assert(getline(file, line));//將第一行輸入到stringstream中,解析出變量V,E,即文件中開頭第一行給出的stringstringstream ss(line);ss >> V >> E;//檢查讀取的點數和引用圖的點數是否是一致的assert(g.V() == V);for (int i = 0; i < E; i++){//讀取下一行assert(getline(file, line));stringstream ss(line);int a, b;ss >> a >> b;//如果a,b不越界assert(a >= 0 && a < V);assert(b >= 0 && b < V);g.AddEdge(a, b);}} private:};
整個代碼展示
Graph.h文件
#pragma once #include<vector> //稠密圖-鄰接矩陣class DenseGraph {private://n表示圖的點數,m表示圖的邊數int n, m;//表示是否是有向圖bool directed;//將變量放在了public權限中,因為遍歷方便//表示稀疏矩陣vector<vector<bool>>g;public:DenseGraph(int n, bool directed){this->n = n;this->m = 0;this->directed = directed;//初始化鄰接矩陣for (int i = 0; i < n; i++){g.push_back(vector<bool>(n, false));}}~DenseGraph(){}//給圖增加一條邊,前提是這兩個節點之間原來是沒有邊的void AddEdge(int a, int b){//檢查越界assert(a >= 0 && a < n);assert(b >= 0 && b < n);//判斷a,b之間是否有邊,如果已經存在邊,返回if (hasedge(a, b))return;//賦值g[a][b] = true;//判斷是否是有向圖if (!directed){g[b][a] = true;}//維護變量m++;}//兩個節點之間是否存在一條邊bool hasedge(int a, int b){//檢查越界assert(a >= 0 && a < n);assert(b >= 0 && b < n);return g[a][b];}//返回圖的邊數int E(){return m;}//返回圖的點數int V(){return n;}//展示圖void show(){cout << "==========DenseGraph===============" << endl;for (int i = 0; i < n; i++){cout << i << ": ";for (int j = 0; j < n; j++){cout << g[i][j]<<" ";}cout << endl;}}class adjIterator {private://定義一個圖的引用DenseGraph &G;//迭代器指向的節點int v;//當前迭代器指向的索引int index;public://初始化引用類型數據成員的唯一機會是在構造函數初始化列表中adjIterator(DenseGraph &g, int v) :G(g) {this->v = v;this->index = -1;}//迭代器的頭//返回第一個不為false的索引int begin() {//index 是這個類的屬性,只有賦值改變,才會改變,當幾點序列改變時,index得初始化index = -1;return next();}//迭代器下一個//返回下一個不為false的索引int next() {//index 是這個類的屬性,只有賦值改變,才會改變for (index += 1; index < G.V(); index++){if (G.g[v][index]){//為了返回下一個不為false的索引,下一次跳入循環后需要index+1,跳過剛剛返回的索引值return index;}}return -1;}//迭代的結尾//返回這個圖的總點數int end(){return index >= G.V();}};};//稀疏圖-鄰接表class SparseGraph{private://n 表示點,m表示邊int n, m;//判斷是否是有向圖int directed;//鄰接表vector<vector<int>>g;public:SparseGraph(int n, int directed){this->n = n;this->m = 0;this->directed = directed;for (int i = 0; i < n; i++){//將向量中的元素設為空g.push_back(vector<int>());}}~SparseGraph(){}//給圖添加一條邊,因為沒有考慮平行邊,所以該函數可能會導致平行邊void AddEdge(int a, int b){//檢查越界問題assert(a >= 0 && a < n);assert(b >= 0 && b < n);//如果兩點間存在邊,則返回,如果加了下列幾行代碼,則時間復雜度編程O(N),故一般不考慮平行邊,//if (hasEdge(a, b))// return ;//賦值g[a].push_back(b);//判斷是否是自環邊,或者是都是有向圖,只有非自環邊,或者無向圖,才滿足條件if (a != b && !directed)g[b].push_back(a);m++;}//判斷是否兩點是否存在邊bool hasEdge(int a, int b){//檢查越界問題assert(a >= 0 && a < n);assert(b >= 0 && b < n);for (int i = 0; i < g[a].size(); i++){if (g[a][i] == b){return true;}}return false;}//返回圖的邊數int E(){return m;}//返回圖的點數int V(){return n;}//展示圖void show(){cout << "==========SparseGraph===============" << endl;for (int i = 0; i < n; i++){cout << i << ": ";for (int j = 0; j < g[i].size(); j++){cout << g[i][j] << " ";}cout << endl;}}//鄰接表的迭代器類class adjIterator {private:SparseGraph &G;//當前迭代器節點的索引int v;//當前迭代器節點中的索引int index;public://初始化引用類型的數據成員,只能在構造函數的初始化列表中初始化adjIterator(SparseGraph &g, int v) :G(g){this->v = v;this->index = 0;}//迭代器的開始,返回當前節點中的第一個索引int begin(){//對于后面的節點,begin必須將index初始化為0才行index = 0;//此處不應該是G.V(),應該是對應每個節點中的多少個索引if (G.g[v].size())return G.g[v][index];//return -1;}//迭代器的迭代,返回當前節點中下一個索引int next(){index++;//此處不應該是G.V(),應該是對應每個節點中的多少個索引if (index < G.g[v].size())return G.g[v][index];//return -1;}//迭代器的接受int end(){return index >= G.g[v].size();}};};//適用于稀疏圖和稠密圖的泛型讀圖編程實現 template <typename Graph> class ReadGraph { public:ReadGraph(Graph &g,const string &filetxt){//讀取文件ifstream file(filetxt);//存儲文件每行的數據string line;int V, E;//確認文件是否打開assert(file.is_open());//將文件的第一行讀取到line中,確認是否讀取成功assert(getline(file, line));//將第一行輸入到stringstream中,解析出變量V,E,即文件中開頭第一行給出的stringstringstream ss(line);ss >> V >> E;//檢查讀取的點數和引用圖的點數是否是一致的assert(g.V() == V);for (int i = 0; i < E; i++){//讀取下一行assert(getline(file, line));stringstream ss(line);int a, b;ss >> a >> b;//如果a,b不越界assert(a >= 0 && a < V);assert(b >= 0 && b < V);g.AddEdge(a, b);}} private: };
主函數部分,除了上文提到的庫,還有一些常用的庫需要包含,自行添加
int main() {string filetext_0= "testG1.txt";DenseGraph g1(13, false);ReadGraph<DenseGraph> readgraph(g1, filetext_0);//跟后面迭代器一樣的功能,用來顯示打印圖g1.show();for (int i = 0; i < g1.V(); i++){cout << i << ": ";DenseGraph::adjIterator iterator(g1, i);for (int j = iterator.begin(); !iterator.end(); j = iterator.next()){cout << j << " ";}cout << endl;}cout << "============================" << endl;string filetext_1 = "testG2.txt";SparseGraph g2(6, false);ReadGraph<SparseGraph> readgraph_1(g2, filetext_1);//跟后面迭代器一樣的功能,用來顯示打印圖g2.show();for (int i = 0; i < g2.V(); i++){cout << i << " : ";SparseGraph::adjIterator iterator(g2, i);for (int j = iterator.begin(); !iterator.end(); j = iterator.next()){cout << j << " ";}cout << endl;} }
?
總結
以上是生活随笔為你收集整理的C++读图txt文件,并将数据结构 图显示出来的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: oracle数据库用户的删改查
- 下一篇: linux 查找pcre源码,apach