深度、广度遍历

深度优先搜索算法(Depth First Search),是搜索算法的一种。是沿着树的深度遍历树的节点,尽可能深的搜索树的分支。

当节点v的所有边都己被探寻过,搜索将回溯到发现节点v的那条边的起始节点。这一过程一直进行到已发现从源节点可达的所有节点为止。

如果还存在未被发现的节点,则选择其中一个作为源节点并重复以上过程,整个进程反复进行直到所有节点都被访问为止。


如右图所示的二叉树:

A 是第一个访问的,然后顺序是 B、D,然后是 E。接着再是 C、F、G。

那么,怎么样才能来保证这个访问的顺序呢?

分析一下,在遍历了根结点后,就开始遍历左子树,最后才是右子树。

因此可以借助堆栈的数据结构,由于堆栈是后进先出的顺序,由此可以先将右子树压栈,然后再对左子树压栈,

这样一来,左子树结点就存在了栈顶上,因此某结点的左子树能在它的右子树遍历之前被遍历。

深度优先遍历代码片段

//深度优先遍历
void depthFirstSearch(Tree root){
    stack<Node *> nodeStack;  //使用C++的STL标准模板库
    nodeStack.push(root);
    Node *node;
    while(!nodeStack.empty()){
        node = nodeStack.top();
        printf(format, node->data);  //遍历根结点
        nodeStack.pop();
        if(node->rchild){
            nodeStack.push(node->rchild);  //先将右子树压栈
        }
        if(node->lchild){
            nodeStack.push(node->lchild);  //再将左子树压栈
        }
    }
}

广度优先搜索算法(Breadth First Search),又叫宽度优先搜索,或横向优先搜索。

是从根节点开始,沿着树的宽度遍历树的节点。如果所有节点均被访问,则算法中止。

如右图所示的二叉树,A 是第一个访问的,然后顺序是 B、C,然后再是 D、E、F、G。

那么,怎样才能来保证这个访问的顺序呢?

借助队列数据结构,由于队列是先进先出的顺序,因此可以先将左子树入队,然后再将右子树入队。

这样一来,左子树结点就存在队头,可以先被访问到。

广度优先遍历代码片段

//广度优先遍历
void breadthFirstSearch(Tree root){
    queue<Node *> nodeQueue;  //使用C++的STL标准模板库
    nodeQueue.push(root);
    Node *node;
    while(!nodeQueue.empty()){
        node = nodeQueue.front();
        nodeQueue.pop();
        printf(format, node->data);
        if(node->lchild){
            nodeQueue.push(node->lchild);  //先将左子树入队
        }
        if(node->rchild){
            nodeQueue.push(node->rchild);  //再将右子树入队
        }
    }
}

完整代码:

/**
 * <!--
 * File   : binarytree.h
 * Author : fancy
 * Email  : [email protected]
 * Date   : 2013-02-03
 * --!>
 */
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include <Stack>
#include <Queue>
using namespace std;
#define Element char
#define format "%c"

typedef struct Node {
    Element data;
    struct Node *lchild;
    struct Node *rchild;
} *Tree;

int index = 0;  //全局索引变量

//二叉树构造器,按先序遍历顺序构造二叉树
//无左子树或右子树用‘#‘表示
void treeNodeConstructor(Tree &root, Element data[]){
    Element e = data[index++];
    if(e == ‘#‘){
        root = NULL;
    }else{
        root = (Node *)malloc(sizeof(Node));
        root->data = e;
        treeNodeConstructor(root->lchild, data);  //递归构建左子树
        treeNodeConstructor(root->rchild, data);  //递归构建右子树
    }
}

//深度优先遍历
void depthFirstSearch(Tree root){
    stack<Node *> nodeStack;  //使用C++的STL标准模板库
    nodeStack.push(root);
    Node *node;
    while(!nodeStack.empty()){
        node = nodeStack.top();
        printf(format, node->data);  //遍历根结点
        nodeStack.pop();
        if(node->rchild){
            nodeStack.push(node->rchild);  //先将右子树压栈
        }
        if(node->lchild){
            nodeStack.push(node->lchild);  //再将左子树压栈
        }
    }
}

//广度优先遍历
void breadthFirstSearch(Tree root){
    queue<Node *> nodeQueue;  //使用C++的STL标准模板库
    nodeQueue.push(root);
    Node *node;
    while(!nodeQueue.empty()){
        node = nodeQueue.front();
        nodeQueue.pop();
        printf(format, node->data);
        if(node->lchild){
            nodeQueue.push(node->lchild);  //先将左子树入队
        }
        if(node->rchild){
            nodeQueue.push(node->rchild);  //再将右子树入队
        }
    }
}

二叉树的深度优先遍历(中序遍历):

当我们利用树的深度优先遍历找到满足条件的一条路径时,需要设置一个bool类型标志,如果在左子树中已经找到,则不需递归右子树,一般采用以下步骤:

Bool findPath(pCur,pNode)

If(满足条件)

Return true;

s.push(pcur);

Bool found=false;//设置一个标志,来判断是否已经找到了一条路径

If(pCur->left)

found=findPath(pCur->left,pNode);

If(pCur->right && !found) //找到了就不用递归

found=findPath(pCur->right,pNode);

If(!found)

s.pop();

Return found;

当我们需要找到所有满足条件的路径时,一般采用如下步骤:

Void findPath(pcur,pnode)

If(满足条件)

Print;

更新状态;

s.push(pcur);

If(pcur->left)

Findpath(pcur->left,pnode);

If(pcur->right)

Findpath(pcur->right,pnode);

还原添加此节点时的状态;

s.pop();

深度、广度遍历

时间: 2024-10-10 12:32:43

深度、广度遍历的相关文章

图的表示、深度广度遍历算法及其应用

世间的一切对象都可化为节点:世间一切关系都可化为节点间的一条线:从而组成了如梦幻泡影的图.将来的环球必定是图的世界. 一.图的表示 图有有向图和无向图,表示方法一般有邻接表.邻接矩阵等方法,无向图和有向图都可以用这两种方法表示. 图1. 图的例子[1] 1.邻接表 在邻接表中,对于每个顶点u,使用一个链表把所有与u相邻的点点串起来,并标记这个集合为adj(u).举个栗子如下: 图2. 邻接表表示图的例子[1] 在真正操作图进行实验的时候,一般也都使用邻接矩阵表示,例如要存储图1中的有向图,可以直

数据结构-6-深度广度遍历搜索原理详解

深度广度遍历搜索的定义想必大家都能熟练的掌握了,下面我就通过一个图的实例,把应用的代码直接贴上供大家参考,以后可以直接借鉴或者使用. #include <iostream> #include <string> #include "Queue.h" using namespace std; //图的邻接矩阵存储表示 #define INFINITY INT_MAX #define MAX_VERTEX_NUM 20 typedef enum {DG, DN, UD

图的广度遍历和深度遍历

/* 图的遍历方法主要有两种:一种是深度优先遍历,一种是广度优先遍历.图的深度优先遍历类同于树的先根遍历,图的广度遍历类同树的层次遍历 一:连通图的深度优先遍历算法 图的深度优先遍历算法是遍历时深度优先的算法,即在图的所有邻接顶点中,每次都在访问当前顶点后,首先访问当前顶点的第一个邻接顶点. 连通图的深度优先遍历递归算法如下: 1.访问顶点v并标记顶点v已访问. 2.查找顶点v的第一个邻接顶点w. 3.若顶点v的邻接顶点w存在,则继续执行,否则算法结束. 4.若顶点w尚未被访问,则深度优先遍历递

Java 实现深度遍历和广度遍历数及其应用

一.深度遍历和广度遍历原理及实现 1.深度优先 英文缩写为DFS即Depth First Search.其过程简要来说是对每一个可能的分支路径深入到不能再深入为止,而且每个节点只能访问一次.对于上面的例子来说深度优先遍历的结果就是:A,B,D,E,I,C,F,G,H.(假设先走子节点的的左侧). 深度优先遍历各个节点,需要使用到堆(Stack)这种数据结构.stack的特点是是先进后出.整个遍历过程如下: 首先将A节点压入堆中,stack(A); 将A节点弹出,同时将A的子节点C,B压入堆中,此

第五章 图的遍历(深度遍历,广度遍历,城市地图,最少转机)

深度和广度优先搜索: 单词分解:首先是搜索 深度和广度:是针对图的遍历而言的 图:由顶点和边组成 图的遍历:把图中每一个顶点都访问一次 一: 输入: 5 5(顶点数,边数) 1 2 1 3 1 5 2 4 3 5 输出: 1 2 4 3 5 (按时间戳输出)深度遍历 1 2 3 5 4 (按时间戳输出)广度遍历 1 #include <stdio.h> 2 int map[10][10], book[10], n, m,sum; 3 void dfs(int cur) 4 { 5 int i;

数据结构-深度遍历和广度遍历(转)

本文转自http://blog.csdn.net/wingofeagle/article/details/13020373 深度遍历: 从图中某个顶点v出发,访问此顶点,然后从v的未被访问的邻接点出发深度优先遍历图,直至图中所有和v有路径相通的顶点都被访问到. 其更适合:目标比较明确,以找到目标为主要目的的情况. 广度遍历: 类似于树中的层序遍历,首先遍历完和某一顶点v相连的所有顶点,然后再遍历和这些顶点相连的顶点,以此类推. 其更适合于:不断扩大遍历范围时找到相对最优解的情况. 具体代码如下:

深度遍历与广度遍历

本盘文章是参考其他人的博客写的,只为自己记忆,参考者勿喷. 深度遍历:非递归,使用List保存已经访问过的节点 广度遍历:递归方式,List保存已经访问过的节点,使用Queue队列 具体图如下所示: package com.cust.grape; import java.util.ArrayList; import java.util.HashSet; import java.util.LinkedList; import java.util.List; import java.util.Que

图的深度和广度遍历(邻接矩阵)

这里我采用邻接矩阵的存储方式对图进行遍历 #include <iostream> #include <queue> #define INFINITY 100 #define MAXNODE 100 #define OK 1 using namespace std; typedef char VertexType; int vis[MAXNODE]; typedef struct { int adj; } ArcType; typedef struct { VertexType ve

8649 图的广度遍历

8649 图的广度遍历 时间限制:1000MS  内存限制:1000K提交次数:1573 通过次数:975 题型: 编程题   语言: G++;GCC Description 使用图的深度遍历实现的邻接表存储结构和基本操作函数,在此基础上实现图的广度遍历算法并加以测试.注意正确使用队列存储结构. 输入格式 第一行:输入0到3之间整数(有向图:0,有向网:1,无向图:2,无向网:3): 第二行:输入顶点数和边数: 第三行:输入各个顶点的值(字符型,长度〈3):(遍历从输入的第一个顶点开始) 第四行