#include #include #include #include #include"MyGraph.h" Edge::Edge() { VerAdj = -1; cost = -1; link = NULL; } int& Edge::get_VerAdj() { return VerAdj; } int& Edge::get_cost() { return cost; } Edge*& Edge::get_link() { return link; } Vertex::Vertex() { VerName = "*"; Description = "*"; adjacent = NULL; mark = x = y = -1; } std::string& Vertex::get_VerName() { return VerName; } std::string& Vertex::get_Description() { return Description; } Edge*& Vertex::get_adjacent() { return adjacent; } int& Vertex::get_mark() { return mark; } int& Vertex::get_x() { return x; } int& Vertex::get_y() { return y; } int& Graph_List::get_MaxCost() { return MaxCost; } Vertex* Graph_List::get_head() { return head; } IMAGE* Graph_List::get_map() { return map; } int Graph_List::get_index(int _mark) { for (int i = 0; i < graphsize; i++) { if (_mark == head[i].get_mark()) return i; } return -1; // 找不到返回-1 } int Graph_List::get_index(std::string name) { for (int i = 0; i < graphsize; i++) { if (name == head[i].get_VerName()) return i; } return -1; } int Graph_List::graph_con(std::fstream& file, char* mapname) { delete_Graph_List(); // 先把类里面的东西删掉 map = new IMAGE; loadimage(map, (LPCTSTR)mapname, 0, 0, false); // 载入图片 file >> MaxCost; file >> graphsize; head = new Vertex[graphsize]; for (int i = 0; i < graphsize; i++) { file >> head[i].get_VerName(); file >> head[i].get_Description(); file >> head[i].get_mark(); file >> head[i].get_x(); file >> head[i].get_y(); head[i].get_x() += LEFTBORDER; head[i].get_y() += TOPBORDER; head[i].get_adjacent() = NULL; } int edgenum; file >> edgenum; for (int j = 0; j < edgenum; j++) { int v1, v2, weight; file >> v1; file >> v2; double startx = head[get_index(v1)].get_x(); double starty = head[get_index(v1)].get_y(); double endx = head[get_index(v2)].get_x(); double endy = head[get_index(v2)].get_y(); weight = (double)sqrt((startx - endx) * (startx - endx) + (starty - endy) * (starty - endy)); insert_edge(get_index(v1), get_index(v2), weight); } return 0; } Graph_List::Graph_List() { head = NULL; map = new IMAGE; graphsize = 0; MaxCost = 0; } Graph_List::~Graph_List() { delete_Graph_List(); } int Graph_List::number_of_vertices()const { return graphsize; } int Graph_List::number_of_edges()const { int n = 0; for (int i = 0; i < graphsize; i++) { Edge* p = head[i].get_adjacent(); while (p) { n++; p = p->get_link(); } } return n / 2; } int Graph_List::save_file(char* filename) { system("del filename"); // 删除文件 std::ofstream fl(filename); // 打开文件,用于写,若不存在则创建 if (!fl) return -1; fl << get_MaxCost() << std::endl; // 文件中输出最大值 fl << number_of_vertices() << std::endl; // 文件中输出节点数 for (int i = 0; i < number_of_vertices(); i++) { fl << head[i].get_VerName() << "\t\t\t" << head[i].get_Description() << "\t\t\t\t\t\t" << head[i].get_mark() << "\t" << head[i].get_x() - LEFTBORDER << "\t" << head[i].get_y() - TOPBORDER << std::endl; // 对齐 } fl << std::endl; int num_of_edges = number_of_edges() * 2; // 无向边 * 2 = 有向边 fl << num_of_edges << std::endl; int num = 0; for (int j = 0; j < number_of_vertices(); j++) { Edge* p = head[j].get_adjacent(); while (p) { if (num == 5) { fl << std::endl; num = 0; } fl << get_head()[j].get_mark() << "\t" << get_head()[p->get_VerAdj()].get_mark() << std::endl; p = p->get_link(); num++; } } fl.close(); return 0; } bool Graph_List::is_graph_empty() { return graphsize == 0; } int Graph_List::get_weight(const int& v1, const int& v2) { if (v1 > graphsize - 1 || v2 > graphsize - 1 || v1 < 0 || v2 < 0) { return -1; } if (v1 == v2) return 0; Edge* p = head[v1].get_adjacent(); while (p != NULL && p->get_VerAdj() != v2) p = p->get_link(); if (p) return p->get_cost(); else return MaxCost + 1; // 两点之间没有边则返回此值 } void Graph_List::insert_vertex(std::string _name, std::string _des, int _mark, int _x, int _y) { Vertex* h = new Vertex[graphsize + 1]; // 创建一个新的顶点表 for (int i = 0; i < graphsize; i++) h[i] = head[i]; // 把新添加的顶点加在新定点表最后 h[graphsize].get_VerName() = _name; h[graphsize].get_Description() = _des; h[graphsize].get_mark() = _mark; h[graphsize].get_x() = _x; h[graphsize].get_y() = _y; h[graphsize].get_adjacent() = NULL; delete[] head; head = h; graphsize++; } int Graph_List::insert_edge(int v1, int v2, int weight) { if (v1 > graphsize - 1 || v2 > graphsize - 1 || v1 < 0 || v2 < 0) { return -1; // 插入元素超界返回-1 } if (weight > MaxCost) return -2; // 返回-2表示权值过大 if (v1 == v2) return -3; // 操作不合法 int i = insert_edge_do(v1, v2, weight); if (i == -4) return i; // 边已存在 insert_edge_do(v2, v1, weight); return i; } int Graph_List::delete_edge(int v2, int v1) { if (v1 > graphsize - 1 || v2 > graphsize - 1 || v1 < 0 || v2 < 0) { return -1; // 元素超界 } if (v1 == v2) return -1; int i = delete_edge_do(v1, v2); if (i == -1) return i; delete_edge_do(v2, v1); return i; } int Graph_List::delete_vertex(const int& v) { if (v > graphsize - 1 || v < 0) return -1; // 元素超界 for (int i = 0; i < graphsize; i++) delete_edge(i, v); // 删除该点所有边 for (int j = v; j <= graphsize - 2; j++) head[j] = head[j + 1]; // 把该顶点后的元素向前挪一个位置 graphsize--; for (int k = 0; k < graphsize - 1; k++) { Edge* p = head[k].get_adjacent(); while (p) { if (p->get_VerAdj() > v) p->get_VerAdj()--; p = p->get_link(); } } return 0; } int Graph_List::modify_vertex(int v, std::string _n, std::string _des, int& _m, int& _x, int& _y) { if (v < 0 || v > number_of_vertices() - 1) return -1; head[v].get_VerName() = _n; head[v].get_Description() = _des; head[v].get_mark() = _m; head[v].get_x() = _x; head[v].get_y() = _y; head[v].get_x() += LEFTBORDER; head[v].get_y() += TOPBORDER; return 0; } int Graph_List::dshortest_path(const int v, int*& path) { int n = graphsize; int* s = new int[n]; // 该节点是否访问过 int* dist = new int[n]; // 存放当前节点到其他节点的最短长度 int i = 0, temp = 0; for (i = 0; i < n; i++) { s[i] = 0; // 未访问节点为0 dist[i] = MaxCost * graphsize * (graphsize - 1) / 2; // 无穷大 path[i] = -1; // 路径数组 } int u = v; Edge* p = NULL; dist[u] = 0; s[u] = 1; path[u] = u; for (int i = 0; i < n; i++) { s[u] = 1; p = head[u].get_adjacent(); while (p) { temp = p->get_VerAdj(); if (dist[u] + p->get_cost() < dist[temp]) { dist[temp] = dist[u] + p->get_cost(); path[temp] = u; } p = p->get_link(); } temp = MaxCost * graphsize * (graphsize - 1) / 2; for (int j = 0; j < n; j++) { if (s[j] == 0 && dist[j] < temp) { temp = dist[j]; u = j; } } } delete[]s; delete[]dist; return 0; } int Graph_List::dlongest_path(const int v, int*& path) { int n = graphsize; int* visit = new int[n]; // 是否访问过 int* dist = new int[n]; // 存距离 int i = 0, temp = 0; for (int i = 0; i < n; i++) { visit[i] = 0; dist[i] = 0; // 迪杰斯特拉改参数 path[i] = -1; // 存路径 } int u = v; Edge* p = NULL; dist[u] = 0; visit[u] = 1; path[u] = u; for (int i = 0; i < n; i++) { visit[u] = 1; p = head[u].get_adjacent(); while (p) { temp = p->get_VerAdj(); if (dist[u] + p->get_cost() > dist[temp]) { dist[temp] = dist[u] + p->get_cost(); path[temp] = u; } p = p->get_link(); } int t = 0; for (int j = 0; j < n; j++) { if (dist[j] > t && visit[j] == 0) { t = dist[j]; u = j; } } } delete[]visit; delete[]dist; return 0; }