`
hm4123660
  • 浏览: 282383 次
  • 性别: Icon_minigender_1
  • 来自: 广州
博客专栏
Dea4ce76-f328-3ab2-b24a-fb268e1eeb75
数据结构
浏览量:69988
社区版块
存档分类
最新评论

图的遍历算法详解

阅读更多

         图是一种比较重要的数据结构,无论多复杂的图都是由顶点和边构成的,图有两种常用的存储结构为邻接矩阵和邻接表。本篇博客将使用邻接表存储图,邻接表是一种顺序分配和链式分配相结合的存储方式。邻接表是表示图的标准方法,尤其对于稀疏图节省很多存储空间,空间复杂度是O(|E|+|V|). 对于每个顶点,使用一个表存放所有邻接的顶点。

        我们要操作的有向图如下:


通过图我们可以轻松画出此有向图的邻接表

 下面我们通过代码来实现图的邻接表存储结构。

 

邻接表存储

定义所需的结构体:

 

//定义邻接表结点的结构
struct node
{
	int data;//结点名
	int weight;//权值
	node * next;//下一个结点的指针
	node()
	{
		next=NULL;
	}
};

//定义邻接表的表头
struct Head
{
	int data;//结点名
	node * first;//执行第一个结点
	Head()
       {
		first=NULL;
	}
};

 

 

定义一个宏表示图的总结点数:

 

#define MAXSIZE 5  //定义图的结点数

 定义表头指针数组

 

 

Head * head[MAXSIZE];//表头指针数组

 

 

有了上面的准备我们可以开始书写存储邻接表的函数了

具体代码如下:

 

//建立邻接表
void Create(Head * & head)
{
	
	while(true)
	{
		int name,wg;
		cin>>name;//输入结点
		if(name==-1)//输入-1表示链表结束
			break;
		cin>>wg;//输入权值
		node * temp=new node;//定义表结点
		temp->data=name;
		temp->weight=wg;
		//把表结点插入到head后面
		if(head->first==NULL)
			head->first=temp;
		else
		{
			temp->next=head->first;
			head->first=temp;
		}


	}

}

 到此我们就可以通过输入把图的信息存储到邻接表里,我们已经把图数据化了,下面就可以对图进行遍历了

 

首先我们要明白图的遍历的定义。

    从给定图中任意指定的顶点(称为起始点)出发,按照某种搜索方式沿着图的边访问图中所有的顶点,使每一个顶点仅被访问一次,这个过程就是图的遍历

 

深度优先搜索算法

     深度优先搜索算法的过程是:从图中某一个初始顶点v出发,首先访问初始顶点v,然后选择一个与顶点v相邻且没被访问过的顶点w为起始顶点,再从w出发进行深度优先搜索,直到图中与当前顶点v邻接的所有顶点都被访问过为止。这里面涉及到回溯。

     根据此方法的过程,可以写出其代码

 

//递归深度优先搜索
void DFS_DG(Head *head[],int v,int visited[])//head[]-头指针数组,v-起始顶点,visited[]--标记数组
{
	node * p;//表结点
	visited[v]=1;
	cout<<v;
	p=head[v]->first;//获取第一个表结点
	while(p!=NULL)
	{
		if(visited[p->data]==0)//还没访问
			DFS_DG(head,p->data,visited);
		p=p->next;
	}
}

 

 

广度优先搜索算法

 

广度优先算法里面我们使用到队列,首先学习下队列。

 

队列

    队列也是一种运算受限的线性表。在这种线性表上,插入限定在表的某一端进行,删除限定在表的另一端进行。允许插入的一端称为队尾(Rear),允许删除的一端称为队头(Front)

    特点:队列中数据元素的入队和出队过程是按照“先进先出”的原则进行的。因此,队列又称为“先进先出”的线性表,简称FIFO

 这里我们使用顺序队列,为了充分的使用数组中的存储空间,把数组的前端和后端连接起来,形成一个环形的顺序表。下面我们将来介绍顺序队列

 

队空的条件

rear==front

 

队满的条件

(rear+1)%MAXSIZE==front//MAXSIZE队的容量

 

初始化队列很简单:

int queue[MAXSIZE],front=0,rear=0;//顺序队列,front是头,rear是尾,队列是插尾删头,先进先出

 

在队列不满的时候入队:

if((rear+1)%MAXSIZE==front)//即队满了
      return;
//入队
rear=(rear+1)%MAXSIZE;
queue[rear]=data;

 

在队不为空的时候出队

if(rear==front)//空队
    return;
//入队
front=(front+1)%MAXSIZE;
data=queue[front];

 

有了上面的队列知识,我们可以开始学习广度优先搜索了。

 

广度优先搜索算法过程是:广度优先搜索是从图的某个顶点v0出发,在访问v0之后,依次搜索访问v0的各个未被访问过的邻接点w1w2,…。然后顺序搜索访问w1的各未被访问过的邻接点,w2的各未被访问过的邻接点,…。以此类推,直到图中所有和初始点v有路径想通的顶点都被访问完为止。

 

其代码为:

//广度优先搜索遍历--使用队列
void BFS(Head *head[],int v)
{
	node *p;//表结点指针
	
	int queue[MAXSIZE],front=0,rear=0;//顺序队列,front是头,rear是尾,队列是插尾删头,先进先出
	int visited[MAXSIZE]={0};//访问标志数组初始化为0

	//开始访问
	cout<<v;
	visited[v]=1;
	rear=(rear+1)%MAXSIZE;
	queue[rear]=v;//入队

	int ok;
	while(front!=rear)//队列不为空
	{
		front=(front+1)%MAXSIZE;
		ok=queue[front];//出队
		p=head[ok]->first;//获取第一个表结点
		while(p!=NULL)//循环遍历其表结点
		{
			if(visited[p->data]==0)//该表结点没有访问过
			{
				cout<<p->data;
				visited[p->data]=1;
				rear=(rear+1)%MAXSIZE;
				queue[rear]=p->data;//入队
			}
			p=p->next;//找下一个结点
		}
	}
}

 

附上源码地址:https://github.com/longpo/algorithm/tree/master/Graph

  • 大小: 5.4 KB
  • 大小: 6.6 KB
2
0
分享到:
评论

相关推荐

    【二叉树的创建与遍历算法详解及实例】二叉树的创建与遍历算法详解及实例

    二叉树的创建与遍历二叉树的创建与遍历算法详解及实例二叉树的创建与遍历算法详解及实例二叉树的创建与遍历算法详解及实例二叉树的创建与遍历算法详解及实例二叉树的创建与遍历算法详解及实例二叉树的创建与遍历算法...

    图的遍历图的遍历图的遍历图的遍历

    图的遍历是计算机科学中图论领域的一个基础概念,主要应用于数据结构和算法分析。在图中,每个节点(也称为顶点)都可能与其他节点通过边相连,遍历图就是按照一定的顺序访问所有节点的过程。这个过程有助于我们理解...

    代码:图 有向图 Directed Graph 优先遍历算法

    ### 有向图的构建与优先遍历算法详解 在计算机科学中,图是一种重要的数据结构,用于模拟现实世界中的关系网络。有向图(Directed Graph),作为图的一种,其特点是边具有方向性,即从一个顶点指向另一个顶点。在...

    图的深度优先遍历算法源码

    ### 图的深度优先遍历算法源码解析与详解 #### 引言 在计算机科学领域,图论是一种广泛应用于各种场景的重要数据结构。其中,深度优先遍历(Depth First Search,简称DFS)是探索图中节点的一种基本算法,它沿着图...

    广度优先遍历图详解基本面

    总结起来,广度优先遍历图是一种重要的图遍历算法,它利用队列数据结构保证了节点的层次访问顺序。在数据结构学习和实际编程中,理解和掌握广度优先遍历是十分必要的,因为它不仅在理论上有重要地位,也在许多实际...

    以二叉链表作存储结构,实现先根遍历算法

    本文将深入探讨如何使用二叉链表作为存储结构来实现先根遍历算法,并进一步了解二叉树的其他遍历方式以及二叉树的基本属性计算。 ### 实验目标与要求 实验的主要目标是创建并操作一棵二叉树,具体包括: 1. **...

    java实现二叉树遍历算法(源代码)

    ### Java实现二叉树遍历算法详解 #### 一、引言 在计算机科学中,二叉树是一种常用的数据结构,广泛应用于各种算法和数据处理场景。为了更好地理解和操作二叉树,掌握其遍历算法至关重要。本文将详细介绍如何使用...

    实现二叉树的各种遍历算法实验报告.docx

    《二叉树遍历算法实现详解》 二叉树作为一种重要的数据结构,广泛应用于计算机科学的各个领域,如编译器、操作系统、图形处理等。本文主要探讨的是如何实现二叉树的三种基本遍历算法:先序遍历、中序遍历和后序遍历...

    先序遍历非递归算法(C语言)

    根据给定的信息,本文将详细解释三种二叉树非递归遍历算法的实现方法:先序遍历、中序遍历以及后序遍历,并重点介绍先序遍历的非递归算法在C语言中的具体实现。 ### 先序遍历非递归算法(C语言) #### 1. 算法概述...

    中序遍历二叉树非递归算法

    通常,我们首先通过递归来实现二叉树的遍历,但递归方法可能因深度过大导致栈溢出,因此掌握非递归版本的遍历算法显得尤为重要。 ### 中序遍历二叉树非递归算法详解 #### 1. 理解中序遍历的基本概念 中序遍历是一...

    二叉树基础知识和遍历算法等

    ### 二叉树基础知识与遍历算法详解 #### 一、二叉树基本概念 **二叉树**是一种特殊的树形结构,在计算机科学领域极为常见。它是一种数据结构,其中每个节点最多有两个子节点,通常被称为左子节点和右子节点。 ###...

    分布式排队中退避树的深度优先遍历算法.docx

    #### 四、深度优先遍历算法详解 ##### 4.1 算法原理 - **初始化**:设置根节点,表示第一次退避操作。 - **递归遍历**:从根节点开始,沿着任意一条路径递归向下遍历。对于每一个节点,检查是否已经解决了冲突。...

    matlab实现二叉树遍历算法(源代码)

    ### MATLAB 实现二叉树遍历算法的知识点详解 #### 一、二叉树节点结构体定义 在MATLAB中实现二叉树的第一步是定义一个表示二叉树节点的结构体。在这个例子中,作者定义了一个名为`TreeNode`的类来表示节点,该类...

    对所建立的二叉树分别进行先序、中序和后序遍历,并输出结果。

    二叉树遍历算法详解 在计算机科学中,二叉树是一种基本的数据结构,广泛应用于编程语言、算法设计和数据存储等领域。二叉树的遍历是指从根节点出发,按照某种顺序访问树中的每个节点的过程。常见的二叉树遍历算法有...

    C语言数据结构之图的遍历实例详解

    本文主要介绍了C语言数据结构之图的遍历实例详解的相关知识点,包括图的遍历算法、图的存储结构、图的遍历实现等。 一、图的遍历算法 图的遍历算法是指从图的一点出发,遍历图的所有顶点的过程。常见的图遍历算法...

    德州扑克Deepstack算法详解

    "德州扑克DeepStack算法详解" 德州扑克DeepStack算法是基于 Counterfactual Regret Minimization(CFR)算法的,CFR算法是一种自我博弈算法,通过自我博弈生成一系列的策略,并最小化遗憾值,获取近似的纳什均衡。 ...

    TreeView控件与SQL数据库的应用(遍历算法)

    ### TreeView 控件与 SQL 数据库的应用(遍历算法) #### 概述 在软件开发过程中,特别是桌面应用程序中,经常需要使用到图形界面来展示层次化的数据结构。`TreeView` 控件是一种非常实用的工具,它能够清晰地展现...

    KNN(1).zip 遍历算法实现K近邻

    在遍历算法中,我们需要对所有训练样本进行遍历,找到K个最近邻。可以使用优先队列(如`priority_queue`)来维护最近邻的集合,每次添加新样本时,如果队列已满(即K个样本),则比较新样本与队列尾部样本的距离,若...

Global site tag (gtag.js) - Google Analytics