// 邻接表类 #ifndef LIST_GRAPH_H #define LIST_GRAPH_H #include #include #include #include "GraphExceptions/InsertExistedConnectException.h" #include "GraphExceptions/NodeIdOutOfRangeException.h" #include "GraphExceptions/SameNodeConnectException.h" using namespace std; /* * 简述: * 节点=数据域+指针域 * 第一个节点存储id * 第二个节点存储值 * 后续节点存储连接关系 * 数据域: * data:可存id,可存其他节点的id,可存数据 * weight:边上的权 */ template class ListGraph { private: struct node { T data; T weight; struct node *next; }; vector nodes; bool flag; //定义是否有向 bool isWeighted; //定义是否有权 public: ListGraph(bool flag = false, bool isWeighted = false) { nodes.clear(); flag = false; isWeighted = false; this->flag = flag; this->isWeighted = isWeighted; } void insert(T data) { node *insert = new node(); insert->data = nodes.size(); insert->weight = 0; insert->next = new node(); insert->next->data = data; insert->next->next = NULL; nodes.push_back(insert); } void connect(int id1, int id2, T weight = 0) { //flag区分是否为有向图 if ((id1 > nodes.size() - 1 || id2 > nodes.size() - 1) || (id1 < 0) || (id2 < 0)) { throw NodeIdOutOfRangeException("您提供的id超出范围", 0X002); } if (id1 == id2) { throw SameNodeConnectException("禁止连接图中的同一个点", 0x001); } node *current = nodes.at(id1); //跳过id节点和值节点 for (int i = 0; i < 1; i++) { current = current->next; } while (current->next != NULL) { if (current->next->data == id2) { if (current->next->weight == weight) { throw InsertExistedConnectException("禁止插入已存在的连接", 0x003); } current->next->weight = weight; if (!flag) { node *current2 = nodes.at(id2); while (current2->next != NULL) { current2 = current2->next; } current2->next->weight = weight; } return; } current = current->next; } current->next = new node(); current->next->data = id2; current->next->weight = weight; current->next->next = NULL; if (!flag) { node *current2 = nodes.at(id2); while (current2->next != NULL) { current2 = current2->next; } current2->next = new node(); current2->next->data = id1; current2->next->weight = weight; current2->next->next = NULL; } } string to_string() { stringstream ss; for (int i = 0; i <= nodes.size() - 1; i++) { node *current = nodes.at(i); while (current != NULL) { if (current->next == NULL) { if (isWeighted) { ss << current->data << "|" << current->weight; } else { ss << current->data; } } else { if (isWeighted) { ss << current->data << "|" << current->weight << " "; } else { ss << current->data << " "; } } current = current->next; } ss << endl; } return ss.str(); } vector BFS(int startId) { if (startId >= nodes.size() || startId < 0) { throw NodeIdOutOfRangeException("起始节点id超出范围", 0X004); } vector visited(nodes.size(), false); queue q; vector result; // 标记起始节点已访问 visited[startId] = true; q.push(startId); while (!q.empty()) { int currentId = q.front(); q.pop(); result.push_back(currentId); node *current = nodes.at(currentId); // 跳过id节点和值节点 current = current->next->next; while (current != NULL) { int neighborId = current->data; if (!visited[neighborId]) { visited[neighborId] = true; q.push(neighborId); } current = current->next; } } return result; } }; #endif //LIST_GRAPH_H