邻接矩阵的基本操作

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

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 VerVertexNum;//顶点cha的集合

bool EdgeVertexNumVertexNum;//邻接矩阵边表,bool类型只存放0和1

int vexnum;//顶点数

}MGraph;

//初始化邻接矩阵

void InitGraph(MGraph* M)

{

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

int i, j;

//初始化顶点

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

{

M->Veri = '\0';

}

//初始化邻接矩阵

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

{

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

{

M->Edgeij = 0;//初始化矩阵全为零

}

}

return;

}

//创建顶点

bool EnVertex(MGraph* M)

{

if (M->vexnum >= VertexNum)

return false;//空间已满

int i = 0;

while (i < VertexNum)

{

M->Veri = 'A' + i;

M->vexnum++;

i++;

}

return true;

}

//创建边

bool EnEdge(MGraph* M)

{

if (M->vexnum <= 1)

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

//创建A的边

M->Edge01 = 1;

M->Edge02 = 1;

M->Edge03 = 1;

//创建B的边

M->Edge10 = 1;

M->Edge13 = 1;

//创建C的边

M->Edge20 = 1;

//创建D的边

M->Edge30 = 1;

M->Edge31 = 1;

M->Edge34 = 1;

//创建E的边

M->Edge43 = 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->Veri == ch1)

index1 = i;

if (M->Veri == ch2)

index2 = i;

}

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

{

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

return INT_MIN;

}

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

if (M->Edgeindex1index2 == 1 && M->Edgeindex2index1 == 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->Veri == ch)

index = i;

if (index == -1)

return false;//该结点不存在

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

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

{

if (M->Edgeindexi == 1)

{

flag = 1;

printf("%c和%c存在边\n", ch, M->Veri);

}

}

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->Veri == ch)

index = i;

if (index == -1)

return false;//未找到该顶点

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

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

{

M->Edgeindexi = 0;

M->Edgeiindex = 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->Veri == ch1)

index1 = i;

if (M->Veri == ch2)

index2 = i;

}

M->Edgeindex1index2 = M->Edgeindex2index1 = 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->Veri == ch1)

index1 = i;

if (M->Veri = ch2)

index2 = i;

}

M->Edgeindex1index2 = 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->Veri == ch)

index = i;

}

printf("\n");

if (index == -1)

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

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

if (M->Edgeindexi == 1)

{

first = M->Veri;

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->Veri == ch1)

index1 = i;

if (M->Veri == ch2)

index2 = i;

}

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

{

if (M->Edgeindex1i == 1)

{

Next = M->Veri;

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->Edgeij);

}

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;

}

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

相关推荐
SoftLipaRZC1 小时前
单链表的应用:经典OJ题与通讯录项目实战
数据结构
SoftLipaRZC1 小时前
单链表专题:从概念到实现
数据结构
折哥的程序人生 · 物流技术专研8 小时前
Java面试85题图解版 · 特别篇:2026后端高频面试题复盘(算法底层逻辑+高并发架构设计全解析,附Java实战代码)
java·网络·数据库·算法·面试
想吃火锅10059 小时前
【leetcode】14.最长公共前缀js
算法·leetcode·职场和发展
云絮.10 小时前
数据库操作
数据库·mysql·算法·oracle
小林ixn10 小时前
LeetCode 206. 反转链表(迭代 + 递归详解)
算法·leetcode·链表
凡人叶枫10 小时前
Effective C++ 条款17:以独立语句将 newed 对象置入智能指针
java·linux·开发语言·c++·算法
菜鸟‍12 小时前
LeetCode 1 27 和 704 || 两数之和 移除元素 二分查找
算法·leetcode·职场和发展
退休倒计时13 小时前
【每日一题】LeetCode 142. 环形链表 II TypeScript
算法·leetcode·链表·typescript
popcorn_min13 小时前
Digits 手写数字识别:随机森林多分类 + 像素级特征热力图
算法·随机森林·分类