邻接表的一些操作
创建 简单的遍历,删除顶点,增加一个顶点
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
typedef struct Node
{
int data;
struct Node* next;
}node;
typedef struct adj
{
int vert;
node* next;
}vertex;
typedef struct map
{
vertex ver[20];
int a;
}G;
G* creat()
{
G* Ga = (G*)malloc(sizeof(G));
int i,x,y;
printf("请输入该图的顶点数");
scanf("%d", &Ga->a);
for (i = 0; i < Ga->a; i++)//初始化要的顶点数
{
Ga->ver[i].vert = i;
Ga->ver[i].next = NULL;
}
node* temp = NULL;//定义一个指针来回连接用的
printf("输入两条的关系<a,b>中间用逗号隔开,输入21结束");//以21作为结束符,最好两个都是21否则有bug
scanf("%d,%d", &x, &y);
while (x != 21 && y != 21)//使用头插法
{
node* pnew = (node*)malloc(sizeof(node));
pnew->data = y;
pnew->next = NULL;
temp = Ga->ver[x-1].next;
if (Ga->ver->next == NULL)//如果顶点还没节点插入,插入节点
Ga->ver[x-1].next = pnew;
else//顶点有节点,后面的节点使用头插法
{
pnew->next = temp;
Ga->ver[x-1].next = pnew;
}
printf("输入两条的关系<a,b>中间用逗号隔开,输入21结束");
scanf("%d,%d", &x, &y);
}
return Ga;
}
void print(G* Ga)
{
node* temp = NULL;
for (int i = 0; i < Ga->a; i++)
{
printf("\n第%d行是", i + 1);//遍历打印
if(Ga->ver[i].next!=NULL)//如果头节点不为空,用temp指针来进行遍历
temp = Ga->ver[i].next;
while (temp->next)
{
printf("->%d", temp->data);
temp = temp->next;
}
if(temp!=NULL)
printf("->%d->NULL", temp->data);
}
}
void search(G* Ga)//此函数只能查找已有的顶点,没有不能查
{
int x;
printf("输入你要查询的节点的数字");
scanf("%d", &x);
printf("\n第%d行是", x );
node* temp = NULL;
temp = Ga->ver[x-1].next;//找到该顶点然后遍历打印
while (temp->next)
{
printf("->%d", temp->data);
temp = temp->next;
}
printf("->%d->NULL", temp->data);
}
void add(G*Ga)
{
int x,y;
node* temp=NULL;
printf("\n请输入你要增加的点提示:应小于20 ");//因为该结构体数组最大为20
scanf("%d", &x);
Ga->a++;//该图的顶点数加一
printf("请输入该点的出度,输入21结束");
scanf("%d", &y);
Ga->ver[x - 1].next = NULL;//先指向空
while(y!=21)
{
node* pnew = (node*)malloc(sizeof(node));
pnew->data = y;
pnew ->next= NULL;
temp = Ga->ver[x - 1].next;
if (Ga->ver->next == NULL)//这是以该顶点增加节点的操作
Ga->ver[x-1].next = pnew;
else
{
pnew->next = temp;
Ga->ver[x - 1].next = pnew;
}
printf("请输入该点的出度,输入21结束");
scanf("%d", &y);
}
printf("请输入该点的入度,输入21结束");
scanf("%d", &y);
while (y!=21)
{
node* pnew = (node*)malloc(sizeof(node));
pnew->data = x;
pnew->next= NULL;
temp = Ga->ver[y - 1].next;
if (Ga->ver->next == NULL)
Ga->ver[y-1].next = pnew;
else
{
pnew->next = temp;
Ga->ver[y-1].next = pnew;
}
printf("请输入该点的入度,输入21结束");
scanf("%d", &y);
}
}
void delpoint(G*Ga)
{
int x;
printf("请输入你要删除的点");
scanf("%d", &x);
node* p1, * p2;//定义两个指针来帮助删除节点
p1 = Ga->ver[x-1].next;//没有考虑该顶点后面都为空情况,如果该顶点后面为空,则p2=p1->next会报错
p2 = p1->next;
Ga->ver[x - 1].next = NULL;//让顶点断开连接
while (p2)
{
free(p1);
p1 = p2;
p2 = p2->next;
}
free(p1);//以上只是删除该顶点出度的情况
for (int i = 0; i < Ga->a; i++)//下面是删除以该顶点为入度的情况,使用遍历查找,再删除
{
p1 = Ga->ver[i].next;//以下都是单链表删除操作
if (p1&&p1->next == NULL && p1->data == x)
{
Ga->ver[i].next = NULL;
free(p1);
}
if(p1!=NULL)
p2 = p1->next;
if (p1&&p1->data == x)
{
Ga->ver[i].next = p2;
free(p1);
}
while (p2->next != NULL && p2->data != x)
{
p1 = p2;
p2 = p2->next;
}
if (p2->next == NULL && p2->data == x)
{
p1->next = NULL;
free(p2);
}
if (p2 && p2->data == x)
{
p1->next = p2->next;
free(p2);
}
}
}
int main()//根据需要选择相对应的函数
{
G* Ga = creat();
search(Ga);
print(Ga);
add(Ga);
delpoint(Ga);
print(Ga);
return 0;
}
运行结果