《数据结构与算法》实验报告——无向图邻接表的构造

数据结构 同时被 2 个专栏收录
26 篇文章 0 订阅
1012 篇文章 11 订阅

《数据结构》实验报告

 

学号:  2018329621200   

机器号   10-414-28       

姓名:  申屠志刚   

日期:  2019/12/9         

程序名:     main.cpp                             

实验内容:   无向图邻接表的构造    

一、目的和要求(需求分析):

1掌握邻接表的存储结构以及邻接表的建立和操作

2 构造一个无向图的邻接表,要求从键盘输入图的顶点数和图的边数,并显示所构造的邻接表)

实验拓展:

1.  构建有向图的邻接表

2.  判断边是否存在

3.  求顶点的度数

二、程序设计的基本思想,原理和算法描述:

邻接表是数组与链表相结合的存储方法,相比于顺序存储结构(邻接矩阵),节省空间。

三、调试和运行程序过程中产生的问题及采取的措施:

1、度数求法;

措施:添加边时即记录度数。

2、对应节点和节点编号;

措施:历遍查找。

3、区分有向图和无向图;

措施:添加标记,以判断是否添加反向边。

四、源程序及注释:

/*
*@Author:   STZG
*@Language: C++
*/
#include <bits/stdc++.h>

#define MAXVEX 30
using namespace std;
int visited[MAXVEX];
int n,m;
typedef char VertexType;
typedef struct ArcNode {
	int adjvex;      /*邻接点序号*/
	VertexType data; /*邻接点信息*/
	struct ArcNode *nextarc;
	char *info;
} ArcNode;
typedef struct VNode	{
	   VertexType data;   /*结点信息*/
	   ArcNode *firstarc; /*指向下一个边结点*/
}VNode,AdjList[MAXVEX];

typedef struct	           //图结构
{
	AdjList vertices;
	int vexnum,arcnum;		//图的当前顶点数与弧数
	int in[MAXVEX],out[MAXVEX];
}ALGraph;
int LocateVex(ALGraph G,char v)	//查找值为v的顶点在顶点向量G.vexs[]中的位置
{
	int i;
	for(i=0;i<G.vexnum;i++)
		if(v==G.vertices[i].data)
			return i;
		return -1;
}

int FirstAdjVex(ALGraph G,char v)//返回v的第一个邻接顶点的序号
{
	int i;
	ArcNode *p;
	i=LocateVex(G,v);		//i为顶点v在图G中的序号
	if(i==-1)
		return -1;
	p=G.vertices[i].firstarc;
	if(p)
		return p->adjvex;
	else
		return -1;
}

int NextAdjVex(ALGraph G,char v,char w)//返回v的(相对于w)的下一个邻接顶点的序号
{
	int i,j;
	ArcNode *p,*q;
	i=LocateVex(G,v);
	j=LocateVex(G,w);
	if(i==-1||j==-1||i==j)
		return -1;
	p=G.vertices[i].firstarc;          //p指向v的邻接顶点链表中的第一个邻接顶点
	while(p->nextarc&&p->adjvex!=j)		//找到邻接顶点w
		p=p->nextarc;
	if(p->nextarc)				//找到邻接顶点w,且w非v的最后一个邻接顶点
	{
		q=p->nextarc;
		return q->adjvex;	//返回v的(相对于w)的下一个邻接顶点的序号
	}
	else
		return -1;		//没有找到w或w是v的最后一个邻接顶点
}

int Visit(char v)
{
	printf("%c ",v);
	return 1;
}
int add(ALGraph &G,int i,int j){
    ArcNode *p,*q;
    G.out[i]++;
    G.in[j]++;
    p=(ArcNode *)malloc(sizeof(ArcNode));
    p->adjvex=j;
    p->info=NULL;
    p->nextarc=NULL;
    if(!G.vertices[i].firstarc)
        G.vertices[i].firstarc=p;
    else
    {//找尾结点
        for(q=G.vertices[i].firstarc;q->nextarc;q=q->nextarc);
            q->nextarc=p;			//插入到链表尾
    }
}
int CreateDG(ALGraph &G)			//采用邻接表表示,构造有向图G
{
	int v,e,i,j,t,f;
	ArcNode *p,*q;
	char tail,head;
	printf("输入顶点个数:");
	scanf("%d",&v);
	if(v<0)
		return 0;
	G.vexnum=v;
	printf("输入弧的条数:");
	scanf("%d",&e);
	if(e<0)
		return	0;
	G.arcnum=e;

	printf("无向图/有向图(0/1):");
	scanf("%d",&f);

	printf("建立DG:\n");
	for(t=0;t<G.vexnum;t++)				//建立头结点顺序表
	{
		fflush(stdin);
		printf("输入%d的信息:",t+1);
		scanf("%c",&G.vertices[t].data);
		G.vertices[t].firstarc=NULL;	//初始化该头结点指针域
		G.in[t]=0;
		G.out[t]=0;
	}
	for(t=0;t<G.arcnum;t++)				//建立表结点链表(每个顶点的邻接顶点链表)
	{
		fflush(stdin);
		printf("输入弧的信息(弧尾-弧头)");
		scanf("%c%*c%c",&tail,&head);
		i=LocateVex(G,tail);
		j=LocateVex(G,head);
		if(i==-1||j==-1||i==j)
			return 0;
        add(G,i,j);

        if(f)add(G,j,i);

	}
	return 1;
}

int DFS(ALGraph G,int v)		//从第v个顶点出发,递归的深度优先遍历有向图G
{
	int w;
	visited[v]=-1;
	printf("%c ",G.vertices[v].data);
	w=FirstAdjVex(G,G.vertices[v].data);
	for(;w>=0;w=NextAdjVex(G,G.vertices[v].data,G.vertices[w].data))
		if(!visited[w])
			DFS(G,w);		//对v的尚未访问的邻接顶点w递归调用DFS()
		return 1;
}

int DFSTraverse(ALGraph G)  //深度优先搜索遍历图G
{
	int i;
	for(i=0;i<G.vexnum;i++)
		visited[i]=0;
	for(i=0;i<G.vexnum;i++)
		if(!visited[i])
			DFS(G,i);
		return 1;
}
void printALGraph(ALGraph G){
    for(int i=0;i<G.vexnum;i++){
        printf("%c|%d-->",G.vertices[i].data,i);
        for(ArcNode* q=G.vertices[i].firstarc;q;q=q->nextarc){
            printf("%d-->",q->adjvex);
        }
        printf("null\n");
    }
}
void printdegree(ALGraph G){
    printf("Node\t入度\t出度\t度\n");
    for(int i=0;i<G.vexnum;i++){
        printf("%c\t%d\t%d\t%d\n",G.vertices[i].data,G.in[i],G.out[i],G.in[i]+G.out[i]);
    }
}
int checkarc(ALGraph G){
    while(1){
        char tail,head;
        fflush(stdin);
		printf("输入弧的信息(弧尾-弧头)");
		scanf("%c%*c%c",&tail,&head);
		int i=LocateVex(G,tail);
		int j=LocateVex(G,head);
		if(i==-1||j==-1||i==j)
			return 0;
        int f=0;
        for(ArcNode* q=G.vertices[i].firstarc;q;q=q->nextarc){
            if(j==q->adjvex){
                f=1;
                break;
            }
        }
        if(f)printf("Yes\n");
        else printf("No\n");
	}
}
int main()
{
	ALGraph G;
	printf("建立有向图G\n");
	if(CreateDG(G))
	{
	    printALGraph(G);
	    printdegree(G);
		printf("深度优先搜索的顺序:");
		DFSTraverse(G);
		printf("\n");
	}
	checkarc(G);
	return 0;
}

五、运行输出结果:

六、心得与体会:

1、掌握邻接表的存储结构以及邻接表的建立和操作。

2、构造无向图/有向图的邻接表。

3、转换思想,记录不变量。

 

 

 

 

 

  • 4
    点赞
  • 2
    评论
  • 29
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

©️2021 CSDN 皮肤主题: 1024 设计师:白松林 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值