描述
给定一个无向图,在此无向图中增加一个新顶点。
输入
多组数据,每组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;
}