数组模拟邻接表-头插法(C++)

2 篇文章 0 订阅

数组模拟邻接表-头插法

有权有向图

给定一张图如下:
在这里插入图片描述

数组方式实现下的数据结构图解:

在这里插入图片描述

结构体方式实现:
#include <iostream>
#include <iomanip>

#define V 10000 //开的数组顶点最大值的容量
using namespace std;

struct Edge //边的结构体
{
    int to;   //边要指向的点
    int w;    //边的权值
    int next; //存储当前边的编号的下一条边的编号
} e[V << 1];  //

int idx = 0;      //当前边的编号
int head[V << 1]; //表头数组,存放当前顶点i的出边的编号
int n, m;         //要插入的顶点的数量和边的数量
//在邻接表中插入一条带权值的边
void addEdge(int u, int v, int w)
{
    e[++idx].to = v;       //当前边编号idx所指向的顶点
    e[idx].w = w;          //当前边编号idx的权值
    e[idx].next = head[u]; //当前边编号idx指向的边的编号,头插法
    head[u] = idx;         //更新当前u所在的表头数组的边的编号idx
}

void print()
{
    for (int i = 1; i <= n; i++)
    {
        for (int j = head[i]; j != 0; j = e[j].next)
        {
            cout << i << " " << e[j].to << " " << e[j].w << endl;
        }
    }
}

int main(int argc, char const *argv[])
{
    //顶点4个,边6条
    n = 4, m = 6;
    //初始化表头数组head
    memset(head, 0, sizeof(head));
    //初始化e结构
    for (int i = 1; i <= n; i++)
    {
        e[i].to = 0;
        e[i].next = 0;
        e[i].w = 0;
    }
    //添加带权值的边
    addEdge(1, 2, 10);
    addEdge(1, 3, 7);
    addEdge(3, 4, 9);
    addEdge(2, 3, 8);
    addEdge(2, 4, 12);
    addEdge(1, 4, 11);
    // 打印
    print();
    return 0;
}
数组方式实现:
#include <iostream>

using namespace std;

#define V 1000 //开的数组顶点最大值的容量

int idx = 0;     //边的编号
int head[V];     //表头数组,存储当前顶点i的出边的编号idx
int to[V << 1];  //终点数组,存储编号idx号边的终点,也是顶点i的邻接点
int W[V << 1];   //边权数组,存储编号idx号边的权值,即顶点i指向to[idx]的权值
int nxt[V << 1]; //指针数组,存储编号idx号边的下一条边

void addEdge(int u, int v, int w) //添加边
{
    nxt[++idx] = head[u]; //当前边编号idx指向的边的编号,头插法
    to[idx] = v;          //当前边编号idx所指向的顶点
    W[idx] = w;           //当前边编号idx的权值
    head[u] = idx;        //更新当前u所在的表头数组的边的编号idx
}
int n, m; //要插入的顶点的数量和边的数量
void print()
{
    //邻接表访问
    for (int i = 1; i <= n; i++)
    {
        for (int j = head[i]; j != 0; j = nxt[j]) //注意 j = nxt[j] 一直到该链表遍历结束
        {
            printf("%d, %d , %d \n", i, to[j], W[j]);
        }
    }
}

int main(int argc, char const *argv[])
{
    //顶点4个,边6条
    n = 4, m = 6;
    //初始化表头数组head
    memset(head, 0, sizeof(head));
    //添加带权值的边
    addEdge(1, 2, 10);
    addEdge(1, 3, 7);
    addEdge(3, 4, 9);
    addEdge(2, 3, 8);
    addEdge(2, 4, 12);
    addEdge(1, 4, 11);
    // 打印
    print();
    return 0;
}

有权无向图

  • 基于有权有向图修改:在添加边[u,v,w]的时候,再加一条反向的边[v,u,w]
#include <iostream>
#include <iomanip>

#define V 10000 //开的数组顶点最大值的容量
using namespace std;

struct Edge //边的结构体
{
    int to;   //边要指向的点
    int w;    //边的权值
    int next; //存储当前边的编号的下一条边的编号
} e[V << 1];  //

int idx = 0;      //当前边的编号
int head[V << 1]; //表头数组,存放当前顶点i的出边的编号
int n, m;         //要插入的顶点的数量和边的数量
//在邻接表中插入一条带权值的边
void addEdge(int u, int v, int w)
{
    e[++idx].to = v;       //当前边编号idx所指向的顶点
    e[idx].w = w;          //当前边编号idx的权值
    e[idx].next = head[u]; //当前边编号idx指向的边的编号,头插法
    head[u] = idx;         //更新当前u所在的表头数组的边的编号idx
}

void print()
{
    for (int i = 1; i <= n; i++)
    {
        for (int j = head[i]; j != 0; j = e[j].next)
        {
            cout << i << " " << e[j].to << " " << e[j].w << endl;
        }
    }
}

int main(int argc, char const *argv[])
{
    int u, v, w;
    cin >> n >> m;
    //初始化表头数组head
    memset(head, 0, sizeof(head));
    //初始化e结构
    for (int i = 1; i <= n; i++)
    {
        e[i].to = 0;
        e[i].next = 0;
        e[i].w = 0;
    }
    //添加带权值的边
    for (int i = 1; i <= m; i++)
    {
        cin >> u >> v >> w;
        addEdge(u, v, w);
        addEdge(v, u, w);
    }
    // 打印
    print();
    return 0;
}

无权有向图

#include <iostream>

using namespace std;

#define V 1000 //开的数组顶点最大值的容量

struct Edge //边的结构体
{
    int to;   //边要指向的点
    int next; //存储当前边的编号的下一条边的编号
} e[V << 1];

int idx = 0;      //当前边的编号
int head[V << 1]; //表头数组,存放当前顶点i的出边的编号

//在邻接表中插入一条无权的边
void addEdge(int u, int v)
{
    e[++idx].to = v;       //当前边编号idx所指向的顶点
    e[idx].next = head[u]; //当前边编号idx指向的边的编号,头插法
    head[u] = idx;         //更新当前u所在的表头数组的边的编号idx
}
int n, m;

void print()
{
    for (int i = 1; i <= n; i++)
    {
        for (int j = head[i]; j != 0; j = e[j].next)
        {
            cout << i << " " << e[j].to << " " << endl;
        }
    }
}

int main(int argc, char const *argv[])
{
    //顶点4个,边6条
    n = 4, m = 6;
    //初始化表头数组head
    memset(head, 0, sizeof(head));
    //初始化e结构
    for (int i = 1; i <= n; i++)
    {
        e[i].to = 0;
        e[i].next = 0;
    }
    //添加带权值的边
    addEdge(1, 2);
    addEdge(1, 3);
    addEdge(3, 4);
    addEdge(2, 3);
    addEdge(2, 4);
    addEdge(1, 4);
    // 打印
    print();
    return 0;
}

无权无向图

  • 基于无权有向图修改:在添加边[u,v]的时候,再加一条反向的边[v,u]
#include <iostream>

using namespace std;

#define V 1000 //开的数组顶点最大值的容量

struct Edge //边的结构体
{
    int to;   //边要指向的点
    int next; //存储当前边的编号的下一条边的编号
} e[V << 1];

int idx = 0;      //当前边的编号
int head[V << 1]; //表头数组,存放当前顶点i的出边的编号

//在邻接表中插入一条无权的边
void addEdge(int u, int v)
{
    e[++idx].to = v;       //当前边编号idx所指向的顶点
    e[idx].next = head[u]; //当前边编号idx指向的边的编号,头插法
    head[u] = idx;         //更新当前u所在的表头数组的边的编号idx
}
int n, m;

void print()
{
    for (int i = 1; i <= n; i++)
    {
        for (int j = head[i]; j != 0; j = e[j].next)
        {
            cout << i << " " << e[j].to << " " << endl;
        }
    }
}

int main(int argc, char const *argv[])
{
    //顶点4个,边6条
    n = 4, m = 6;
    //初始化表头数组head
    memset(head, 0, sizeof(head));
    //初始化e结构
    for (int i = 1; i <= n; i++)
    {
        e[i].to = 0;
        e[i].next = 0;
    }
    //添加带权值的边
    addEdge(1, 2);
    addEdge(2, 1);
    addEdge(1, 3);
    addEdge(3, 1);
    addEdge(3, 4);
    addEdge(4, 3);
    addEdge(2, 3);
    addEdge(3, 2);
    addEdge(2, 4);
    addEdge(4, 2);
    addEdge(1, 4);
    addEdge(4, 1);
    // 打印
    print();
    return 0;
}
  • 2
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值