// // Created by 31416 on 24-12-4. // #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; } 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<data<<"|"<weight; } else { ss<data; } }else { if (isWeighted){ ss<data<<"|"<weight<<" "; } else { ss<data<<" "; } } current = current->next; } ss< 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