4003基于邻接表的新顶点的增加(C++,附详细解析)

描述

给定一个无向图,在此无向图中增加一个新顶点。

输入

多组数据,每组m+2行。第一行有两个数字n和m,代表有n个顶点和m条边。顶点编号为1到n。第二行到第m+1行每行有两个数字h和k,代表边依附的两个顶点。第m+2行有一个数字f,代表新插入的顶点编号。当n和m都等于0时,输入结束

输出

每组数据输出n+1行。为增加顶点后的邻接表。每两个数字之间用空格隔开。

输入样例 1 

3 2
1 2
2 3
4
2 1
1 2
4
0 0

输出样例 1

1 2
2 3 1
3 2
4
1 2
2 1
4

这是邻接表的第一道题,从这道题练起,慢慢熟悉邻接表的使用机制吧(ง • v •)ง~

思路:

邻接表就是所有的表头(顶点)在一个大的数组里顺序排列,表里的每一个元素都是一个链表节点,它们又各自分别指向与自己相邻的节点,就像是一栋大楼,从上到下每一层的窗户里都伸出不同的花枝来一样~是不是很形象呢~

看ppt上的示例代码感觉那个数组开得太大了,实际生活中不方便,所以想改良一下能不能结合题意弄一个长度可变,或者是不一下开这么大的数组,然后想到了线性表那一章里面用一个int*指针,在创建顺序表的时候才new一个已知大小的数组的思路,于是决定采用那个思路。

重点:区分好普通节点LNode和指向节点的指针linklist

由题意,邻接表从1开始算,所以要能使用下标为n的区域,并且后来又插了一个新节点,所以一共要开辟[n+2]这么大的数组,因为VList是linklist类型(指针类型),所以它的new是new一个LNode类型(可以简记为new是比当前“低”一个等级的)

之后遍历那个数组,初始化每个点的序号以及指向NULL。

h,k那里,linklist p,q之后,别忘了要=new LNode就是头插法了,不然那么多节点都要弄尾节点还要取好名字不可能的。。

之后在n+1位输入新插入的节点,它是孤立点,所以指向NULL就可以了

Show的时候也用指针的方式,对“大楼”里的每层都建立一个指针,然后遍历输出就可以了,注意输出格式,另外由于是用p->next作为判断条件,别忘了手动输出最后一个节点的vex~

#include<iostream>
#include<string>
#include<algorithm>
#include<vector>
#include<set>
#include<map>
using namespace std;

typedef struct LNode
{
	int vex;
	struct LNode* next;
}*linklist, LNode;
typedef struct Sheet
{
	LNode *VList;
	int vexnum;
	int arcnum;
}ALGragh;
void Create(ALGragh& alg, int n, int m)
{
	alg.vexnum = n;
	alg.arcnum = m;
	alg.VList = new LNode[n+2];
	for (int i = 1; i <= n; i++)
	{
		alg.VList[i].vex = i;
		alg.VList[i].next = NULL;
	}
	int h, k;
	for (int i = 0; i < m; i++)
	{
		cin >> h >> k;
		linklist p=new LNode, q=new LNode;
		p->vex = h;
		p->next = alg.VList[k].next;
		q->vex = k;
		q->next = alg.VList[h].next;
		alg.VList[h].next = q;
		alg.VList[k].next = p;
	}
	int p;
	cin >> p;
	alg.VList[n + 1].vex = p;
	alg.VList[n + 1].next = NULL;
}
void Show(ALGragh alg,int n)
{
	for (int i = 1; i <= n + 1; i++)
	{
		linklist p = &alg.VList[i];
		while (p->next)
		{
			cout << p->vex;
			if (p->next)
				cout << ' ';
			p = p->next;
		}
		cout <<p->vex<< endl;
	}
}
int main()
{
	int m, n;
	while (cin >> n >> m && m != 0 && n != 0)
	{
		ALGragh a;
		Create(a, n, m);
		Show(a, n);
	}
	return 0;
}

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值