zoukankan      html  css  js  c++  java
  • 图所有路径输出

    昨天被一道华为实习题目难住了,深深地发现自己的图基础不扎实啊,今天先补一把奶——图的所有路径输出

    思想跟dfs很像,dfs是不断向一条路径遍历,遍历一个标记一个,然后要回溯一下,再找没标记的。它不能经过所有路径,但是可以经过所有节点。

    所有路径需要按照这个思路(copy一下):

    求下图中节点0到节点5的所有路径: 
    这里写图片描述

    1、 我们建立一个存储结点的栈结构,将起点0入栈,将结点0标记为入栈状态;

    2、 从结点0出发,找到结点0的第一个非入栈状态的邻结点2,将结点2标记为入栈状态;

    3、 从结点2出发,找到结点2的第一个非入栈状态的邻结点4,将结点4标记为入栈状态;

    4、 从结点4出发,找到结点4的第一个非入栈状态的邻结点5,将结点5标记为入栈状态;

    5、 栈顶结点5是终点,那么,我们就找到了一条起点到终点的路径,输出这条路径;

    6、 从栈顶弹出结点5,将5标记为非入栈状态;

    7、 现在栈顶结点为5,结点5没有除终点外的非入栈状态的结点,所以从栈顶将结点5弹出;

    8、现在栈顶结点为4,结点4除了刚出栈的结点5之外,没有非入栈状态的相邻结点,那么我们将结点4出栈;

    9、现在栈顶为结点2,结点2除了刚出栈的结点4之外,没有非入栈状态的相邻结点,那么我们将结点2出栈;

    10、现在栈顶结点为0,从节点0出发,找到结点0的第一个非入栈状态的邻结点1,将结点1标记为入栈状态;一直查找到终点节点5。

    11、重复步骤7-11,就可以找到从起点3到终点6的所有路径;

    12、栈为空,算法结束。

    以上1-5为典型的dfs的一个子过程——不撞南墙不回头的一直遍历到目的!

    接下来到头了,就要回溯了(这就涉及到递归),到上一个节点,然后以上一个节点为开始继续不撞南墙不回头。

    说到这,应该就很明白了。

    我们需要几个部分:

    1.栈

    2.打印栈函数

    3.检查接下来入栈的值是否已经在栈内的函数

    4.很像dfs的一个函数

    又到了我最喜欢的上代码环节:

    #include <iostream>
    #include <fstream>
    #include <vector>
    #include <algorithm>
    #include <string>
    #include <stack>
    
    using namespace std;
    
    
    int map[6][6] = {
        { 0, 2, 10, 5, 3, -1 },
        { -1, 0, 12, -1, -1, 10 },
        { -1, -1, 0, -1, 7, -1 },
        { 2, -1, -1, 0, 2, -1 },
        { 4, -1, -1, 1, 0, -1 },
        { 3, -1, 1, -1, 2, 0 }
    };
    
    stack<int> s;
    
    void Print(stack<int> s)
    {
        while (!s.empty())
        {
            cout << s.top() << " ";
            s.pop();
        }
        cout << endl;
    }
    bool findval(stack<int> s, int val)
    {
        while (!s.empty())
        {
            if (s.top() == val)
            {
                return true;
            }
            s.pop();
        }
        return false;
    }
    
    void AllPath(int start, int end)
    {
        if (start == end)
        {
            Print(s);
            s.pop();
            return;
        }
    
        for (int i = 0; i < 6; i++)
        {
            if (map[start][i] != -1 && start != i && findval(s, i) == false)
            {
                s.push(i);
                AllPath(i, end);
            }
        }
    
        //这一步很重要!对于start节点遍历所有连接,如果遍历完,就要把stack中的start节点pop掉,否则会无限递归
        s.pop();
    }
    
    
    int main()
    {
        int X = 0, Y = 4;
    
        s.push(X);
    
        while (!s.empty())
        {
            AllPath(X, Y);
        }
    
        return 0;
    }

    邻接矩阵中-1表示不通,0表示没有(也可以认为不通吧,反正没有自己指向自己的)。

    这样可以显示所有要走的路径。

  • 相关阅读:
    Warning: $HADOOP_HOME is deprecated解决方法
    配置hadoop-1.2.1 eclipse开发环境
    Retinex图像增强算法代码
    XML 处理利器 : XStream
    #一周五# win10通用平台,无处不在的Xamarin,msbuild开源,MVP卢建晖的Asp.NET 5系列 (视频)
    javascript两种声明函数的方式的一次深入解析
    Spring AOP (二)
    Spring AOP (一)
    如何成为Android高手
    模拟 POJ 2993 Emag eht htiw Em Pleh
  • 原文地址:https://www.cnblogs.com/wyc199288/p/6618356.html
Copyright © 2011-2022 走看看