邻接矩阵的基本操作

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

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;

}

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

相关推荐
WBluuue10 分钟前
数据结构与算法:树上倍增与LCA
数据结构·c++·算法
bruk_spp27 分钟前
牛客网华为在线编程题
算法
lkbhua莱克瓦2440 分钟前
Java基础——集合进阶用到的数据结构知识点1
java·数据结构·笔记·github
杨福瑞1 小时前
数据结构:单链表(2)
c语言·开发语言·数据结构
王璐WL2 小时前
【数据结构】单链表及单链表的实现
数据结构
黑屋里的马2 小时前
java的设计模式之桥接模式(Bridge)
java·算法·桥接模式
z187461030032 小时前
list(带头双向循环链表)
数据结构·c++·链表
sin_hielo2 小时前
leetcode 1611
算法·leetcode
李小白杂货铺3 小时前
识别和破除信息茧房
算法·信息茧房·识别信息茧房·破除信息茧房·算法推荐型茧房·观点过滤型茧房·茧房
来荔枝一大筐3 小时前
C++ LeetCode 力扣刷题 541. 反转字符串 II
c++·算法·leetcode