C语言 图的邻接矩阵和邻接表存储实现

实验六 图的邻接矩阵和邻接表存储实现

一、实验目的

1、理解并掌握图的邻接矩阵存储;
2、理解并掌握图的邻接表存储;
3、实现两种存储结构。

二、实验内容

编写程序实现下图的邻接矩阵与邻接表的创建和输出。
图

三、实验步骤和设计思想

1、创建邻接矩阵,按照顶点与顶点之间有无边(有边即为1)输入数据,无边不输入,默认为0
2、根据之前输入数据形成的邻接矩阵创建邻接表,并将邻接表输出

四、程序清单

#include <stdio.h>
#include <stdlib.h>
#define Vmax 100
typedef  char  VType;//顶点字符型
typedef  int  EType;//边,矩阵元素int型

typedef  struct {
      VType  vexs[Vmax]; //顶点表:存图的所有顶点,比如abcd四个顶点,放入数组中
	  EType  edges[Vmax][Vmax]; //邻接矩阵—边表 值为0 1整数
	  int  Vnum, Enum; // 图的顶点数和边数
     }MGraph;

typedef  char  VType; //顶点字符型
typedef   int  EType;// 边:对应顶点数组的数组下标,int型

typedef struct node
{
    EType  adjvex;
    struct node *next;
}EdgeNode;//边结点

typedef struct
{
    VType vertex;
    EdgeNode *firstedge;
}VertexNode;//顶点结点

typedef struct
{
    VertexNode vexlist[Vmax];//顶点结点数组
    int vexnum,arcnum;//顶点数、边数
}AdjGraph;//图的邻接表
typedef  int  elemtype;
 typedef   struct{
     elemtype data[Vmax]; //将栈中元素定义为elemtype类型
     int  top;                   //:指向栈顶位置的指针(即数组下标)
}SqStack;

typedef char  ElemType;
typedef  struct
{
	ElemType data[Vmax];	/*保存队中元素*/
	int front,rear;	  /*队头和队尾指针,队头指向队列首元素的前一个位置,队尾指向队尾元素。*/
} SqQueue;

void InitQueue(SqQueue *&q)//初始化
{
    q=(SqQueue*)malloc(sizeof(SqQueue));
    q->front=q->rear=0;
}

bool enQueue(SqQueue *&q,ElemType e)//进队列
{
    if((q->rear+1)%Vmax==q->front){ //队满上溢出
        printf("队满\n");
        return false;
    }
    q->rear=(q->rear+1)%Vmax;
    q->data[q->rear]=e;
    return true;
}

bool deQueue(SqQueue *&q,ElemType e)//出队列
{
    if(q->front==q->rear){        //队空下溢出
       printf("队空\n");
       return false;
    }
    q->front=(q->front+1)%Vmax;
    e=q->data[q->front];
    return true;
}

bool QueueEmpty(SqQueue *q)//判断队列是否为空
{
    return (q->rear==q->front);
}


void DestroyQueue(SqQueue *&q)//销毁队列
{
    free(q);
}

void CreateUDN(MGraph *&G)
{
    int i,j,vi,vj,w;
    G=(MGraph *)malloc(sizeof(MGraph));
    printf("请输入邻接矩阵的顶点数和边数:\n");
    scanf("%d %d",&G->Vnum,&G->Enum);               //输入总顶点数,总边数
    printf("请输入每个顶点的信息:\n");
    getchar();
    for( i=0; i<G->Vnum; i++)                     //将顶点存入数组中
    {
        scanf("%c",&G->vexs[i]);             //依次输入点的信息
    }
    for( i=0; i<G->Vnum; i++)                     //图的初始化
    {
        for( j=0; j<G->Vnum; j++)
        {
                G->edges[i][j] = 0;           //初始化为0
        }
    }
    printf("\n");
    for(i=0; i<G->Enum; i++)
    {
        printf("请输入边的信息:\n");
        scanf("%d %d %d",&vi,&vj,&w);
        G->edges[vi-1][vj-1] = w; //因为无向图是对称的,a[i][j] = a[j][i]
        G->edges[vj-1][vi-1] = w;
    }
}

void PrintfGraph(MGraph *&G)         //输出邻接矩阵的信息
{
    int i,j;
    printf("\n邻接矩阵为:\n");
    for(i=0;i<G->Vnum;i++)
    {
        printf("\t%c",G->vexs[i]);
    }
    printf("\n");
    for(i=0; i<G->Vnum; i++)
    {
        printf("\n%c\t",G->vexs[i]);
        for(j=0; j<G->Vnum; j++)
        {
            printf("%d\t",G->edges[i][j]);
        }
    }
}

void CreateAdj(AdjGraph *&F,MGraph *&G){
    int i,j;
    EdgeNode *p;
    F=(AdjGraph *)malloc(sizeof(AdjGraph));
    for(i=0;i<G->Vnum;i++){
        F->vexlist[i].firstedge=NULL;
    }
    for(i=0;i<G->Vnum;i++){
        for(j=0;j<G->Vnum;j++)
            if(G->edges[i][j]!=0&&G->edges[i][j]!=32767){
                p=(EdgeNode *)malloc(sizeof(EdgeNode));
                p->adjvex=j;
                p->next=F->vexlist[i].firstedge;
                F->vexlist[i].firstedge=p;
            }
    }
    F->vexnum=G->Vnum;
	F->arcnum=G->Enum;
}

void DispAdj(AdjGraph *&F,MGraph *&G){
    int i;EdgeNode *p;
    printf("\n图的邻接表为\n");
    for(i=0;i<F->vexnum;i++){
        p=F->vexlist[i].firstedge;
        printf("%c->",G->vexs[i]);
        while(p!=NULL){
            printf("%d->",p->adjvex);
            p=p->next;
        }
        printf("NULL\n");
    }
}


void DestroyAdj(AdjGraph*& G) {  //销毁邻接表
	int i; EdgeNode * pre, * p;
	for (i = 0; i < G->vexnum; i++) {  //扫描所有的单链表
		pre = G->vexlist[i].firstedge;  //p指向第i个单链表的头结点
		if (pre != NULL) {
			p = pre->next;
			while (p != NULL)
			{
				free(pre);  //释放pre
				pre = p; p = p->next;
			}
			free(pre);  //最后循环结束,释放pre
		}
	}
	free(G);  //释放邻接表指针
}

//int visited[Vmax]={0};//全局数组
//void DFS(AdjGraph *&g,MGraph *&G ,int v);//函数声明
//void BFS(AdjGraph *g,MGraph *&G,int v);//函数声明

int main()
{
    MGraph *G;
    CreateUDN(G);
    PrintfGraph(G);
    printf("\n");
    AdjGraph *F;
	CreateAdj(F,G);  //创建图的邻接表
	DispAdj(F,G);  //输出图的邻接表
	int v;
//	DFS(F,G,v);
	printf("\n");
//	BFS(F,G,v);
	DestroyAdj(F);  //释放图的邻接表=0
}

/*void DFS(AdjGraph *&g,MGraph *&G,int v)   //深度优先遍历算法
{
    EdgeNode *p=g->vexlist[v].firstedge;//p指向顶点v的第一个邻接点
    visited[v]=1;              //置已访问标记
    printf("%c->",G->vexs[v]);  //输出被访问的顶点
        while (p!=NULL){
        if(visited[p->adjvex]==0)//若p->adjvex顶点未被访问,递归访问
           DFS(g,G,p->adjvex);
        p=p->next;//p指向顶点v的下一个邻接点
    }
}
void BFS(AdjGraph *g,MGraph *&G,int v)//广度优先遍历
{
    EdgeNode *p ;
    int w,i;
    SqQueue * qu;         //定义队列指针
    InitQueue(qu);        //初始化队列
    for(i=0;i<g->vexnum;i++)//访问标记数组初始化
        visited[i]=0;
    printf("%c->",G->vexs[v]);//输出被访问的顶点
    visited[v]=1;             //标记已访问位置
    enQueue(qu,v);            //入队
    while(!QueueEmpty(qu)){    //队不空
        deQueue(qu,w);        //出队一个顶点w
        p=g->vexlist[w].firstedge;//指向w的第一个邻接点
        while(p!=NULL){          //查找w的所有邻接点
            if(visited[p->adjvex]==0){//若该邻接点未被访问
                printf("%c->",G->vexs[p->adjvex]);//输出该邻接点
                visited[p->adjvex]=1;//标记已访问位置
                enQueue(qu,p->adjvex);//该顶点进队
            }
            p=p->next;       //找下一个邻接点
        }
    }
    printf("\n");
}*/

五、代码运行结果

在这里插入图片描述

  • 10
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值