邻接表(c语言)
来源:互联网 发布:美工包括哪些 编辑:程序博客网 时间:2024/06/01 09:20
#include <stdio.h>
#include <malloc.h>
typedef char DataType;
#define MaxVertices 10
typedef struct Node
{
int dest;//邻接边的弧头顶点序号
struct Node *next;//单链表的下一个结点指针
}Edge;//邻接边单链表的结点结构体
typedef struct
{
DataType data;
int source;
Edge *adj;
}AdjLHeight;//数组结构体
typedef struct
{
AdjLHeight a[MaxVertices];//数组
int numOfVertices;
int numOfEdges;
}AdjLGraph;//邻接表结构体
//边信息的结构体
typedef struct
{
int row;
int col;
}RowCol;
//邻接表初始化
void AdjInitiate(AdjLGraph *G)
{
int i;
G->numOfVertices=0;
G->numOfEdges=0;
for(i=0;i<MaxVertices;i++)
{
G->a[i].source=i;
G->a[i].adj=NULL;
}
}
//插入顶点
void InsertVertex(AdjLGraph *G,int i,DataType vertex)
{
if(i>=0 && i<MaxVertices)
{
G->a[i].data=vertex;
G->numOfVertices++;
}
else
{
printf("顶点越界!");
}
}
//插入边
void InsertEdge(AdjLGraph *G,int v1,int v2)
{
Edge *p;
if(v1<0 || v1>=G->numOfVertices || v2<0 || v2>=G->numOfVertices)
{
printf("参数v1或v2越界!");
return;
}
p=(Edge *)malloc(sizeof(Edge));
p->dest=v2;
p->next=G->a[v1].adj;
G->a[v1].adj=p;
G->numOfEdges++;
}
//创建图
void CreatGraph(AdjLGraph *G,DataType v[],int n,RowCol d[],int e)
{
int i,k;
AdjInitiate(G);
for(i=0;i<n;i++)
{
InsertVertex(G,i,v[i]);
}
for(k=0;k<e;k++)
{
InsertEdge(G,d[k].row,d[k].col);
}
}
//删除边
void DeleteEdge(AdjLGraph *G,int v1,int v2)
{
Edge *curr,*pre;
if(v1<0 ||v1>=G->numOfVertices || v2<0 || v2>=G->numOfVertices)
{
printf("参数v1或v2越界!");
return;
}
pre=NULL;
curr=G->a[v1].adj;
while(curr!=NULL && curr->dest!=v2)
{
pre=curr;
curr=curr->next;
}
if(curr!=NULL && curr->dest==v2 && pre==NULL)
{
G->a[v1].adj=curr->next;
free(curr);
G->numOfEdges--;
}
else if(curr!=NULL && curr->dest==v2 && pre!=NULL)
{
pre->next=curr->next;
free(curr);
G->numOfEdges--;
}
else
{
printf("边不存在!");
}
}
//取第一个邻接顶点
int GetFirstVex(AdjLGraph G,int v)
{
Edge *p;
if(v<0 || v>=G.numOfVertices)
{
printf("参数v越界!");
return -1;
}
p=G.a[v].adj;
if(p!=NULL)
{
return p->dest;
}
else
{
return -1;
}
}
//取下一个邻接顶点
int GetNextVex(AdjLGraph G,int v1,const int v2)
{
Edge *p;
if(v1<0 || v1>=G.numOfVertices || v2<0 || v2>=G.numOfVertices)
{
printf("参数v1或v2越界!");
return -1;
}
p=G.a[v1].adj;
while(p!=NULL)
{
if(p->dest!=v2)
{
p=p->next;
continue;
}
else break;
}
p=p->next;
if(p!=NULL)
{
return p->dest;
}
else
{
return -1;
}
}
//撤销
AdjDestroy(AdjLGraph *G)
{
int i;
Edge *p,*q;
for(i=0;i<G->numOfVertices;i++)
{
p=G->a[i].adj;
while(p!=NULL)
{
q=p->next;
free(p);
p=q;
}
}
}
void main()
{
AdjLGraph g2;
Edge *p;
DataType v[]={'A','B','C','D','E'};//顶点集合
int n=5;//顶点数目
int e=6;//边数目
int i,j;
RowCol d[]={{0,1},{0,3},{3,1},{0,2},{2,4},{0,4}};//边集合
CreatGraph(&g2,v,n,d,e);
printf("顶点信息:\n");
for(i=0;i<g2.numOfVertices;i++)
{
printf("%c ",g2.a[i].data);
}
printf("边信息:\n");
for(i=0;i<g2.numOfVertices;i++)
{
printf("点%c的边有: ",g2.a[i].data);
p=g2.a[i].adj;
while(p!=NULL)
{
if(p->dest!=NULL)
{
printf("<%d,%d>",g2.a[i].source,p->dest);
}
p=p->next;
}
printf("\n");
}
printf("\n");
DeleteEdge(&g2,0,4);
printf("删除<0,4>边后:\n");
for(i=0;i<g2.numOfVertices;i++)
{
printf("点%c的边有: ",g2.a[i].data);
p=g2.a[i].adj;
while(p!=NULL)
{
if(p->dest!=NULL)
{
printf("<%d,%d>",g2.a[i].source,p->dest);
}
p=p->next;
}
printf("\n");
}
}
#include <malloc.h>
typedef char DataType;
#define MaxVertices 10
按个人理解:首先观察邻接表整体,里面包含一个数组,数组里面最后一个元素是一个头指针,头指针中包含得是一个单向链表,由此可以建立结构体。可以从小开始看,也可以从大开始看,这里我从大开始看,首先邻接表结构体AdjLGraph,里面元素应该有数组,现在为了方便操作,外加边数目元素和顶点数目元素,然后数组结构体AdjLHeight,里面应该有数据元素、下标元素、头指针元素,接着,同样的道理,头指针里应有一个单链表,即单链表结构体Edge。最后为了方便操作,试验数据可以用一个结构体存储,即RowCol。
typedef struct Node
{
int dest;//邻接边的弧头顶点序号
struct Node *next;//单链表的下一个结点指针
}Edge;//邻接边单链表的结点结构体
typedef struct
{
DataType data;
int source;
Edge *adj;
}AdjLHeight;//数组结构体
typedef struct
{
AdjLHeight a[MaxVertices];//数组
int numOfVertices;
int numOfEdges;
}AdjLGraph;//邻接表结构体
//边信息的结构体
typedef struct
{
int row;
int col;
}RowCol;
//邻接表初始化
void AdjInitiate(AdjLGraph *G)
{
int i;
G->numOfVertices=0;
G->numOfEdges=0;
for(i=0;i<MaxVertices;i++)
{
G->a[i].source=i;
G->a[i].adj=NULL;
}
}
//插入顶点
void InsertVertex(AdjLGraph *G,int i,DataType vertex)
{
if(i>=0 && i<MaxVertices)
{
G->a[i].data=vertex;
G->numOfVertices++;
}
else
{
printf("顶点越界!");
}
}
//插入边
void InsertEdge(AdjLGraph *G,int v1,int v2)
{
Edge *p;
if(v1<0 || v1>=G->numOfVertices || v2<0 || v2>=G->numOfVertices)
{
printf("参数v1或v2越界!");
return;
}
p=(Edge *)malloc(sizeof(Edge));
p->dest=v2;
p->next=G->a[v1].adj;
G->a[v1].adj=p;
G->numOfEdges++;
}
//创建图
void CreatGraph(AdjLGraph *G,DataType v[],int n,RowCol d[],int e)
{
int i,k;
AdjInitiate(G);
for(i=0;i<n;i++)
{
InsertVertex(G,i,v[i]);
}
for(k=0;k<e;k++)
{
InsertEdge(G,d[k].row,d[k].col);
}
}
//删除边
void DeleteEdge(AdjLGraph *G,int v1,int v2)
{
Edge *curr,*pre;
if(v1<0 ||v1>=G->numOfVertices || v2<0 || v2>=G->numOfVertices)
{
printf("参数v1或v2越界!");
return;
}
pre=NULL;
curr=G->a[v1].adj;
while(curr!=NULL && curr->dest!=v2)
{
pre=curr;
curr=curr->next;
}
if(curr!=NULL && curr->dest==v2 && pre==NULL)
{
G->a[v1].adj=curr->next;
free(curr);
G->numOfEdges--;
}
else if(curr!=NULL && curr->dest==v2 && pre!=NULL)
{
pre->next=curr->next;
free(curr);
G->numOfEdges--;
}
else
{
printf("边不存在!");
}
}
//取第一个邻接顶点
int GetFirstVex(AdjLGraph G,int v)
{
Edge *p;
if(v<0 || v>=G.numOfVertices)
{
printf("参数v越界!");
return -1;
}
p=G.a[v].adj;
if(p!=NULL)
{
return p->dest;
}
else
{
return -1;
}
}
//取下一个邻接顶点
int GetNextVex(AdjLGraph G,int v1,const int v2)
{
Edge *p;
if(v1<0 || v1>=G.numOfVertices || v2<0 || v2>=G.numOfVertices)
{
printf("参数v1或v2越界!");
return -1;
}
p=G.a[v1].adj;
while(p!=NULL)
{
if(p->dest!=v2)
{
p=p->next;
continue;
}
else break;
}
p=p->next;
if(p!=NULL)
{
return p->dest;
}
else
{
return -1;
}
}
//撤销
AdjDestroy(AdjLGraph *G)
{
int i;
Edge *p,*q;
for(i=0;i<G->numOfVertices;i++)
{
p=G->a[i].adj;
while(p!=NULL)
{
q=p->next;
free(p);
p=q;
}
}
}
void main()
{
AdjLGraph g2;
Edge *p;
DataType v[]={'A','B','C','D','E'};//顶点集合
int n=5;//顶点数目
int e=6;//边数目
int i,j;
RowCol d[]={{0,1},{0,3},{3,1},{0,2},{2,4},{0,4}};//边集合
CreatGraph(&g2,v,n,d,e);
printf("顶点信息:\n");
for(i=0;i<g2.numOfVertices;i++)
{
printf("%c ",g2.a[i].data);
}
printf("边信息:\n");
for(i=0;i<g2.numOfVertices;i++)
{
printf("点%c的边有: ",g2.a[i].data);
p=g2.a[i].adj;
while(p!=NULL)
{
if(p->dest!=NULL)
{
printf("<%d,%d>",g2.a[i].source,p->dest);
}
p=p->next;
}
printf("\n");
}
printf("\n");
DeleteEdge(&g2,0,4);
printf("删除<0,4>边后:\n");
for(i=0;i<g2.numOfVertices;i++)
{
printf("点%c的边有: ",g2.a[i].data);
p=g2.a[i].adj;
while(p!=NULL)
{
if(p->dest!=NULL)
{
printf("<%d,%d>",g2.a[i].source,p->dest);
}
p=p->next;
}
printf("\n");
}
}
阅读全文
0 0
- 邻接表(c语言)
- 邻接表:C语言实现
- 将图读进邻接表实现文件C语言
- 反转一个邻接表C语言
- C语言里面邻接表的创建
- 复习(数据结构):图:c语言:邻接表
- C语言邻接表的实现
- 拓扑排序(C语言 邻接表)
- 关键路径(C语言 邻接表)
- dijkstra算法(C语言 邻接表)
- floyd算法(C语言 邻接表)
- 图的邻接表存储(C语言实现)
- 图邻接表C语言实现 拓扑排序
- 邻接表生成模型头文件C语言
- 邻接表生成模型实现文件C语言
- 图的邻接表存储以及相关操作 C语言
- 邻接表无向图(一)之 C语言详解
- 邻接表有向图(一)之 C语言详解
- 调用EntityManager出现The import javax.persistence cannot be resolved
- 配置文件保存在exe所在目录
- Books CodeForces
- Redis常用命令之排序函数
- flask使用Blueprint进行多模块应用的编写
- 邻接表(c语言)
- 基于Hexo搭建博客
- 错误解决】The prefix "context" for element "context:component
- How does Android-x86 work? --- Chih-Wei Huang answer the problem.
- Struts2_自定义转换器
- 读《大话设计模式》学习小结(一)装饰器模式
- 常见面试题
- Harmonic Number (II) LightOJ
- neo4j import tool