图的几种储存结构

昨天借了两本图论的书,
才发现我之前的做法有点笨,
一点优化都没有..
于是把一上午看的图的储存结构写了一边.
各种结构的优缺点总结了一下.
收获很大.

//图的几种储存结构
//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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值