图的邻接表的操作实现
2017-06-14 16:46 tlnshuju 阅读(489) 评论(0) 编辑 收藏 举报<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("顶点越界!!!\n"); } } //插入边 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("顶点集合:\n"); for(i=0;i<g.numOfVerts;i++){ printf("data=%c source=%d\n",g.a[i].data,g.a[i].source); } printf("first =%d ",GetFirstVex(g,0)); printf("\n"); }</span>
输出: