图的邻接表的操作实现

<span style="font-size:18px;">#include<stdio.h>
#include<malloc.h>
#define MaxVertices 10       //定义顶点的最大值 
typedef char DataType;

typedef struct Node{

	int dest;//邻接边的弧头顶点序号
	struct Node *next;//单链表的下一个结点指针
}Edge;//邻接边单链表的结点结构体


typedef struct{

	DataType data;//顶点数据元素
	int source;//邻接边的弧尾顶点序号
	Edge *adj;//邻接边的头指针
}AdjLHeight;//数组的数据元素类型结构体

typedef struct {
	AdjLHeight a[MaxVertices];//邻接表数组
    int numOfVerts;//顶点个数
	int numOfEdges;//边个数
}AdjLGraph;//邻接表结构体


//定义例如以下的结构体来完毕创建图的须要
typedef struct{

	int row;//行下标
	int col;//列下标
}RowCol;//边信息结构体



//初始化
void AdjInitiate(AdjLGraph *g){

	int i;
	g->numOfEdges=0;
	g->numOfVerts=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){
//在图G中的第i(0<=i<MaxVertices)个位置插入顶点数据元素vertex
	if(i>=0&&i<MaxVertices){
	
		g->a[i].data=vertex;//存储顶点数据元素vertex
		g->numOfVerts++;//个数加一
	}else{
	
		printf("顶点越界!!!
");
	}
}

//插入边
void InsertEdge(AdjLGraph *g,int v1,int v2){
//在图G中增加边<v1,v2>
	Edge *p;
	if(v1<0||v1>=g->numOfVerts||v2<0||v2>=g->numOfVerts){
	
		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++;//边个数加1

}


//删除边
void DeleteEdge(AdjLGraph *g,int v1,int v2){
//删除图G中的边<v1,v2>
	Edge *curr,*pre;
	if(v1<0||v1>=g->numOfEdges||v2<0||v2>=g->numOfEdges){
	
		printf("參数v1或v2越界出错!!!");
		return ;
	}

	pre=NULL;
	curr=g->a[v1].adj;
	while(curr!=NULL){
	//在v1顶点的邻接边单链表中查找v2顶点
		pre=curr;
		curr=curr->next;
	}

	//删除邻接边<v1,v2>
	if(curr!=NULL&&curr->dest==v2&&pre==NULL){
	//当邻接边<v1,v2>的结点是单链表的第一个结点时
		g->a[v1].adj=curr->next;
		free(curr);
		g->numOfEdges--;
	}else if(curr!=NULL&&curr->dest==v2&&pre!=NULL){
	//当邻接边<v1,v2>的结点不是单链表的第一个节点时
		pre->next=curr->next;
		free(curr);
		g->numOfEdges--;
	}else{
	
		//当邻接边<v1,v2>不存在时
		printf("边<v1,v2>不存在!!!");
	}
}


//取第一个邻接顶点
int GetFirstVex(AdjLGraph g,int v){
//取图G中的顶点v的第一个邻接顶点
	//取到时。则返回该邻接顶点相应序号;否则返回-1
	Edge *p;
	if(v<0||v>=g.numOfVerts){
	
		printf("參数v越界出错");
		return -1;
	}

	p=g.a[v].adj;
	if(p!=NULL){
	
		return p->dest;//返回该邻接顶点的相应序号
	}else{
	
		return -1;//返回-1
	}

}


//取下一个邻接顶点
int GetNextVex(AdjLGraph g,int v1,int v2){
//取图G中顶点v1的邻接顶点v2的下一个邻接顶点
	//取到时,则返回该邻接顶点的相应序号;否则返回-1
	Edge *p;
	if(v1<0||v1>=g.numOfVerts||v2<0||v2>=g.numOfVerts){
	
		printf("參数v1或v2越界出错");
		return -1;
	}

	p=g.a[v1].adj;
	while(p!=NULL){//寻找顶点v1的邻接顶点v2
		if(p->dest!=v2){
		
			p=p->next;
			continue;
		}else{
		
			break;
		}
	}

	p=p->next;//p指向该邻接顶点v2的下一个邻接顶点
	if(p!=NULL){
	
		return p->dest;//返回该邻接顶点的相应序号
	}else{
	
		return -1;//返回-1
	}
}


//撤销
void AdjDestroy(AdjLGraph *g){
//撤销图G中的全部单链表占用的存储空间
	int i;
	Edge *p,*q;
	for(i=0;i<g->numOfVerts;i++){
	
		p=g->a[i].adj;
		while(p!=NULL){
		
			q=p->next;
			free(p);
			p=q;
		}
	}
}


//创建图
void CreatGraph(AdjLGraph *g,DataType v[],int n,RowCol d[],int e){
//创建有n个顶点e条边的图
	//顶点信息存放在数组v中,边信息存放在数组d中
	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 main(){
	AdjLGraph g;  
    DataType a[]={'A','B','C','D','E'};  
    RowCol rc[]={{0,1},{0,4},{1,3},{2,1},{3,2}};  
    int n=5,e=5;
	int i,j;
    CreatGraph(&g,a,n,rc,e);//创建图 
	printf("顶点集合:
");
	for(i=0;i<g.numOfVerts;i++){
		printf("data=%c  source=%d
",g.a[i].data,g.a[i].source);
	}
	printf("first =%d ",GetFirstVex(g,0));
	printf("
");
}</span>





输出:









原文地址:https://www.cnblogs.com/tlnshuju/p/7009712.html