图的邻接表的操作实现

<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>

输出:

时间: 2024-08-01 06:08:16

图的邻接表的操作实现的相关文章

浅谈数据结构之图的邻接表深度和广度优先遍历(九)

邻接矩阵是一种不错的图存储结构,但是我们发现,对于边数相对较少的图,这种结构是存在对存储空间的极大浪费的.我们知道,顺序存储结构存在预先分配内存可能造成空间浪费的问题,于是引出了链式存储的结构.同样的,我们也可以考虑对边或弧使用链式存储的方式来避免空间浪费的问题.因此,对于图的存储结构,我们同样引入了一种数组与链表相组合的存储方法,我们一般称之为邻接表. 邻接表的处理方法是这样的:(1).图中顶点用一个一维数组存储,当然,顶点也可以用单链表来存储,不过数组可以较容易的读取顶点的信息,更加方便:另

看数据结构写代码(36) 图的邻接表表示与实现

图的邻接表表示法,是为每一个顶点建立一个链表,链表里存放着相同弧尾的 弧的信息,这些链表顺序存放在数组中.下面是无向图g2的邻接表 邻接表 比 邻接矩阵 节省空间,同时 也带来一些操作上的 不便,例如 看 两个顶点是否 相邻,需要 遍历 链表,在 求 无向图顶点的度时,只需 遍历 顶点的链表,而 求 有向图 顶点的度 需要 遍历 整个图 查找 弧头 为这个顶点的 个数. 如果 不想这样做,可以 建立 逆邻接表,即 链表里 存放着 相同 弧头的 弧 的信息. 下一节 要说的 十字链表 类似于这种结

数据结构学习笔记05图 (邻接矩阵 邻接表--&gt;BFS DFS)

数据结构之图 图(Graph) 包含 一组顶点:通常用V (Vertex) 表示顶点集合 一组边:通常用E (Edge) 表示边的集合 边是顶点对:(v, w) ∈E ,其中v, w ∈ V 有向边<v, w> 表示从v指向w的边(单行线) 不考虑重边和自回路 无向图:边是无向边(v, w) 有向图:边是有向边<v, w> 连通:如果从V到W存在一条(无向)路径,则称V和W是连通的 连通图(Connected Graph):如果对于图的任一两个顶点v.w∈V,v和w都是连通的,则称

图的邻接表表示、广度优先、深度优先搜索

图,就是我们在数据结构中学到的图,它是一种存储信息的结构.图是一类在实际应用中非常常见的数据结构,当数据规模大到一定程度时,如何对其进行高效计算即成为迫切需要解决的问题.最常见的大规模图数据的例子就是互联网网页数据,网页之间通过链接指向形成规模超过500 亿节点的巨型网页图.再如,Facebook 社交网络也是规模巨大的图,仅好友关系已经形成超过10 亿节点.千亿边的巨型图,考虑到Facebook 正在将所有的实体数据节点都构建成网状结构,其最终形成的巨型网络数据规模可以想见其规模.要处理如此规

数据结构之---C语言实现图的邻接表存储表示

// 图的数组(邻接矩阵)存储表示 #include <stdio.h> #include <stdlib.h> #include <string.h> #define MAX_NAME 3 // 顶点字符串的最大长度+1 #define MAX_VERTEX_NUM 20 typedef int InfoType; // 存放网的权值 typedef char VertexType[MAX_NAME]; // 字符串类型 typedef enum{DG, DN, AG

图(邻接表)

我们先来看一个图 我们想将这个图的信息存储到邻接表中,我们需要一个数组保存节点信息,还要有一个节点用来保存与该节点相邻的节点信息. 1 typedef struct arc_node 2 { 3 int pos; 4 int distance; 5 struct arc_node * next; 6 } Arc_node;//保存Node节点的相邻节点信息 7 8 typedef struct node 9 { 10 node_type info; 11 Arc_node * next; 12

数据结构(10) -- 图的邻接表存储

////////////////////////////////////////////////////////// //图的邻接表存储 ////////////////////////////////////////////////////////// #include <iostream> #include <stdlib.h> using namespace std; //图的邻接表表示法 #define MaxVertexNum 100 enum GraphType{DG,

_DataStructure_C_Impl:图的邻接表存储

#include<stdio.h> #include<stdlib.h> #include<string.h> //图的邻接表类型定义 typedef char VertexType[4]; typedef char InfoPtr; typedef int VRType; #define INFINITY 10000 //定义一个无限大的值 #define MaxSize 50 //最大顶点个数 typedef enum{DG,DN,UG,UN}GraphKind;

基于C++ STL图的邻接表表示及深度、广度搜索实现

基于C++ STL图的邻接表表示及深度.广度搜索实现,对图论的学习有帮助,代码如下: #include <iostream> #include <vector> #include <set> using namespace std; #define MAX(a, b) ((a) > (b) ? (a) : (b) ) //定义图的定点 typedef struct Vertex { int id; vector<int> connectors; //存