You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
303 lines
7.7 KiB
303 lines
7.7 KiB
#include<iostream>
|
|
#include<fstream>
|
|
#include<graphics.h>
|
|
#include<string>
|
|
#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;
|
|
} |