//圖節點信息 typedef struct Node{ int edge_num;//邊號 int src;//源點 int vertex;//自身 int weight;//邊的權重 }Node;
/******************************************************* * 類名稱: 鄰接表圖 ********************************************************/ class Graph{ private: int edge_num;//圖邊的個數 int vertex_num;//圖的頂點數目 list* graph_list;//鄰接表 public: Graph(){} Graph(char* graph[], int edgenum); ~Graph(); void print();//以鄰接表的形式打印圖信息 private: vector get_graph_value(char* graph[], int columns);//獲得每條邊的數據 void addEdge(char* graph[], int columns); };
0,0,1,1 1,0,2,2 2,0,3,1第1列為邊的標號,第2列為邊的起點,第3列為邊的終點,第4列為邊的權重。
/**************************************************************** * 函數名稱:read_file * 功能描述: 讀取文件中的圖的數據信息 * 參數列表: buff是將文件讀取的圖信息保存到buff指向的二維數組中 * spec是文件中圖最大允許的邊的個數 * filename是要打開的圖文件 * 返回結果:無 *****************************************************************/ int read_file(char ** const buff, const unsigned int spec, const char * const filename) { FILE *fp = fopen(filename, "r"); if (fp == NULL) { printf("Fail to open file %s, %s.\n", filename, strerror(errno)); return 0; } printf("Open file %s OK.\n", filename); char line[MAX_LINE_LEN + 2]; unsigned int cnt = 0; while ((cnt < spec) && !feof(fp)) { line[0] = 0; fgets(line, MAX_LINE_LEN + 2, fp); if (line[0] == 0) continue; buff[cnt] = (char *)malloc(MAX_LINE_LEN + 2); strncpy(buff[cnt], line, MAX_LINE_LEN + 2 - 1); buff[cnt][4001] = 0; cnt++; } fclose(fp); printf("There are %d lines in file %s.\n", cnt, filename); return cnt; }
/**************************************************************** * 函數名稱:release_buff * 功能描述: 釋放剛才讀取的文件中的圖的數據信息 * 參數列表: buff是指向文件讀取的圖信息 * valid_item_num是指圖中邊的個數 * 返回結果:void *****************************************************************/ void release_buff(char ** const buff, const int valid_item_num) { for (int i = 0; i < valid_item_num; i++) free(buff[i]); }
int main(int argc, char *argv[]) { char *topo[5000]; int edge_num; char *demand; int demand_num; char *topo_file = argv[1]; edge_num = read_file(topo, 5000, topo_file); if (edge_num == 0) { printf("Please input valid topo file.\n"); return -1; } Graph G(topo, edge_num);//創建一個圖對象G G.print();//以鄰接表的形式打印圖信息 release_buff(topo, edge_num); return 0; }
#ifndef GRAPH_H #define GRAPH_H #include#include
#include #include #include #include #include #include #include #include #include using namespace std; #define MAX_VERTEX_NUM 600 //圖節點信息 typedef struct Node{ int edge_num;//邊號 int src;//源點 int vertex;//自身 int weight;//邊的權重 }Node; /******************************************************* * 類名稱: 鄰接表圖 ********************************************************/ class Graph{ private: int edge_num;//圖邊的個數 int vertex_num;//圖的頂點數目 list * graph_list;//鄰接表 public: Graph(){} Graph(char* graph[], int edgenum); ~Graph(); void print();//以鄰接表的形式打印圖信息 private: vector get_graph_value(char* graph[], int columns);//獲得每條邊的數據 void addEdge(char* graph[], int columns); }; /************************************************* 函數名稱:print 功能描述:將圖的信息以鄰接表的形式輸出到標准輸出 參數列表:無 返回結果:無 *************************************************/ void Graph::print() { cout << "******************************************************************" << endl; //for(int i = 0 ; i < MAX_VERTEX_NUM; ++i){ for(int i = 0 ; i < vertex_num; ++i){ if(graph_list[i].begin() != graph_list[i].end()){ cout << i << "-->"; for(list ::iterator it = graph_list[i].begin(); it != graph_list[i].end(); ++it){ cout << (*it).vertex << "(邊號:" << (*it).edge_num << ",權重:" << (*it).weight << ")-->"; } cout << "NULL" << endl; } } cout << "******************************************************************" << endl; } /************************************************* 函數名稱:get_graph_value 功能描述:將圖的每一條邊的信息保存到一個數組中 參數列表: graph:指向圖信息的二維數組 columns:圖的第幾條邊 返回結果:無 *************************************************/ vector Graph::get_graph_value(char* graph[], int columns) { vector v; char buff[20]; int i = 0, j = 0, val; memset(buff, 0, 20); while((graph[columns][i] != '\n') && (graph[columns][i] != '\0')){ if(graph[columns][i] != ','){ buff[j] = graph[columns][i]; j++; } else{ j = 0; val = atoi(buff); v.push_back(val); memset(buff, 0, 20); } i++; } val = atoi(buff); v.push_back(val); return v; } /************************************************* 函數名稱:addEdge 功能描述:將圖的每一條邊的信息加入圖的鄰接表中 參數列表:graph:指向圖信息的二維數組 columns:圖的第幾條邊 返回結果:無 *************************************************/ void Graph::addEdge(char* graph[], int columns) { Node node; vector v = get_graph_value(graph, columns); node.edge_num = v[0]; node.src = v[1]; node.vertex = v[2]; node.weight = v[3]; if(node.vertex > vertex_num) vertex_num = node.vertex; //要考慮重復的邊,但是邊的權重不一樣 for(list ::iterator it = graph_list[node.src].begin(); it != graph_list[node.src].end(); ++it){ if((*it).vertex == node.vertex){ if((*it).weight > node.weight){ (*it).weight = node.weight; } return; } } graph_list[node.src].push_back(node); } /************************************************* 函數名稱:構造函數 功能描述:以鄰接表的形式保存圖的信息,並保存必須經過的頂點 參數列表:graph:指向圖信息的二維數組 edgenum:圖的邊的個數 返回結果:無 *************************************************/ Graph::Graph(char* graph[], int edgenum) { edge_num = edgenum; vertex_num = 0; graph_list = new list [MAX_VERTEX_NUM+1]; for(int i = 0; i < edgenum; ++i){ addEdge(graph, i); } vertex_num++; } /************************************************* 函數名稱:析構函數 功能描述:釋放動態分配的內存 參數列表:無 返回結果:無 *************************************************/ Graph::~Graph() { delete[] graph_list; } #endif
#include#include #include #include #include #include #include #include #include #include #include "graph.h" #define MAX_LINE_LEN 4000 int read_file(char ** const buff, const unsigned int spec, const char * const filename); void release_buff(char ** const buff, const int valid_item_num); int main(int argc, char *argv[]) { char *topo[5000]; int edge_num; char *demand; int demand_num; char *topo_file = argv[1]; edge_num = read_file(topo, 5000, topo_file); if (edge_num == 0) { printf("Please input valid topo file.\n"); return -1; } Graph G(topo, edge_num);//創建一個圖對象G G.print();//以鄰接表的形式打印圖信息 release_buff(topo, edge_num); return 0; } /**************************************************************** * 函數名稱:read_file * 功能描述: 讀取文件中的圖的數據信息 * 參數列表: buff是將文件讀取的圖信息保存到buff指向的二維數組中 * spec是文件中圖最大允許的邊的個數 * filename是要打開的圖文件 * 返回結果:無 *****************************************************************/ int read_file(char ** const buff, const unsigned int spec, const char * const filename) { FILE *fp = fopen(filename, "r"); if (fp == NULL) { printf("Fail to open file %s, %s.\n", filename, strerror(errno)); return 0; } printf("Open file %s OK.\n", filename); char line[MAX_LINE_LEN + 2]; unsigned int cnt = 0; while ((cnt < spec) && !feof(fp)) { line[0] = 0; fgets(line, MAX_LINE_LEN + 2, fp); if (line[0] == 0) continue; buff[cnt] = (char *)malloc(MAX_LINE_LEN + 2); strncpy(buff[cnt], line, MAX_LINE_LEN + 2 - 1); buff[cnt][4001] = 0; cnt++; } fclose(fp); printf("There are %d lines in file %s.\n", cnt, filename); return cnt; } /**************************************************************** * 函數名稱:release_buff * 功能描述: 釋放剛才讀取的文件中的圖的數據信息 * 參數列表: buff是指向文件讀取的圖信息 * valid_item_num是指圖中邊的個數 * 返回結果:void *****************************************************************/ void release_buff(char ** const buff, const int valid_item_num) { for (int i = 0; i < valid_item_num; i++) free(buff[i]); }
0,0,1,1 1,0,2,2 2,0,3,1 3,2,1,3 4,3,1,1 5,2,3,1 6,3,2,1 7,3,0,1
0,0,13,15 1,0,8,17 2,0,19,1 3,0,4,8 4,1,0,4 5,2,9,19 6,2,15,8 7,3,0,14 8,3,11,12 9,4,1,15 10,4,5,17 11,5,8,18 12,5,9,14 13,5,6,2 14,6,17,4 15,7,13,1 16,7,16,19 17,8,6,1 18,8,12,17 19,9,14,11 20,10,12,1 21,11,7,12 22,11,4,7 23,12,14,5 24,13,17,12 25,13,4,2 26,14,19,9 27,15,10,14 28,15,18,2 29,16,8,1 30,17,9,14 31,17,19,3 32,17,18,10 33,18,15,8 34,18,3,8 35,19,18,12 36,2,3,20 37,3,5,20 38,5,7,20 39,7,11,20 40,11,13,20 41,17,11,20 42,11,19,20 43,17,5,20 44,5,19,20
root@linux_ever:~/linux_ever/algorithm/graph_ch9# ls case0 case1 graph.h testGraph testGraph.cpp root@linux_ever:~/linux_ever/algorithm/graph_ch9# ./testGraph ./case0/topo.csv Open file ./case0/topo.csv OK. There are 8 lines in file ./case0/topo.csv. ****************************************************************** 0-->1(邊號:0,權重:1)-->2(邊號:1,權重:2)-->3(邊號:2,權重:1)-->NULL 2-->1(邊號:3,權重:3)-->3(邊號:5,權重:1)-->NULL 3-->1(邊號:4,權重:1)-->2(邊號:6,權重:1)-->0(邊號:7,權重:1)-->NULL ****************************************************************** root@linux_ever:~/linux_ever/algorithm/graph_ch9# ./testGraph ./case1/topo.csv Open file ./case1/topo.csv OK. There are 45 lines in file ./case1/topo.csv. ****************************************************************** 0-->13(邊號:0,權重:15)-->8(邊號:1,權重:17)-->19(邊號:2,權重:1)-->4(邊號:3,權重:8)-->NULL 1-->0(邊號:4,權重:4)-->NULL 2-->9(邊號:5,權重:19)-->15(邊號:6,權重:8)-->3(邊號:36,權重:20)-->NULL 3-->0(邊號:7,權重:14)-->11(邊號:8,權重:12)-->5(邊號:37,權重:20)-->NULL 4-->1(邊號:9,權重:15)-->5(邊號:10,權重:17)-->NULL 5-->8(邊號:11,權重:18)-->9(邊號:12,權重:14)-->6(邊號:13,權重:2)-->7(邊號:38,權重:20)-->19(邊號:44,權重:20)-->NULL 6-->17(邊號:14,權重:4)-->NULL 7-->13(邊號:15,權重:1)-->16(邊號:16,權重:19)-->11(邊號:39,權重:20)-->NULL 8-->6(邊號:17,權重:1)-->12(邊號:18,權重:17)-->NULL 9-->14(邊號:19,權重:11)-->NULL 10-->12(邊號:20,權重:1)-->NULL 11-->7(邊號:21,權重:12)-->4(邊號:22,權重:7)-->13(邊號:40,權重:20)-->19(邊號:42,權重:20)-->NULL 12-->14(邊號:23,權重:5)-->NULL 13-->17(邊號:24,權重:12)-->4(邊號:25,權重:2)-->NULL 14-->19(邊號:26,權重:9)-->NULL 15-->10(邊號:27,權重:14)-->18(邊號:28,權重:2)-->NULL 16-->8(邊號:29,權重:1)-->NULL 17-->9(邊號:30,權重:14)-->19(邊號:31,權重:3)-->18(邊號:32,權重:10)-->11(邊號:41,權重:20)-->5(邊號:43,權重:20)-->NULL 18-->15(邊號:33,權重:8)-->3(邊號:34,權重:8)-->NULL 19-->18(邊號:35,權重:12)-->NULL ******************************************************************輸出結果的每一行的第一列表示各個頂點的標號。 比如: 0-->13(邊號:0,權重:15)-->8(邊號:1,權重:17)-->19(邊號:2,權重:1)-->4(邊號:3,權重:8)-->NULL 上面表示,頂點0到13的邊的邊號為0,權重為15。頂點0到頂點8的邊的邊號為1,權重為17。頂點0到頂點19的邊的邊號為2,權重為1。頂點0到頂點4的邊的邊號為3,權重為8。