数据结构与算法(7-1)图的存储(邻接矩阵、邻接表)

目录

 

一、图的邻接矩阵

存储结构

总代码

二、网图的邻接矩阵

存储结构

总代码

 三、图的邻接表

存储结构

1、顶点列表结构体

2、邻接顶点结构体

 总代码

四、网图的邻接表

 存储结构

 1、顶点列表结构体

2、邻接顶点结构体

总代码 



一、图的邻接矩阵

存储结构

顶点数组:存储顶点数据

边数组:存储边数据

typedef struct
{
	char vertex[MAXSIZE];					//顶点
	int edge[MAXSIZE][MAXSIZE];		//邻接顶点
	int vertexNum;								//顶点数量
}Graph;
Graph G;

总代码

//无/有向图的邻接矩阵
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>

#define MAXSIZE 20

typedef struct
{
	char vertex[MAXSIZE];					//顶点
	int edge[MAXSIZE][MAXSIZE];		//邻接顶点
	int vertexNum;								//顶点数量
}Graph;
Graph G;

//输入顶点
void InputVertex()
{
	int i = 0;
	char ch;
	printf("请输入需要创建的图顶点(不需要空格):\n");
	do
	{
		scanf("%c", &ch);
		if (ch != '\n')
			G.vertex[i++] = ch;
	} while (ch != '\n');
	G.vertexNum = i;
}

//查找(根据结点找索引)
int findIndex(char ch)
{
	int i;
	for (i = 0; i < G.vertexNum; i++)
	{
		if (G.vertex[i] == ch)
			return i;
	}
	return -1;				//没找到
}

//创建图
void InputEdge()
{
	int i, index;
	char ch;
	for (i = 0; i < G.vertexNum; i++)
	{
		printf("请输入%c指向的邻接结点:\n", G.vertex[i]);
		scanf("%c", &ch);
		while (ch != '\n')
		{
			index = findIndex(ch);			//查找输入结点的索引
			G.edge[i][index] = 1;
			scanf("%c", &ch);
		}
	}
}

//输出测试
void Print()
{
	int i, j;
	for (i = 0; i < G.vertexNum; i++)
	{
		printf("\n%c结点的邻接结点为:\t", G.vertex[i]);
		for (j = 0; j < G.vertexNum; j++)
		{
			if (G.edge[i][j] != 0)
				printf("%c\t", G.vertex[j]);
		}
	}
}

int main()
{
	//创建图
	InputVertex();
	InputEdge();

	//输出测试
	Print();

	return 0;
}

二、网图的邻接矩阵

存储结构

顶点数组:存储顶点数据

边数组:存储边数据

网图与图相比多了一个“”,可以理解为距离

边数组中对角线为0:因为对角线表示的是指向自身,自身到自身的距离自然是0。

到其他相邻结点距离为:权。

到其他不相邻结点距离为:无穷大(可以用计算机允许的尽可能大的数据代替无穷大)。

总代码

//邻接矩阵(无向网图)
#include<iostream>
#include<stdio.h>
using namespace std;

#define MAXSIZE 20
#define MAX 65535							//无穷大

typedef struct Graph
{
	char vertex[MAXSIZE];					//顶点
	int arc[MAXSIZE][MAXSIZE];		//边	(权存放在其中)
	int numVertex, numArc;				//顶点数、边数
}Graph;
Graph G;

void Input()
{
	cout << "请输入需要创建的顶点数量和边的数量:\n";
	cin >> G.numVertex >> G.numArc;
}

//初始化
void Init_Graph()
{
	int i, j;
	//给数组赋0
	for (i = 0; i < G.numVertex; i++)
	{
		for (j = 0; j < G.numVertex; j++)
		{
			G.arc[i][j] = MAX;						//先把所有元素赋为无穷大
		}
		G.arc[i][i] = 0;								//对角线元素
	}
}

//创建无向图
void CreateGraph()
{
	int i, j, num, index = 0;
	for (i = 0; i < G.numVertex; i++)
	{
		printf("请输入第%d个结点及相邻结点数量:\n", i + 1);
		getchar();
		cin >> G.vertex[i] >> num;
		if (num > 0)
			printf("请分别输入相邻结点下标和权(空格分隔):\n", num);
		for (j = 0; j < num; j++)
		{
			getchar();
			cin >> index;
			cin >> G.arc[i][index];
		}
	}
}

//遍历
void Traverse()
{
	int i, j;
	for (i = 0; i < G.numVertex; i++)
	{
		for (j = 0; j < G.numVertex; j++)
			printf("%d\t", G.arc[i][j]);
		cout << endl;
	}
}

int main()
{
	Input();
	Init_Graph();
	CreateGraph();		//创建
	Traverse();			//遍历

	return 0;
}

 三、图的邻接表

存储结构

无向图邻接表:

有向图邻接表:

1、顶点列表结构体

//顶点列表
typedef struct VertexList
{
	int index;							//索引
	char data;							//数据
	EdgeNode* firstedge;		//指向第一个邻接结点
}VertexList;
VertexList L[MAXSIZE];

2、邻接顶点结构体

//邻接顶点
typedef struct EdgeNode
{
	int index;							//邻接结点索引
	char data;							//邻接结点数据
	struct EdgeNode* next;	//指向下一个邻接结点
}EdgeNode;

 总代码

//图的邻接表
#include<stdio.h>
#include<iostream>
#include<malloc.h>
using namespace std;

#define MAXSIZE 100
int listLength = 0;

//邻接顶点
typedef struct EdgeNode
{
	int index;							//邻接结点索引
	char data;							//邻接结点数据
	struct EdgeNode* next;	//指向下一个邻接结点
}EdgeNode;

//顶点列表
typedef struct VertexList
{
	int index;							//索引
	char data;							//数据
	EdgeNode* firstedge;		//指向第一个邻接结点
}VertexList;
VertexList L[MAXSIZE];

//输入
void Input()
{
	int i = 0;
	char ch = ' ';
	cout << "请输入需要创建的结点:\n";
	scanf_s("%c", &ch, 1);
	for (i = 0; i < MAXSIZE && ch != '\n'; i++)
	{
		L[i].data = ch;
		scanf_s("%c", &ch, 1);
	}
	listLength = i;				//获取列表长度(吸收空格)
}

void InitList()
{
	int i;
	for (i = 0; i < listLength; i++)
		L[i].firstedge = NULL;
}

//查找
int find(char ch)
{
	int i;
	for (i = 0; i < listLength; i++)
	{
		if (ch == L[i].data)
			return ch;
	}
	return NULL;
}

//初始化列表
void Create_List()
{
	int i;
	char ch, choice;
	EdgeNode* N = NULL;
	for (i = 0; i < listLength; i++)
	{
		printf("%c是否有邻接结点?(Y/N)\n", L[i].data);
		scanf_s("%c", &choice, 1);
		getchar();
		if (choice == 'y' || choice == 'Y')
		{
			L[i].firstedge = (EdgeNode*)malloc(sizeof(EdgeNode));
			N = (EdgeNode*)malloc(sizeof(EdgeNode));
			N = L[i].firstedge;												//连接
			printf("请输入%c的邻接结点:\n", L[i].data);
			while (1)
			{
				scanf_s("%c", &ch, 1);
				if (ch == '\n')
					break;
				else if (ch == ' ')
					continue;
				N->data = ch;						//值
				N->index = find(ch);			//查找并赋值索引
				N->next = (EdgeNode*)malloc(sizeof(EdgeNode));		//下一个
				N = N->next;
			}
			N->next = NULL;
		}
	}
}

void Print()
{
	int i;
	EdgeNode* N = NULL;
	for (i = 0; i < listLength; i++)
	{
		printf("\n%c的邻接结点:", L[i].data);
		N = L[i].firstedge;
		while (N)
		{
			cout << N->data;
			N = N->next;
		}
		cout << endl;
	}
}

int main()
{
	Input();
	InitList();

	Create_List();

	Print();

	return 0;
}

四、网图的邻接表

 存储结构

 1、顶点列表结构体

//结点列表
typedef struct NodeList
{
	char data;
	int length;
	EdgeNode* firstEdge;
}NodeList;
NodeList L[MAXSIZE];

2、邻接顶点结构体

//邻接结点
typedef struct EdgeNode
{
	int index;
	char data;
	int weight;								//权重
	struct EdgeNode* next;
}EdgeNode, * pEdgeNode;			//*pEdgeNode后面为创建二级指针

总代码 

//网图的邻接表
//运用了二级指针:要直接修改地址需要用到二级指针
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<iostream>
#include<malloc.h>
using namespace std;

#define MAXSIZE 100
int length = 0;

//邻接结点
typedef struct EdgeNode
{
	int index;
	char data;
	int weight;								//权重
	struct EdgeNode* next;
}EdgeNode, * pEdgeNode;			//*pEdgeNode后面为创建二级指针

//结点列表
typedef struct NodeList
{
	char data;
	int length;
	EdgeNode* firstEdge;
}NodeList;
NodeList L[MAXSIZE];

//输入并初始化
void Input_Init()
{
	int i = 0;
	char ch = ' ';
	printf("请输入需要创建的结点:\n");
	while (ch != '\n')						//(这里其实用do while()会更好)
	{
		scanf_s("%c", &ch);
		L[i].data = ch;
		L[i].firstEdge = NULL;
		i++;
	}
	length = i - 1;						//包括了换行符
	printf("请分别输入这%d个结点的邻接结点的数量:\n", length);
	for (i = 0; i < length; i++)
	{
		scanf("%d", &L[i].length);
	}
}

//获取索引
int findIndex(char ch)
{
	int i = 0;
	for (i = 0; i < length; i++)
	{
		if (ch == L[i].data)
			return i;
	}
	return -1;
}

//创建列表
void CreateList()
{
	int i, j, weight;
	char ch = ' ';
	pEdgeNode* N = NULL;								//----------------------二级指针--------------------//
	for (i = 0; i < length; i++)
	{
		if (ch != '\n')					//创建首
		{
			L[i].firstEdge = (EdgeNode*)malloc(sizeof(EdgeNode));
			//-----------------二级指针---------------//
			N = (pEdgeNode*)malloc(sizeof(pEdgeNode));
			N = &L[i].firstEdge;
		}
		printf("请分别输入%c结点的邻接结点和权重:\n", L[i].data);
		for (j = 0; j < L[i].length; j++)
		{
			getchar();
			scanf("%c %d", &ch, &weight);
			if (ch == ' ')								//空格不计
			{
				j--;
				continue;
			}

			//-----------------二级指针操作---------------//
			(*N)->index = findIndex(ch);		//获取索引
			if ((*N)->index != -1)					//有该元素
			{
				(*N)->data = ch;							//赋值
				(*N)->weight = weight;				//权重
				(*N)->next = (EdgeNode*)malloc(sizeof(EdgeNode));	//创建next指针
				N = &((*N)->next);						//后移(指向next指针的地址)(注:next也为二级指针时不行,不知道为什么)
			}
		}
		(*N) = NULL;										//----------地址置空,用到了二级指针----------//
	}
}

//遍历
void Print()
{
	int i = 0, j;
	pEdgeNode* N;
	for (i = 0; i < length; i++)
	{
		N = &L[i].firstEdge;
		printf("\n%c结点邻接结点:\n", L[i].data);
		while ((*N) != NULL)
		{
			printf("%c权重:%d\n", (*N)->data, (*N)->weight);
			N = &((*N)->next);
		}
	}
}

int main()
{
	Input_Init();

	CreateList();

	Print();

	return 0;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

_(*^▽^*)_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值