邻接表(c语言)

来源:互联网 发布:美工包括哪些 编辑:程序博客网 时间:2024/06/01 09:20
#include <stdio.h>
#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");
}
}
原创粉丝点击