一、目的和要求(需求分析):
1、掌握邻接表的存储结构以及邻接表的建立和操作。
2、 构造一个无向图的邻接表,要求从键盘输入图的顶点数和图的边数,并显示所构造的邻接表)
实验拓展:1. 构建有向图的邻接表
2. 判断边是否存在
3. 求顶点的度数
以下是代码:
#include<stdio.h>
#include<iostream>
#include<stdlib.h>
#define vnum 20
using namespace std;
typedef struct arcnode
{
int adjvex; //边所对应的顶点编号
struct arcnode * next; //指向下一条边的指针
}ArcNode;
typedef struct vexnode
{
int vertex; //顶点编号
ArcNode *first; //指向第一条依附该顶点的边的指针
}AdjList[vnum];
typedef struct
{
AdjList adjlist;
int vexnum,arcnum; //顶点和边的个数
}Graph;
void Init(Graph *GA,int a,int b) //初始化
{
int i;
GA->vexnum=a;
GA->arcnum=b;
for(i=0;i<GA->vexnum;i++)
{
GA->adjlist[i].vertex=i; //初始化顶点信息
GA->adjlist[i].first=NULL; //初始化i的第一个邻接点为NULL
}
}
void InsertArcnode(Graph *GA) //无向图的构造
{
ArcNode *p;
int i,j,k;
for(k=0;k<GA->arcnum;k++)
{
cout << "请输入第"<<k+1<<"条边【两个顶点(从0开始)之间用空格隔开】:";
scanf("%d %d",&i,&j);
p=(ArcNode *)malloc(sizeof(ArcNode));//生成j的表结点
p->adjvex=j;
p->next=GA->adjlist[i].first; //将结点j链接到i的单链表中
GA->adjlist[i].first=p;
p=(ArcNode *)malloc(sizeof(ArcNode));//生成i的表结点
p->adjvex=i;
p->next=GA->adjlist[j].first; //将结点i链接到j的单链表中
GA->adjlist[j].first=p;
}
}
void PrintGraph(Graph *GA) //打印图
{
cout<<endl;
cout << "生成邻接表如下:" << endl;
for(int i=0;i<GA->vexnum;i++)
{
printf("v%d:",i);
ArcNode *p=GA->adjlist[i].first;
while(p!=NULL)
{
printf("-->%d",p->adjvex);
p=p->next;
}
printf(" ");
}
printf("----------------------------------- ");
}
void CreateLink(Graph *GA){ //有向图的建立
ArcNode *p;
int i,j,k;
for(k=0;k<GA->arcnum;k++){
cout << "请输入第"<<k+1<<"条边【两个顶点(从0开始)之间用空格隔开】:";
scanf("%d %d",&i,&j);
p=(ArcNode *)malloc(sizeof(ArcNode));
p->adjvex=j;
p->next=GA->adjlist[i].first;
GA->adjlist[i].first=p;
}
}
void Judge(Graph *GA){ //判断有向图中是否存在边
int i,j;
cout << "请输入欲判断的边:";
scanf("%d %d",&i,&j);
ArcNode *p=GA->adjlist[i].first;
while(p!=NULL){
if(p->adjvex==j){cout<<"该边存在"<<endl;break;}
else p=p->next;
}
if(p==NULL){cout<<"该边不存在"<<endl;}
}
void Count_degree(Graph *GA){ //计算有向图中顶点的出度入度
int i;
int out=0,in=0; //out储存出度,in储存入度
cout << "请输入顶点编号(从0开始):";
scanf("%d",&i);
if(GA->adjlist[i].first==NULL){out=0;}
else {
ArcNode *p=GA->adjlist[i].first;
while(p!=NULL){
out++;
p=p->next;
}
}
for(int k=0;k<GA->vexnum;k++)
{
ArcNode *p=GA->adjlist[k].first;
while(p!=NULL)
{
if(p->adjvex==i){in++;break;}
p=p->next;
}
}
cout << "该顶点的出度为:"<<out<<endl;;
cout << "该顶点的入度为:"<<in<<endl;;
}
void choice(){ //选择界面
int choice1;
cout << "请选择功能:"<<"1.无向图 2.有向图 3.退出"<<endl;
cin >> choice1;
if(choice1==1){
int a,b;
Graph GA;
printf("----------------------------------- ");
printf("请输入无向图的顶点数和边数:");
scanf("%d %d",&a,&b);
Init(&GA,a,b);
InsertArcnode(&GA);
PrintGraph(&GA);
choice();
}
if(choice1==2){
int a,b;
Graph GA;
printf("----------------------------------- ");
printf("请输入有向图的顶点数和边数:");
scanf("%d %d",&a,&b);
Init(&GA,a,b);
CreateLink(&GA);
PrintGraph(&GA);
cout << "功能:1.查询边是否存在 2.查询顶点的出度入度 3.返回上一级"<<endl;
int choice2;
cin >> choice2;
while(choice2!=3){
switch(choice2){
case 1:Judge(&GA);break;
case 2:Count_degree(&GA);break;
}
cout << "功能:1.查询边是否存在 2.查询顶点的出度入度 3.返回上一级"<<endl;
cin >> choice2;
}
choice();
}
if(choice1==3){return;}
}
int main()
{
choice(); //功能界面
return 0;
}