一、目的和要求(需求分析):
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("\n");
}
printf("-----------------------------------\n");
}
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("-----------------------------------\n");
printf("請輸入無向圖的頂點數和邊數:");
scanf("%d %d",&a,&b);
Init(&GA,a,b);
InsertArcnode(&GA);
PrintGraph(&GA);
choice();
}
if(choice1==2){
int a,b;
Graph GA;
printf("-----------------------------------\n");
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;
}