昨天借了两本图论的书,
才发现我之前的做法有点笨,
一点优化都没有..
于是把一上午看的图的储存结构写了一边.
各种结构的优缺点总结了一下.
收获很大.
//图的几种储存结构
//1.邻接矩阵
//2.前向星(三元组)
//3.邻接表
//4.静态链表(链式前向星)
#define fence puts("----------------------")
#define mem(a,b) memset(a,b,sizeof(a))
#include <iostream>
#include <cstring>
#include <vector>
#include <algorithm>
#include <list>
using namespace std;
const int MAXN = 1010;
const int INF = 0x3f3f3f3f;
//图的几种储存结构
//1.邻接矩阵
//2.前向星(三元组)
//3.邻接表
//4.静态链表(链式前向星)
//1.邻接矩阵
//构造 时间复杂度O(n^2) 空间复杂度O(n^2)
//优点:实现简单,可以直接查询任意两节点间是否存在边,和边的权值
//缺点:遍历效率低,不能储存重边;初始化效率低;大图空间开销大(n>10e5);对于稀疏矩阵利用率低
int n, m;//节点数,边数
int Adjacency_matrix[MAXN][MAXN];
void transam()
{
for (int i = 0; i < n; ++i) {
for (int j = 0; j < n; ++j)
cout << Adjacency_matrix[i][j] << " ";
cout << endl;
}
}
void ini_Am()
{
//int n, m;//节点数,边数
cin >> n >> m;
mem(Adjacency_matrix, INF);
for (int i = 0; i < n; ++i)
Adjacency_matrix[i][i] = 0;
for (int i = 0; i < m; ++i)
{
int x, y, z;//节点,节点,路径长度
cin >> x >> y >> z;
Adjacency_matrix[x][y] = Adjacency_matrix[y][x] = z;
}
fence;
transam();
fence;
}
//2.前向星(三元组)
//构造 时间复杂度O(mlogm) 空间复杂度O(m)
//优点:可以储存重边,复杂度低
//缺点:无法直接判断两点间是否存在边
struct Node {
int x, y, z;
Node(int X, int Y, int Z) :x(X), y(Y), z(Z) { }
};
//排序规则 按照x有小到大排序,若x相等按y小大顺序排,若y也相等,按z小大顺序排
bool cmp(Node a, Node b)
{
if (a.x == b.x && a.y == b.y)
return a.z < b.z;
if (a.x == b.x)
return a.y < b.y;
return a.x < b.x;
}
vector<Node>edge;
void transtri()
{
int len = edge.size();
for (int i = 0; i < len; ++i)
cout << edge[i].x << " " << edge[i].y << " " << edge[i].z << endl;
}
void ini_tri()
{
//int n, m;//节点数,边数
cin >> n >> m;
for (int i = 0; i < m; ++i)
{
int x, y, z;//节点,节点,路径长度
cin >> x >> y >> z;
edge.push_back(Node(x, y, z));
}
sort(edge.begin(), edge.end(), cmp);
fence;
transtri();
fence;
}
//3.邻接表
//构造 时间复杂度O(m) 空间复杂度O(m)
//优点:复杂度低
//缺点:无法直接判断两点间是否存在边
vector<vector<pair<int, int>>>vec;
void transedg()
{
for (int i = 0; i < n; ++i)
for (int j = 0; j < vec[i].size(); ++j)
cout << i << " " << vec[i][j].first << " " << vec[i][j].second << endl;
}
void ini_edg()
{
//int n, m;//节点数,边数
cin >> n >> m;
vec.resize(m);
for (int i = 0; i < m; ++i)
{
int x, y, z;//节点,节点,路径长度
cin >> x >> y >> z;
vec[x].push_back(pair<int, int>(y, z));
}
fence;
transedg();
fence;
}
//4.链式前向星
//时间复杂度 O(m) 空间复杂度O(n+m)
//优点:代码原理简单;可以储存重边;可以储存大量数据;没有动态内存管理;
//缺点:无法直接判断两点间是否存在边
struct EdgeNode
{
int to;
int w;
int next;
}Edges[MAXN];
int Head[MAXN];
void trans()
{
for (int i = 0; i < n; ++i)
for (int k = Head[i]; k != -1; k = Edges[k].next)
cout << i << " " << Edges[k].to << " " << Edges[k].w << endl;
}
void ini_edg2()
{
//int n, m;//节点数,边数
cin >> n >> m;
for (int i = 0; i < n; ++i)
Head[i] = -1;
for (int i = 0; i < m; ++i)
{
int x, y, z;//节点,节点,路径长度
cin >> x >> y >> z;
Edges[i].to = y;
Edges[i].w = z;
Edges[i].next = Head[x];
Head[x] = i;
}
fence;
trans();
fence;
}
/*//测试数据
3 4
0 1 1
0 2 2
1 2 3
0 2 4
*/
int main()
{
ini_Am();
ini_tri();
ini_edg();
ini_edg2();
system("pause");
return 0;
}