`
Touch_2011
  • 浏览: 290491 次
  • 性别: Icon_minigender_1
  • 来自: 武汉
社区版块
存档分类
最新评论

邻接表存储的有向图的基本操作(C语言实现)

阅读更多
/*
 * 邻接表存储的有向图的基本操作
 */
#include<stdio.h>
#include<stdlib.h>

#define MAX_VERTEX 20
typedef char VertexType;

//用数组vertex按序存放遍历的各个顶点,广度遍历时看成队列,深度遍历时看成栈
VertexType vertex[MAX_VERTEX];

//图的边的定义
typedef struct EdgeNode
{
	int nextToVertex;           //相邻顶点
    struct EdgeNode * nextEdge; //下一条边
}EdgeNode,*PEdgeNode;

//图的顶点的定义
typedef struct
{
	VertexType vertex;      //顶点信息
    PEdgeNode  firstEdge;   //第一条边(出度)
}VertexNode,*PVertexNode;

//图的定义 
typedef struct 
{
    int vertexNum;         //顶点个数
	int edgeNum;           //边的个数
	VertexNode vertexNode[MAX_VERTEX]; //顶点信息数组
}GraphList,*PGraphList;

//建立有向图
void createGraph(PGraphList pGraph)
{
	int i,from,to;
	PEdgeNode p,pEdge;
    
	printf("请输入有向图顶点个数:\n");
	scanf("%d",&pGraph->vertexNum);
	for(i=0;i<pGraph->vertexNum;i++){
        pGraph->vertexNode[i].vertex='a'+i; 
		pGraph->vertexNode[i].firstEdge=NULL;
	}
	printf("请输入有向图边的个数:\n");
	scanf("%d",&pGraph->edgeNum);
	printf("请输入有向图边的信息:\n");
	printf("起始点   终点\n");
	for(i=0;i<pGraph->edgeNum;i++){
		scanf("%d%d",&from,&to);

		pEdge=(PEdgeNode)malloc(sizeof(EdgeNode));
		pEdge->nextEdge=NULL;
		pEdge->nextToVertex=to;

		p=pGraph->vertexNode[from].firstEdge;
		if(!p)
           pGraph->vertexNode[from].firstEdge=pEdge;
        else{
			while(p->nextEdge){
               p=p->nextEdge;
			}
			p->nextEdge=pEdge;
		}
	}
}

//求指定顶点
VertexType getVertexByIndex(PGraphList pGraph,int index)
{
	return pGraph->vertexNum==0?'0':pGraph->vertexNode[index].vertex;
}

//求第一个顶点
VertexType getFirstVertex(PGraphList pGraph)
{
	return pGraph->vertexNum==0?'0':pGraph->vertexNode[0].vertex;
}

//求图中顶点index的下一个顶点
VertexType getVertexAfterIndex(PGraphList pGraph,int index)
{
    return (index>=0 && index+1 < pGraph->vertexNum) ? pGraph->vertexNode[index+1].vertex : '0';
}

//求第一个与顶点index相邻的顶点
VertexType getVertexNextIndex(PGraphList pGraph,int index)
{
	if(index>=0&&index<pGraph->vertexNum){
        if(pGraph->vertexNode[index].firstEdge)
			return pGraph->vertexNode[pGraph->vertexNode[index].firstEdge->nextToVertex].vertex;
	}
	return '0';
}

//根据顶点信息寻返回顶点在图中的位置
int findVertex(PGraphList pGraph,VertexType vertex)
{
	int i;
	for(i=0;i<pGraph->vertexNum;i++)
		if(pGraph->vertexNode[i].vertex==vertex)
			return i;
	return -1;
}

//返回任一顶点的出度
int getArcsNum(PGraphList pGraph,int index)
{
	int k=0;
	PEdgeNode p=pGraph->vertexNode[index].firstEdge; 
	if(index>=0&&index<pGraph->vertexNum){
		while(p){
			k++;
			p=p->nextEdge;
		}
		return k;
	}
	return -1;
}

//判断任意两个顶点之间是否有边
int connected(PGraphList pGraph,int from,int to)
{
	PEdgeNode p=pGraph->vertexNode[from].firstEdge;
    if((from<0 || from>=pGraph->vertexNum) || (to<0 && to>=pGraph->vertexNum))
		return 0;
	while(p){
		if(p->nextToVertex==to)
			return 1;
		p=p->nextEdge;
	}
	return 0;
}

//广度优先遍历
void breadthTraverse(PGraphList pGraph)
{
	int i,k;
	int flag[MAX_VERTEX];//记录顶点的下标
	int front,rear;
    PEdgeNode p;
	front=rear=0;
	for(i=0;i<MAX_VERTEX;i++)
		flag[i]=-1;
	//从第一个顶点开始
	front=rear=0;
	vertex[rear++]=pGraph->vertexNode[0].vertex;
	flag[0]=0;

	while(front<rear){
		i=flag[front];
		p=pGraph->vertexNode[i].firstEdge;
		while(p){
			for(k=0;k<rear;k++)//判断此顶点是否在队列中
				if(flag[k]==p->nextToVertex)
					break;
            if(k==rear){
				vertex[rear]=pGraph->vertexNode[p->nextToVertex].vertex;
				flag[rear++]=p->nextToVertex;
			}
			p=p->nextEdge;
		}
		front++;
	}
}

//深度优先遍历
void depthTraverse(PGraphList pGraph)
{
	int i,top=0,k,m;
	int flag[MAX_VERTEX];//记录顶点的下标
	PEdgeNode p;
	for(i=0;i<MAX_VERTEX;i++)
		flag[i]=-1;
	//从第一个顶点开始
	vertex[top++]=pGraph->vertexNode[0].vertex;
	flag[0]=0;

	while(top>0 && top<pGraph->vertexNum){
		if(!p)//退栈,从上一个顶点开始
			i=flag[--m];
		else
			m=i=flag[top-1];
       
		p=pGraph->vertexNode[i].firstEdge;
        while(p){
        	for(k=0;k<top;k++)
				if(flag[k]==p->nextToVertex)
					break;
            if(k==top){
				vertex[top]=pGraph->vertexNode[p->nextToVertex].vertex;
				flag[top++]=p->nextToVertex;
				break;
			}
			p=p->nextEdge;
		} 
	}
}

//测试
void main()
{
	int i;
    GraphList  graph;
    createGraph(&graph);
	printf("指定顶点:%c\n",getVertexByIndex(&graph,0));
	printf("第一个顶点:%c\n",getFirstVertex(&graph));
	printf("index的下一个顶点:%c\n",getVertexAfterIndex(&graph,0));
	printf("第一个与顶点index相邻的顶点:%c\n",getVertexNextIndex(&graph,0));
	printf("根据顶点信息寻返回顶点在图中的位置:%d\n",findVertex(&graph,'b'));
	printf("返回任一顶点的出度:%d\n",getArcsNum(&graph,0));
	printf("判断任意两个顶点之间是否有边:%d\n",connected(&graph,0,1));

    printf("-----------广度优先遍历-----------------\n\n");
	breadthTraverse(&graph);
	for(i=0;i<graph.vertexNum;i++)
    	printf("%-3c",vertex[i]);

    printf("\n\n-------深度优先遍历------------------\n\n");
	depthTraverse(&graph);
	for(i=0;i<graph.vertexNum;i++)
    	printf("%-3c",vertex[i]);
	printf("\n\n");
}

 

1
0
分享到:
评论

相关推荐

    图的邻接表存储C语言实现

    ### 图的邻接表存储与C语言实现:深入解析 #### 核心概念与背景 在数据结构领域,图是一种非常重要的非线性数据结构,它由顶点集(Vertex Set)和边集(Edge Set)组成。在图中,顶点代表数据对象,而边则表示这些...

    C语言数据结构邻接表课程设计

    在“C语言数据结构邻接表课程设计”中,我们将深入探讨如何利用C语言实现数据结构中的邻接表,这是图论中一个重要的抽象概念。邻接表是表示图的有效方式,尤其对于稀疏图(边的数量远小于顶点数量的平方)来说,它的...

    有向图的邻接表遍历(c语言)

    通过阅读和学习这个代码,你可以掌握如何在C语言中使用邻接表表示有向图,并实现这两种遍历算法。这不仅有助于理解图的遍历,还能增强C语言编程技能,对解决实际问题有很大帮助。 为了确保代码的正确性和效率,应当...

    用c语言写的图的邻接表操作集合

    这个“图的邻接表基本操作集合”可能包含了以上提到的一些或所有功能,通过阅读和分析源代码,可以深入理解邻接表的工作原理,以及如何用C语言高效地实现图的各种操作。对于学习数据结构和算法,尤其是图论的初学者...

    C#有向图算法(邻接表包含关键路径、DFS、BFS、拓扑排序)

    本文将详细讲解如何使用C#语言实现有向图算法,包括邻接表、关键路径、深度优先搜索(DFS)和广度优先搜索(BFS),以及拓扑排序。 首先,我们要理解有向图的概念。有向图是由顶点(节点)和边组成的,边具有方向性...

    数据结构C语言版_图的邻接矩阵存储表示和实现

    ### 数据结构C语言版_图的邻接矩阵存储表示和实现 #### 1. 图的邻接矩阵存储表示概述 图是一种重要的非线性数据结构,由顶点集和边集组成,用数学符号表示为 G = (V, E),其中 V 是顶点集合,E 是边集合。在计算机...

    c语言 用邻接矩阵构造图,输出对应的邻接表

    而对于有向图,这个性质可能不成立。 在程序的开始,用户会被要求输入图的节点数和边数。节点数表示图中顶点的数量,而边数则表示连接这些顶点的边的数量。这两个值是构建邻接矩阵的基础,因为它们决定了矩阵的大小...

    数据结构学习--图的邻接矩阵和邻接表存储

    总的来说,理解和熟练掌握图的邻接矩阵和邻接表存储方式,对于解决实际问题,如网络路由、社交网络分析、图形算法等具有重要意义。通过这样的实验,可以加深对这两种存储方式的理解,提高编程能力。

    无向图_C语言_

    总之,这个项目涵盖了无向图的邻接表存储、深度优先搜索以及先序遍历等核心概念,是学习和实践图论及C语言编程的好例子。通过这个项目,开发者可以深入了解图的存储和遍历算法,并提升解决复杂问题的能力。

    邻接表建立(C语言)

    对于有向图,只有起点会在终点的邻接表中出现。 3. **C语言基础**: - **变量声明**:在C语言中,我们需要先声明变量类型,然后给变量命名。例如,`int vertex, edge;` 声明了两个整型变量。 - **结构体**:C语言...

    无向图的邻接矩阵存储及输出

    通过邻接矩阵来存储和操作无向图是一种直观且高效的方法,特别是在处理稠密图时。本文介绍的代码示例提供了从创建无向图到输出邻接矩阵的完整过程,有助于理解无向图的邻接矩阵表示方法及其应用。在实际编程中,选择...

    邻接链表法实现图C代码

    对于有向图,出度是发往其他节点的边数,入度是从其他节点接收的边数。 8. **获取图的结点数**:图的结点数是图中所有节点的总数,可以通过维护一个计数器或者遍历所有节点来计算。 9. **获取图的边数**:图的边数...

    数据结构实验3.4:以邻接表为存储结构的图的深度、宽度优先遍历.doc

    在计算机科学中,图是一种表示对象间关系的数据结构,邻接表是高效存储无向图或有向图的一种方式,它通过链表来存储各个顶点的邻接点。 深度优先遍历是一种递归的搜索策略,从给定的起始顶点开始,沿着图中的边尽...

    c语言图结构邻接表

    对于一个无向图或有向图,邻接表通过一系列链表来表示图中的顶点及其连接的边。每个顶点都对应着一个链表,链表中的节点(称为边节点)存储了与该顶点相连的所有邻接顶点的信息。这种方式特别适用于稀疏图(即边的...

    数据结构-c语言-带main函数-图7.2-图的存储结构-图的邻接表的创建-无向图。

    图可以分为有向图和无向图两种,无向图是指边没有方向的图。在本节中,我们将讨论无向图的存储结构。 图的存储结构 图的存储结构可以分为邻接矩阵和邻接表两种。在本节中,我们将讨论邻接表的存储结构。 邻接表 ...

    数据结构一学期作业(顺序栈,三元组,串,树,邻接表,邻接矩阵,二叉树,等等代码c语言实现)

    一学期数据结构的代码作业,基本上涵盖了课本上面所有算法的C语言代码实现,压缩包无密码 2019/11/03 21:43 1,478 BF_KMP.cpp 2019/11/03 21:22 2,664 KMP.cpp 2019/10/24 18:49 3,956 LinkStack.cpp 2019/11/21 ...

    c语言实现图的拓扑排序

    通过上述C语言实现,我们可以对任何有向无环图进行拓扑排序。这个过程涉及到图的遍历、队列的操作以及邻接表的管理,是数据结构和算法学习中的经典问题。掌握这种方法不仅可以加深对图的理解,也有助于提升编程解决...

    图的邻接表(c语言 算法 程序)

    在邻接表中,每个节点将有一个链表,存储与其相邻的所有节点。 ```c typedef struct Node { int id; // 其他可能的属性,如权重等 } Node; typedef struct Edge { Node *neighbor; // 边可能具有的其他属性,...

Global site tag (gtag.js) - Google Analytics