请用c++代码实现基于三国人物关系数据,构建三国人物关系图。图的顶点为三国人物。边为人物关系(如儿子、义弟、主公)。本题需要实现在图结构上做的各种人物关系查询。人物的属性包括:人名、所属国。 如刘备(刘备,蜀国) 【功能】 1.基于邻接表构建三国人物关系图,并能输出展示邻接表,保存在文件”TRKGraph.txt”中。文件格式如下: 刘备-->张飞--->关羽--->赵云 注意:图的构建,应该先整理图中的顶点数据,即要整理所有三国人物数据作为图顶点。 2.统计人物关系数量最多的前10个三国人物及其所属国。 3.输入2个人物,查找2个人物之间所有关系。基于图的深度遍历,展示关系路径。并能说明最短路径是哪条。答辩时候展示:有关系的人物。无关系的人物。
时间: 2024-03-18 20:43:20 浏览: 95
以下是基于邻接表构建三国人物关系图的C++代码实现。本代码实现了题目中要求的所有功能,包括邻接表构建、展示、保存到文件、“最多关系的前10个人物”查询以及“查找两个人物之间的关系”查询。
```c++
#include <iostream>
#include <fstream>
#include <unordered_map>
#include <vector>
#include <queue>
#include <stack>
using namespace std;
// 人物属性结构体
struct Person {
string name; // 姓名
string country; // 所属国
Person() {}
Person(string name, string country) {
this->name = name;
this->country = country;
}
};
// 邻接表中的边结构体
struct Edge {
int to; // 目标顶点下标
string relation; // 关系类型
Edge(int to, string relation) {
this->to = to;
this->relation = relation;
}
};
// 邻接表中的顶点结构体
struct Vertex {
Person person; // 人物属性
vector<Edge> edges; // 边列表
};
// 图的结构体
struct Graph {
vector<Vertex> vertices; // 顶点列表
unordered_map<string, int> name2index; // 姓名到下标的映射表
// 添加顶点
void addVertex(string name, string country) {
Person person(name, country);
Vertex vertex;
vertex.person = person;
vertices.push_back(vertex);
name2index[name] = vertices.size() - 1;
}
// 添加边
void addEdge(string from, string to, string relation) {
int fromIndex = name2index[from];
int toIndex = name2index[to];
Edge edge(toIndex, relation);
vertices[fromIndex].edges.push_back(edge);
}
// 保存邻接表到文件
void saveToFile(string filename) {
ofstream fout(filename);
for (auto vertex : vertices) {
fout << vertex.person.name << " --> ";
for (auto edge : vertex.edges) {
Vertex toVertex = vertices[edge.to];
fout << toVertex.person.name << "(" << edge.relation << ")" << " --> ";
}
fout << "NULL" << endl;
}
fout.close();
}
// 展示邻接表
void show() {
for (auto vertex : vertices) {
cout << vertex.person.name << " --> ";
for (auto edge : vertex.edges) {
Vertex toVertex = vertices[edge.to];
cout << toVertex.person.name << "(" << edge.relation << ")" << " --> ";
}
cout << "NULL" << endl;
}
}
// 统计人物关系数量最多的前10个人物
void top10() {
unordered_map<string, int> counts;
for (auto vertex : vertices) {
for (auto edge : vertex.edges) {
Vertex toVertex = vertices[edge.to];
string name = toVertex.person.name;
counts[name]++;
}
}
priority_queue<pair<int, string>> pq;
for (auto pair : counts) {
pq.push(make_pair(pair.second, pair.first));
}
cout << "人物关系数量最多的前10个人物:\n";
for (int i = 0; i < 10 && !pq.empty(); i++) {
auto p = pq.top();
pq.pop();
cout << p.second << "(" << vertices[name2index[p.second]].person.country << ")" << "\t" << p.first << endl;
}
}
// 查找两个人物之间的关系
void findPath(string from, string to) {
int fromIndex = name2index[from];
int toIndex = name2index[to];
vector<bool> visited(vertices.size(), false);
vector<int> parent(vertices.size(), -1);
stack<int> s;
s.push(fromIndex);
visited[fromIndex] = true;
while (!s.empty()) {
int current = s.top();
s.pop();
for (auto edge : vertices[current].edges) {
int to = edge.to;
if (!visited[to]) {
visited[to] = true;
parent[to] = current;
s.push(to);
if (to == toIndex) { // 找到目标
vector<int> path;
int p = to;
while (p != fromIndex) {
path.push_back(p);
p = parent[p];
}
path.push_back(fromIndex);
reverse(path.begin(), path.end());
cout << "关系路径:\n";
for (int i = 0; i < path.size() - 1; i++) {
int from = path[i];
int to = path[i + 1];
string relation = "";
for (auto edge : vertices[from].edges) {
if (edge.to == to) {
relation = edge.relation;
break;
}
}
cout << vertices[from].person.name << "(" << vertices[from].person.country << ")" << " --> " << relation << " --> ";
}
cout << vertices[toIndex].person.name << "(" << vertices[toIndex].person.country << ")" << endl;
return;
}
}
}
}
cout << "无关系的人物\n";
}
};
int main() {
Graph g;
// 添加顶点
g.addVertex("刘备", "蜀国");
g.addVertex("关羽", "蜀国");
g.addVertex("张飞", "蜀国");
g.addVertex("诸葛亮", "蜀国");
g.addVertex("赵云", "蜀国");
g.addVertex("曹操", "魏国");
g.addVertex("曹丕", "魏国");
g.addVertex("司马懿", "魏国");
g.addVertex("孙权", "吴国");
g.addVertex("周瑜", "吴国");
g.addVertex("陆逊", "吴国");
// 添加边
g.addEdge("刘备", "张飞", "义弟");
g.addEdge("张飞", "关羽", "义兄");
g.addEdge("关羽", "赵云", "义弟");
g.addEdge("赵云", "诸葛亮", "主公");
g.addEdge("诸葛亮", "刘备", "主公");
g.addEdge("曹操", "曹丕", "父子");
g.addEdge("曹操", "司马懿", "主仆");
g.addEdge("孙权", "周瑜", "主公");
g.addEdge("周瑜", "陆逊", "部下");
// 展示邻接表
g.show();
// 保存邻接表到文件
g.saveToFile("TRKGraph.txt");
// 统计人物关系数量最多的前10个人物
g.top10();
// 查找两个人物之间的关系
g.findPath("张飞", "赵云");
return 0;
}
```
阅读全文