邻接表

我们都知道在存储稠密图时候,邻接表比邻接矩阵效率高,因为邻接矩阵中在存储稀疏图时候,很多没用连接的点既占了空间,也浪费搜索时间。所以这篇博客帮助大家,学习一下邻接表。写的不好之处,请海涵。

首先我们需要需要定义一个结构体,来描述边。

struct e{
	int to; // 边的终点
	int next;// 专业书上叫做存储当前边的下一条边,但是我觉得理解为上一条边好像更好,过会从图中可以看出,别急
	int val;// 边的权值
	//可能有些人想问,为啥没起点,因为起点在表头当中,就是后面我们直接用一个数组存储了各个起点。叫做head[MAXN]
};

接下来,我们需要将图的信息通过函数add()添加进来,图的每一条边心里给它加一个编号,我们这里从1开始
首先定义几个全局变量:head[MAXN] from to val num=1(边的序号)
介绍一下head[x]:存储x的最新一条编号,也可理解为x的最后一条编号。数组默认为0

void add(起点from,终点to,权值val){
	e[num].next=head[from]; //意思是e[num].next存储from的上一条边的号
	e[num].to=to;
	e[num].val=val;//看情况写不写
	//既然我们添加一条边,那么head[from]就要更新了,对吧
	head[from]=num++;//之后边的序号就增加1
}

给大家画了这个草图,将就看一下,这个next是不是存储上一条边号?至少我是这样觉得。。只不过受单词影响了。。
数组模拟邻接表
解释一下上图中的几个重要地方:
怎么表示2 4之间有连接:

for(int i=head[2];i!=0;){//从head[2]的最后一条边寻找  对应上图就是4号边
	if(e[i].to==4){
		cout<<"find";
		break;
	}
	//没有找到怎么办,别忘了我们next,起到了大作用,往上一条边访问,上一条与2连接的边号是多少?是3吧,怎么表达?
	i=head[2]=e[i].next;
}
1 2
1 3
2 4
2 3
3 4
find

好了,说了这么多,还是看看代码吧,我们现在做个题目,就简单把上面这幅图用邻接表的方式输出吧

#include<iostream>
#include<cstring>
using namespace std;
#define MAXN 1000
// 描述边的信息
struct e{
    int to;
    int next;
    int val;
};
int head[MAXN],num=1;
e ee[MAXN];
void add(int from,int to){
    ee[num].next=head[from];
    ee[num].to=to;
    head[from]=num++;
}
int main(){
    memset(head,0,sizeof head);
    //上图 4个顶点  5条边  但是无向图是要保存双向,明白吧。
    for(int i=1;i<=5;i++){
        int from,to,val;//这里val就不输入了,因为是 0
        cin>>from>>to;
        add(from,to);
        add(to,from);
    }
    for(int i=1;i<=4;i++){//遍历每个起点
        for(int j=head[i];j!=0;){
            if(ee[j].to!=0){
                cout<<i<<" "<<ee[j].to<<endl;
            }
            j=head[i]=ee[j].next;
        }
        cout<<endl;
    }
    return 0;
}

//输入
1 2
1 3
2 4
2 3
3 4

//输出
1 3
1 2

2 3
2 4
2 1

3 4
3 2
3 1

4 3
4 2

如果觉得这篇文章对你有所帮助,请关注。
文章版权所有

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ahstunwy

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值