#include<stdio.h>
#include<malloc.h>
#include<assert.h>
#define Default_Vertex_Size 10
#define T char
//图的定义
typedef struct GraphMtx
{
int MaxVertices;
int NumVertices;
int NumEdges;
T *VerticesList;
int **Edge;
}GraphMtx;
void InitGraphMtx(GraphMtx *g);
void InsertVertex(GraphMtx *g,T v);
void ShowGraphMtx(GraphMtx *g);
void InsertEdge(GraphMtx *g,T v1,T v2);
int GetVertexPos(GraphMtx *g,T v);
void RemoveEdge(GraphMtx *g,T v1,T v2);
void RemoveVertex(GraphMtx *g,T v);
//矩阵的初始化
void InitGraphMtx(GraphMtx *g)
{
g->MaxVertices = Default_Vertex_Size;
g->NumVertices = g->NumEdges = 0;
g->VerticesList = (T*)malloc(sizeof(T)*g->MaxVertices);
assert(g->VerticesList!=nullptr);
g->Edge = (int**)malloc(sizeof(int*)*g->MaxVertices);
assert(g->Edge!=nullptr);
for(int i=0;i<g->MaxVertices;++i)
{
g->Edge[i] = (int*)malloc(sizeof(int)*g->MaxVertices);
}
for(int i=0;i<g->MaxVertices;++i)
{
for(int j=0;j<g->MaxVertices;++j)
{
g->Edge[i][j] = 0;
}
}
}
//插入点操作
void InsertVertex(GraphMtx *g,T v)
{
if(g->NumVertices >= g->MaxVertices)
return;
g->VerticesList[g->NumVertices++] = v;
}
//输出矩阵
void ShowGraphMtx(GraphMtx *g)
{
printf(" ");
for(int i=0;i<g->NumVertices;++i)
{
printf("%c ",g->VerticesList[i]);
}
printf("\n");
for(int i=0;i<g->NumVertices;++i)
{
printf("%c ",g->VerticesList[i]);
for(int j=0;j<g->NumVertices;++j)
printf("%d ",g->Edge[i][j]);
printf("\n");
}
printf("\n");
}
//获取点的下标操作
int GetVertexPos(GraphMtx *g,T v)
{
for(int i=0;i<g->NumVertices;i++)
{
if(g->VerticesList[i]==v)
return i;
}
return -1;
}
//插入边操作
void InsertEdge(GraphMtx *g,T v1,T v2)
{
int p1 = GetVertexPos(g,v1);
int p2 = GetVertexPos(g,v2);
if(p1==-1||p2==-1)
return;
if(g->Edge[p1][p2] != 0)
return;
g->Edge[p1][p2] = g->Edge[p2][p1] = 1;
g->NumEdges++;
}
//删除边操作
void RemoveEdge(GraphMtx *g,T v1,T v2)
{
int p1 = GetVertexPos(g,v1);
int p2 = GetVertexPos(g,v2);
if(p1 == -1 || p2 == -1)
return;
if(g->Edge[p1][p2]==0)
return;
g->Edge[p1][p2] = g->Edge[p2][p1] = 0;
g->NumEdges--;
}
//删除点操作---包括删除与该点有联系的边
void RemoveVertex(GraphMtx *g,T v)
{
int p = GetVertexPos(g,v);
if(p == -1)
return;
for(int i=p;i<g->NumVertices-1;++i)
{
g->VerticesList[i] = g->VerticesList[i+1];
}
int numegdes = 0;
for(int i=0;i<g->NumVertices;++i)
{
if(g->Edge[p][i]!=0)
numegdes++;
}
for(int j=p;j<g->NumVertices-1;++j)
{
for(int k=0;k<g->NumVertices;k++)
{
g->Edge[j][k] = g->Edge[j+1][k];
}
}
for(int j=p;j<g->NumVertices-1;j++)
{
for(int k=0;k<g->NumVertices;k++)
g->Edge[k][j] = g->Edge[k][j+1];
}
g->NumVertices--;
g->NumEdges -= numegdes;
}
//摧毁图结构
void DestroyGraph(GraphMtx *g)
{
free(g->VerticesList); //释放已分配的存储相应的点的空间
g->VerticesList = NULL;
for(int i=0;i<g->NumVertices;++i) //二维数组,先逐个释放一级数组的存储空间
free(g->Edge[i]);
free(g->Edge); //释放二级存储空间
g->Edge = NULL;
g->NumEdges = g->NumVertices = g->MaxVertices = 0; //变量值赋为0
}
//获取该点的第一个邻接顶点
int GetFirstNeighbor(GraphMtx *g,T v)
{
int p = GetVertexPos(g,v);
if(p == -1)
return -1;
for(int i=0;i<g->NumVertices;++i)
{
if(g->Edge[p][i] == 1)
return i;
}
return -1;
}
//获取该点的第一个邻接顶点的下一个节点
int GetNextNeighbor(GraphMtx *g,T v,T w)
{
int pv = GetVertexPos(g,v); //获取点下标
int pw = GetVertexPos(g,w);
if(pv == -1 || pw ==-1) //判断点下标的合法性
return -1;
for(int i=pw+1;i<g->NumVertices;++i) //遍历与pv点有关联的点,位置从pw位置开始
{
if(g->Edge[pv][i] == 1)
return i; //返回所要的点的下标
}
return -1;
}
int main()
{
GraphMtx gm;
//初始化
InitGraphMtx(&gm);
//插入点操作
InsertVertex(&gm,'A');
InsertVertex(&gm,'B');
InsertVertex(&gm,'C');
InsertVertex(&gm,'D');
InsertVertex(&gm,'E');
//InsertVertex(&gm,'A');
//插入边操作
InsertEdge(&gm,'A','B');
InsertEdge(&gm,'A','D');
InsertEdge(&gm,'B','C');
InsertEdge(&gm,'B','E');
InsertEdge(&gm,'C','D');
InsertEdge(&gm,'C','E');
//InsertEdge(&gm,'C','D');
//获取该点的第一个邻接顶点
int pos = GetFirstNeighbor(&gm,'A');
printf("%c \n",gm.VerticesList[pos]);
//获取该节点的下一个节点的邻接顶点
pos = GetNextNeighbor(&gm,'A','B');
printf("%d \n",pos);
ShowGraphMtx(&gm);
//删除边
RemoveEdge(&gm,'B','C');
ShowGraphMtx(&gm);
//删除点
RemoveVertex(&gm,'C');
ShowGraphMtx(&gm);
//摧毁图结构
DestroyGraph(&gm);
return 0;
}