邻接矩阵的基本操作

之前我们介绍了图的几种存储方式和一些初始化之类的简单操作,今天给大家展示关于邻接矩阵的基本操作.

Ajacent(G,x,y):判断图G是否存在边<x,y>或(x,y)

Neighbor(G,x):判断图中与结点x相邻的边

InsertVertex(G,x):在图中插入顶点x

DeleteVertex(G,x):在图中删除顶点x

AddEdge(G,x,y):若无向边(x,y)或有向边<x,y>不存在,则向图中添加该边

RemoveEdge(G,x,y):若无向边(x,y)或有向边<x,y>存在,则从图G中删除该边

FirstNeighbor(G,x):求图G中顶点x的第一个邻接点,若有则返回顶点号。若x没有邻接点或图中不存在x,则返回-1

NextNeighBor(G,x,y):假设图G中顶点y是顶点x的一个邻接点,返回除y之外顶点x的下一个邻接点的顶点号,若y是x的最后一个邻接点,则返回-1

具体的代码实现:

//邻接矩阵的构建

#include<stdio.h>

#include<stdbool.h>

#include<limits.h>

#define VertexNum 5 //假设是5个顶点组成的无向图

typedef struct

{

char Ver[VertexNum];//顶点cha的集合

bool Edge[VertexNum][VertexNum];//邻接矩阵边表,bool类型只存放0和1

int vexnum;//顶点数

}MGraph;

//初始化邻接矩阵

void InitGraph(MGraph* M)

{

M->vexnum = 0;//初始化为0

int i, j;

//初始化顶点

for (i = 0; i < VertexNum; i++)

{

M->Ver[i] = '\0';

}

//初始化邻接矩阵

for (i = 0; i < VertexNum; i++)

{

for (j = 0; j < VertexNum; j++)

{

M->Edge[i][j] = 0;//初始化矩阵全为零

}

}

return;

}

//创建顶点

bool EnVertex(MGraph* M)

{

if (M->vexnum >= VertexNum)

return false;//空间已满

int i = 0;

while (i < VertexNum)

{

M->Ver[i] = 'A' + i;

M->vexnum++;

i++;

}

return true;

}

//创建边

bool EnEdge(MGraph* M)

{

if (M->vexnum <= 1)

return false;//非图或者只有一个顶点无法创建边

//创建A的边

M->Edge[0][1] = 1;

M->Edge[0][2] = 1;

M->Edge[0][3] = 1;

//创建B的边

M->Edge[1][0] = 1;

M->Edge[1][3] = 1;

//创建C的边

M->Edge[2][0] = 1;

//创建D的边

M->Edge[3][0] = 1;

M->Edge[3][1] = 1;

M->Edge[3][4] = 1;

//创建E的边

M->Edge[4][3] = 1;

return true;

}

//判断图G是否存在边(x,y)

int Adjacent(MGraph* M, char ch1, char ch2)

{

if (M->vexnum == 0)

return INT_MIN;//非图

if (M->vexnum == 1)

return INT_MIN;//一个顶点无边

int index1 = -1;//存储ch1在顶点数组中的位置

int index2 = -1;//存储ch2在顶点数组中的位置

int i = 0;

//找出ch1与ch2的下标

for (i; i < VertexNum; i++)

{

if (M->Ver[i] == ch1)

index1 = i;

if (M->Ver[i] == ch2)

index2 = i;

}

if (index1 == -1 || index2 == -1)

{

printf("顶点不合法\n");

return INT_MIN;

}

//判断ch1与ch2在矩阵中的值

if (M->Edge[index1][index2] == 1 && M->Edge[index2][index1] == 1)

return 1;

else

return 0;

return INT_MIN;

}

//列出图M中与顶点x相邻的边

bool Neighbors(MGraph* M, char ch)

{

if (M->vexnum == 0)

return false;//图不合法

if (M->vexnum == 1)

return false;//只有一个顶点

int index = -1;//求该顶点的下标

int i;

int flag = 0;//标记

for (i = 0; i < VertexNum; i++)

if (M->Ver[i] == ch)

index = i;

if (index == -1)

return false;//该结点不存在

//当ch与其他顶点存在边

for (i = 0; i < VertexNum; i++)

{

if (M->Edge[index][i] == 1)

{

flag = 1;

printf("%c和%c存在边\n", ch, M->Ver[i]);

}

}

if (flag == 0)

printf("%c不存在边\n", ch);

return true;

}

//从图中删除顶点

bool DeleteVertex(MGraph* M, char ch)

{

if (M->vexnum == 0)

return false;//非法图

if (M->vexnum == 1)

return false;//只有一个顶点

//求出ch的下标

int index = -1;

int i = 0;

for (i = 0; i < VertexNum; i++)

if (M->Ver[i] == ch)

index = i;

if (index == -1)

return false;//未找到该顶点

//令该顶点所在行和列置为0

for (i = 0; i < VertexNum; i++)

{

M->Edge[index][i] = 0;

M->Edge[i][index] = 0;

}

return true;

}

//添加边

bool AddEdge(MGraph* M, char ch1, char ch2)

{

if (M->vexnum == 0)

return false;//非法图

if (M->vexnum == 1)

return false;//只有一个顶点

int flag;

flag = Adjacent(M, ch1, ch2);

if (flag == INT_MIN)

return false;//非法图

else if (flag == 1)

return false;//已经存在边

else

{//获取两个顶点的下标

int index1 = -1;

int index2 = -1;

int i;

for (i = 0; i < VertexNum; i++)

{

if (M->Ver[i] == ch1)

index1 = i;

if (M->Ver[i] == ch2)

index2 = i;

}

M->Edge[index1][index2] = M->Edge[index2][index1] = 1;

printf("%c和%c 连接成功\n",ch1,ch2);

}

return true;

}

//删除边

bool RemoveEdge(MGraph* M, char ch1, char ch2)

{

int flag = Adjacent(M, ch1, ch2);

if (flag == INT_MIN)

return false;//图不合法

else if (flag == 0)

return false;//两个顶点之间没有边

else

{

//获取顶点

int index1, index2;

int i;

for (i = 0; i < VertexNum; i++)

{

if (M->Ver[i] == ch1)

index1 = i;

if (M->Ver[i] = ch2)

index2 = i;

}

M->Edge[index1][index2] = 0;

printf("%c与%c之间已经删除边\n",ch1, ch2);

}

return true;

}

//获取顶点的第一个邻接点的顶点号

char FirstNeighbor(MGraph* M, char ch)

{

if (M->vexnum == 0)

return '\0';//非法图

if (M->vexnum == 1)

return '\0';//只有一个顶点

//获取该顶点在数组中的位置

int index = -1;

int i;

char first = '\0';

for (i = 0; i < VertexNum; i++)

{

if (M->Ver[i] == ch)

index = i;

}

printf("\n");

if (index == -1)

return '\0';//无该顶点

for (i = 0; i < VertexNum; i++)

if (M->Edge[index][i] == 1)

{

first = M->Ver[i];

return first;

}

return -1;

}

char NextNeightbor(MGraph* M, char ch1, char ch2)

{

if (M->vexnum == 0)

return '\0';//非法图

if (M->vexnum == 1)

return '\0';//只有一个顶点

//获取两个顶点的下标

int index1 = -1;

int index2 = -1;

char Next = '\0';

int i = 0;

for (i; i < VertexNum; i++)

{

if (M->Ver[i] == ch1)

index1 = i;

if (M->Ver[i] == ch2)

index2 = i;

}

for (i = index2 + 1; i < VertexNum; i++)

{

if (M->Edge[index1][i] == 1)

{

Next = M->Ver[i];

return Next;

}

}

return -1;

}

//打印图

void PrintGraph(MGraph* M)

{

int i = 0;

int j = 0;

for (i = 0; i < 5; i++)

{

for (j = 0; j < 5; j++)

{

printf("%d", M->Edge[i][j]);

}

printf("\n");

}

}

int main()

{

MGraph M;//定义一个指向图的变量

InitGraph(&M);//初始化图

EnVertex(&M);//插入顶点

EnEdge(&M);//创建边

//图的具体操作

//判断图M是否存在边(x,y)

Adjacent(&M, 'A', 'E');

//列出图M中与顶点x相邻的边

Neighbors(&M, 'A');

//从图中删除顶点

//DeleteVertex(&M, 'C');

//若无向边(x,y)不存在,则向图G中删除该边

AddEdge(&M, 'D', 'C');

//若无向边(x,y)存在,则从图M中删除该边

//RemoveEdge(&M, 'D', 'C');

//求图M中顶点x的第一个邻接点,若有则返回顶点号。若x没有邻接点或图中不存在x,则返回-1

char ch = FirstNeighbor(&M, 'A');

printf("A的第一个邻接点为%c\n",ch);

//假设图M中顶点y是顶点x的一个邻接点,返回除y外顶点x的下一个邻接点的顶点号,若y是x的最后一个邻接点,则返回-1

char c = NextNeightbor(&M, 'A', 'B');

printf("A下一个邻接点的下一个为%c", c);

//打印图

//PrintGraph(&M);

return 0;

}

我们这个创建的是无向图的具体操作,有向图与无向图大部分类似,极个别可能有差别,大家在创建的时候需要留意.

相关推荐
im_AMBER1 分钟前
Leetcode 63 定长子串中元音的最大数目
c++·笔记·学习·算法·leetcode
小白程序员成长日记1 小时前
2025.11.29 力扣每日一题
数据结构·算法·leetcode
咫尺的梦想0072 小时前
链表-反装链表
数据结构·链表
在黎明的反思2 小时前
进程通信之消息队列(IPC)
算法
老鱼说AI2 小时前
算法基础教学第一步:数据结构
数据结构·python·算法
Jing_Rainbow3 小时前
【LeetCode Hot100 刷题日记(19/100)】54. 螺旋矩阵 —— 数组、矩阵、模拟、双指针、层序遍历🌀
算法·面试·程序员
地平线开发者4 小时前
征程 6 | linear 高精度输出配置方式
算法·自动驾驶
小尧嵌入式4 小时前
C++基础语法总结
开发语言·c++·stm32·单片机·嵌入式硬件·算法
white-persist4 小时前
【攻防世界】reverse | IgniteMe 详细题解 WP
c语言·汇编·数据结构·c++·python·算法·网络安全
稚辉君.MCA_P8_Java4 小时前
Gemini永久会员 归并排序(Merge Sort) 基于分治思想(Divide and Conquer)的高效排序算法
java·linux·算法·spring·排序算法