图形的遍历

图形的遍历一个图形G=(V,E),存在某一顶点v,希望从v开始,通过此顶点相邻的顶点而去访问G中其他顶点直达全部的顶点遍历完毕。在遍历的过程中可能会重复经过某些顶点及边线,经由图形的遍历可以判断该图形是否连通,并找出连通单元和路径。图形遍历有两种方法:深度优先搜索Deep-First-Search广度优先搜索Breadth-First-Search一、深度优先搜索从图形的某一顶点开始遍历,被访问过的

大家好,又见面了,我是你们的朋友全栈君。

一个图形G=(V,E),存在某一顶点v,希望从v开始,通过此顶点相邻的顶点而去访问G中其他顶点直达全部的顶点遍历完毕。在遍历的过程中可能会重复经过某些顶点及边线,经由图形的遍历可以判断该图形是否连通,并找出连通单元和路径。
图形遍历有两种方法:

  • 深度优先搜索Deep-First-Search
  • 广度优先搜索Breadth-First-Search

一、深度优先搜索

从图形的某一顶点开始遍历,被访问过的顶点做上已访问的标记,接着从与此顶点相邻且未访问过的顶点中选择任意一个顶点,并做上已访问的记号,再以该顶点为新的起点进行深度优先搜索遍历。

我们以下图为例进行代码实现:
这里写图片描述

定义public static void DFS(int current)实现深度优先搜索,定义数组run[]来标记顶点的遍历情况,1表示已遍历,0表示未遍历。图使用邻接表进行存放,从选定顶点的链表的头结点进行判断,若该顶点未遍历,则递归调用该函数从该节点开始进行深度优先遍历,否则指针后移寻找该顶点未被遍历的顶点。

public static void DFS(int current)代码如下:

    public static void DFS(int current) {
        run[current]=1;                                        //改顶点设为已遍历
        System.out.print("["+current+"]");                     //打印顶点

        while(head[current].first!=null) {                     //从链表头结点开始
            if(run[head[current].first.data]==0)               //若该顶点未遍历就进行DFS递归调用
                DFS(head[current].first.data);
            head[current].first=head[current].first.next;      //否则指针后移
        }
    }

主要代码如下:(Node类和GraphLink类的定义见博客图表示法中的邻接表法
http://blog.csdn.net/zd454909951/article/details/78896793

public class Test {
    //静态变量可全局使用
    public static int[] run=new int[9];                     //判断顶点是否已遍历,1代表遍历,0代表未遍历
    public static GraphLink[] head=new GraphLink[9];        //声明链接表数组

    public static void main(String[] args) {
        int data[][]= {
  
  {
  
  1,2},{
  
  2,1},{
  
  1,3},{
  
  3,1},{
  
  2,4},{
  
  4,2},{
  
  2,5},{
  
  5,2},{
  
  3,6},{
  
  6,3},{
  
  3,7},{
  
  7,3},{
  
  4,5},{
  
  5,4},{
  
  6,7},{
  
  7,6},{
  
  5,8},{
  
  8,5},{
  
  6,8},{
  
  8,6}};
        System.out.println("图形的邻接表的内容:");
        for(int i=1;i<9;i++) {

            run[i]=0;
            head[i]=new GraphLink();
            System.out.print("顶点"+i+"=>");
            for(int j=0;j<data.length;j++) {
                if(data[j][0]==i)
                    head[i].insert(data[j][1]);
            }
            head[i].print();
        }
        System.out.println("深度优先遍历顶点:");
        DFS(1);    //从顶点1开始遍历
        System.out.println();
    }

程序运行结果如下:
这里写图片描述

递归函数DFS具体运行过程如下:
这里写图片描述

这里写图片描述

二、广度优先搜索

从图中的某一顶点开始遍历,然后访问所有与其相邻的顶点,最后访问所有与这些顶点相邻的顶点。
代码中需要用到队列,选择一个顶点入队,然后将其所有相邻的未被访问的顶点都入队,依次对队列中的顶点进行上述操作直到队列为空。

public static void BFS(int current)代码如下:

    /*广度优先搜索函数*/
    public static void BFS(int current) {
        Node tempNode;
        enqueue(current);                                         //将第一个顶点存入队列
        run[current]=1;                                           //将遍历过的顶点设为1
        System.out.print("["+current+"]");                        //打印该遍历过的顶点
        while(front!=rear) {                                      //判断队列是否为空
            current=dequeue();                                    //从队列中取出顶点
            tempNode=head[current].first;                         //记录目前顶点的链表的表头

            while(tempNode!=null) {                               //判断该顶点的链表是否为空,即遍历所有与该顶点相邻的顶点
                if(run[tempNode.data]==0) {                       //相邻的顶点未遍历
                    enqueue(tempNode.data);                       //访问该顶点并存入队列
                    run[tempNode.data]=1;                         //将该顶点标记为已遍历
                    System.out.print("["+tempNode.data+"]");      //打印该顶点
                }
                tempNode=tempNode.next;                           //指针后移,继续遍历出队列顶点的链表
            }
        }
    }

    /*入队*/
    public static void enqueue(int value) {
        if(rear>=MAXSIZE)                                         //队列已满
            return;
        rear++;
        queue[rear]=value;
    }

    /*出队*/
    public static int dequeue() {
        if(front==rear)                                           //队列为空
            return -1;
        front++;
        return queue[front];
    }

主要代码如下:(Node类和GraphLink类的定义见博客图表示法中的邻接表法
http://blog.csdn.net/zd454909951/article/details/78896793

public class Test {
    public static int[] run=new int[9];                          //用来记录各顶点是否遍历过
    public static GraphLink[] head=new GraphLink[9];
    public final static int MAXSIZE=10;                          //定义队列的最大容量
    static int[] queue=new int[MAXSIZE];                         //队列数组的声明
    static int front=-1,rear=-1;                                 //定义队列的头指针和尾指针

    public static void main(String[] args) {
        int data[][]= {
  
  {
  
  1,2},{
  
  2,1},{
  
  1,3},{
  
  3,1},{
  
  2,4},{
  
  4,2},{
  
  2,5},{
  
  5,2},{
  
  3,6},{
  
  6,3},{
  
  3,7},{
  
  7,3},{
  
  4,5},{
  
  5,4},{
  
  6,7},{
  
  7,6},{
  
  5,8},{
  
  8,5},{
  
  6,8},{
  
  8,6}};
        System.out.println("图形的邻接表的内容:");
        for(int i=1;i<9;i++) {
            run[i]=0;
            head[i]=new GraphLink();
            System.out.print("顶点"+i+"=>");
            for(int j=0;j<data.length;j++) {
                if(data[j][0]==i)
                    head[i].insert(data[j][1]);
            }
            head[i].print();
        }
        System.out.println("深度优先遍历顶点:");
        BFS(1);  //调用广度优先搜索函数,从顶点1开始访问
        System.out.println();
    }
}

程序运行结果如下:

这里写图片描述

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/133639.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 基于VUE + Echarts 实现可视化数据大屏展示效果[通俗易懂]

    基于VUE + Echarts 实现可视化数据大屏展示效果[通俗易懂]中国(寿光)国际蔬菜科技博览会智慧农业系统—LED拼接屏展示前端开发文档上线后呈现效果:一、开发需求及方案制定1、确定现场led拼接屏的宽高比,按照1920px*1080px的分辨率,F11全屏后刚好占满整屏且无滚动条;2、与产品设计确定页面相关功能:第一屏相关功能:实时时间、当地天气、菜博会基本信息、图表数据统计(近三日人流量、…

    2022年6月7日
    104
  • html5 移动端开发模板,搭建一个vue-cli的移动端H5开发模板

    html5 移动端开发模板,搭建一个vue-cli的移动端H5开发模板简介vue-mobile是是基于vue-cli实现的移动端H5开发模板,其中已经搭建好基本的开发框架,可帮助您实现快速开发。技术栈:vue+vux+axios+less功能搭建项目目录配置css预处理器配置UI组件库vux解决移动端适配配置页面路由缓存axios请求封装工具类函数封装toast组件封装dialog组件封装底部导航组件封装列表页demo表单页…

    2022年6月21日
    58
  • goland激活服务器(注册激活)

    (goland激活服务器)好多小伙伴总是说激活码老是失效,太麻烦,关注/收藏全栈君太难教程,2021永久激活的方法等着你。IntelliJ2021最新激活注册码,破解教程可免费永久激活,亲测有效,下面是详细链接哦~https://javaforall.net/100143.html23LNPMIJZT-eyJsaWNlbnNlSWQi…

    2022年3月29日
    271
  • LC5软件激活成功教程用户口令[通俗易懂]

    LC5软件激活成功教程用户口令[通俗易懂]一、背景知识口令认证口令认证是身份认证的一种手段,计算机通过用户输入的用户名进行身份标识,通过访问·输入的口令对其是否拥有该用户对应的真实身份进行鉴别。口令攻击口令攻击可以通过强力攻击进行激活成功教程,也可以采用字典激活成功教程和字典混合激活成功教程的方法,根据是否掌握口令加密算法和口令数据的情况,采用在线激活成功教程和离线激活成功教程的方式。LC5LC5是一款口令激活成功教程工具,也可以被网络管理员用于检测Windows、Linux系统用户是否使用了不安全的密码,被普遍认为是当前最好、最快的Windows/Linux系统管理员账

    2022年7月24日
    10
  • Java中,为什么byte类型的取值范围为-128~127?

    Java中,为什么byte类型的取值范围为-128~127?在学习Java基础语法的时候,初学者的我们可能都会有这么一个疑问为什么byte类型的取值范围为什么是[-128,127]而不是[-127,127]。01111111表示最大的数值:127,因为第一位是符号位,所以11111111应该是最小的数值:-127,不是这样才对?在解释这个问题之前我们需要了解几个概念:机器数、真值、原码、反码、补码机器数:一个数在计算机中的二进制表示形式,叫做这个数的机器

    2022年6月15日
    25
  • neokylin操作系统_kinit命令

    neokylin操作系统_kinit命令基础命令进入根目录cd/新建用户useraddname切换用户suname设置用户密码passwdname创建目录mkdirdirname目录删除(强制)rm(-rf)dirname文件创建touchfilename查看当前目录下的文件ll(-a查看隐藏文件)pwd查看当前目录或文件位置创建文件Touchaa.dataVimaaa.dataechomljs>data.log文件查看catfilename仅查看vimf

    2022年8月10日
    5

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号