数据结构——图

一、实验目的

  1. 学习图的基本定义方式
  2. 熟练掌握图的矩阵存储和邻接表存储。

二、实验要求

【项目1】实现图的邻接矩阵和邻接表的存储,要求:
在这里插入图片描述

  1. 建立如图所示的有向图G的邻接矩阵,并输出;
  2. 建立如图所示的有向图G的邻接表,并输出。

main.cpp程序代码:

#include <iostream>
#include <stdio.h>
#include "graph.h"
using namespace std;
int main()
{
    int a[6][MAXV] = {{0,5,INF,7,INF,INF},
                      {INF,0,4,INF,INF,INF},
                      {8,INF,0,INF,INF,9},
                      {INF,INF,5,0,INF,6},
                      {INF,INF,INF,5,0,INF},
                      {3,INF,INF,INF,1,0}};
    MatGraph *graph;
    createMat(graph,a,6,10);
    cout<<"*********显示邻接矩阵*********"<<endl;
    dispMat(graph);
    destroyMat(graph);
    cout<<endl;
    AdjGraph *G;
    createAdj(G,a,6,10);
//    MatToList1(graph,G);
    cout<<"*********显示邻接表*********"<<endl;
    dispAdj(G);
    destroyAdj(G);
    return 0;
}

运行结果截图:
在这里插入图片描述
【项目2】—项目1的图采用邻接矩阵 g 存储,设计实现以下功能的算法:
(1)求出图中每个顶点的入度。
(2)求出图中每个顶点的出度。

程序代码:
Main.cpp:

#include <iostream>
#include <stdio.h>
#include "graph.h"
using namespace std;
int main()
{
    int a[6][MAXV] = {{0,5,INF,7,INF,INF},
                      {INF,0,4,INF,INF,INF},
                      {8,INF,0,INF,INF,9},
                      {INF,INF,5,0,INF,6},
                      {INF,INF,INF,5,0,INF},
                      {3,INF,INF,INF,1,0}};
    MatGraph *graph;
    createMat(graph,a,6,10);
    cout<<"*********显示邻接矩阵*********"<<endl;
    dispMat(graph);
    countOutMat(graph);
    countInMat(graph);
    destroyMat(graph);
    return 0;
}

Graph.cpp:

#include "graph.h"
#include <iostream>
using namespace std;

//邻接表相关函数定义
void createAdj(AdjGraph *& graph,int a[MAXV][MAXV],int n,int e)//创建邻接表
{
    ArcNode * arcnode;
    graph = (AdjGraph*)malloc(sizeof(AdjGraph*));
    for(int i = 0;i<n;++i){
        graph->adjlist[i].firstarc = NULL;  //初始状态下,头结点不指向任何结点
    }
    for(int i = 0;i < n; ++i){    //扫描邻接矩阵中的所有顶点
        for(int j = n-1 ;j>=0;--j){
            if(a[i][j] != 0 && a[i][j] != INF){
                arcnode = (ArcNode*)malloc(sizeof(ArcNode*));
                arcnode->adjvex = j;
                arcnode->weight = a[i][j];
                arcnode->nextarc = graph->adjlist[i].firstarc;  //头插法插入节点
                graph->adjlist[i].firstarc = arcnode;
            }
        }
    }
    graph->n = n;
    graph->e = e;
}
void dispAdj(AdjGraph *graph)//显示邻接表
{
    ArcNode* arcnode;
    for(int i = 0;i < graph->n;++i){
        arcnode = graph->adjlist[i].firstarc;
        printf("%3d: ",i);
        while(arcnode != NULL){
            printf("%3d[%d]->",arcnode->adjvex,arcnode->weight);
            arcnode = arcnode -> nextarc;
        }
        printf("^\n");
    }
}
void destroyAdj(AdjGraph* graph)
{
    ArcNode* arcnode,*p;
    for(int i = 0;i < graph->n;++i){
        arcnode = graph->adjlist[i].firstarc;
        if(arcnode != NULL){
            p = arcnode->nextarc;
            while(p != NULL){
                free(arcnode);
                arcnode = p;
                p = p->nextarc;
            }
            free(arcnode);
        }
    }
    free(graph);
    cout<<"*****邻接表已销毁*******"<<endl;
}
//邻接矩阵相关函数定义
void createMat(MatGraph*& graph,int a[MAXV][MAXV],int n,int e)//创建邻接矩阵
{
    VertexType* vertex;
    graph = (MatGraph*)malloc(sizeof(MatGraph));
    for(int i = 0; i < n; ++i){
        vertex = (VertexType*)malloc(sizeof(VertexType));
        vertex->no = i;
        for(int j = 0; j < n; ++j){
            graph->edges[i][j] = a[i][j];
        }
        graph-> vexs[i] = *vertex;
        graph->n = n;
        graph->e = e;
    }
}
void dispMat(MatGraph *g)//输出邻接矩阵
{
    int i,j;
	for (i=0;i<g->n;i++)
	{
		for (j=0;j<g->n;j++)
			if (g->edges[i][j]==INF)
				printf("%3s","∞");
			else
				printf("%3d",g->edges[i][j]);
		printf("\n");
	}
}
void destroyMat(MatGraph *g)
{
//    for(int i = 0; i < g->n; ++i)
//        free(g->vexs[i])
    free(g);
    cout<<"*****邻接矩阵已销毁*******"<<endl;
}
void MatToList1(MatGraph *g,AdjGraph *&G)
//将邻接矩阵g转换成邻接表G
{
	int i,j;
	ArcNode *p;
	G=(AdjGraph *)malloc(sizeof(AdjGraph));
	for (i=0;i<g->n;i++)					//给邻接表中所有头节点的指针域置初值
		G->adjlist[i].firstarc=NULL;
	for (i=0;i<g->n;i++){					//检查邻接矩阵中每个元素
		for (j=g->n-1;j>=0;j--){
			if (g->edges[i][j]!=0 && g->edges[i][j]!=INF)	//存在一条边
			{
			   	p=(ArcNode *)malloc(sizeof(ArcNode));	//创建一个节点*p
				p->adjvex=j;
				p->weight=g->edges[i][j];
				p->nextarc=G->adjlist[i].firstarc;		//将*p链到链表后
				G->adjlist[i].firstarc=p;
			}
		}
    }
	G->n=g->n;G->e=g->e;
}
void countOutMat(MatGraph *g)
{
    int i,j;
    for(i=0;i<g->n;++i)
    {
        int cnt=0;
        for(j=0;j<g->n;++j)
        {
            if(g->edges[i][j] != 0 && g->edges[i][j] != INF)
                ++cnt;
        }
        printf("第%d个顶点的出度为:%d\n",i,cnt);
    }
}
void countInMat(MatGraph *g)
{
    int i,j;
    for(j=0;j<g->n;++j)
    {
        int cnt=0;
        for(i=0;i<g->n;++i)
        {
            if(g->edges[i][j] != 0 && g->edges[i][j] != INF)
                ++cnt;
        }
        printf("第%d个顶点的入度为:%d\n",i,cnt);
    }
}

Graph.h:

#ifndef GRAPH_H_INCLUDED
#define GRAPH_H_INCLUDED

#include <malloc.h>
#include <stdio.h>
#include <iostream>
#define MAXV 100
#define INF 32767
using namespace std;
typedef int InfoType;

//数据结构定义
//邻接表结构定义
typedef struct ANode{
    int adjvex;
    struct ANode *nextarc;
    int weight;
}ArcNode;//边节点类型

typedef struct Vnode{
    InfoType info;
    ArcNode *firstarc;
}VNode;//头节点

typedef struct {
    VNode adjlist[MAXV];
    int n,e;
}AdjGraph; //完整邻接表结构

//邻接矩阵结构定义
typedef struct{
    int no;
    InfoType info;
}VertexType; //顶点类型

typedef struct{
    int edges[MAXV][MAXV];
    int n,e;
    VertexType vexs[MAXV];
}MatGraph; //完整邻接矩阵结构

//函数声明
//邻接表相关函数声明
void createAdj(AdjGraph *& graph,int a[MAXV][MAXV],int n,int e);
void dispAdj(AdjGraph *graph);
void destroyAdj(AdjGraph* graph);
//邻接矩阵相关函数声明
void createMat(MatGraph*& graph,int a[MAXV][MAXV],int n,int e);
void dispMat(MatGraph *g);
void destroyMat(MatGraph *g);
//邻接表和邻接矩阵相互转换
void MatToList1(MatGraph *g,AdjGraph *&G);
void countOutMat(MatGraph *g);
void countInMat(MatGraph *g);

#endif // GRAPH_H_INCLUDED

运行结果截图:
在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值