草庐IT

c++ - 深度优先图遍历

coder 2024-02-12 原文

我正在尝试打印深度优先遍历。我有以下代码继续给我一个段错误。当我尝试打印图中的最后一个顶点时,它似乎正在发生。我从顶点“A”开始的第一次遍历按预期工作。但是当我尝试从 D 开始进行深度优先打印时,我遇到了段错误。这是我的源代码:

这是我的原始源代码:

void wdigraph::depth_first(int u) const {

  bool found = false;

  vector<bool> visited;             // create a boolean vector
  for(int i =0; i < size; i++)      // the size of the graph
    visited.push_back(false);       // to mark when a node has been visited

  stack<int> depth_first;           // used to hold vertices that have been visited
  visited[u] = true;                // mark as visited
  cout << label[u];                 // print first vertex
  depth_first.push(u);              // put first vertex on stack

  while(!all_visited(visited)) {    // continue until all vertices have been visited
    found = false;

    for(unsigned i = 0; i < visited.size() && !found; i++) {
      if(adj_matrix[u][i] != 0 && !visited[i]) {  // found next vertex
        cout << "->" << label[i];   // print vertex
        visited[i] = true;          // mark vertex as visited
        depth_first.push(i);        // push vertx onto stack
        found = true;               // set found = true to end for loop
        u = i;
      }//endif
    }//endfor  

    if(found == false) {            // no available neighbors
      u = depth_first.top();        // get top of stack
      depth_first.pop();            // pop from stack
    }//endif
  }//endwhile 

  cout << '\n';
}

void wdigraph::print_graph() const {
  cout << '\n';
  cout << "No of Nodes = " << size << endl;

  cout << "\nAdjacency Matrix\n" << endl;

  cout << "  |";
  for(int i = 0; i < size; i++)
    cout << "  " << label[i];

  cout << '\n';

  cout << "--|";
  for(int i = 0; i < size; i++)
    cout << "---";
  cout << '\n';

  for(int i = 0; i < size; i++) {
    cout << label[i] << " |";

    for(int j = 0; j < size; j++) {
      if(adj_matrix[i][j] != 0)
        cout << " " << setw(2) << right << adj_matrix[i][j];
      else
        cout << "  -";
    }//endjfor

      cout << '\n';

      if(i != size-1)
        cout << "  |" << endl;
  }//endifor

  cout << '\n';
}
bool all_visited(vector<bool> &v) {
  for(unsigned i = 0; i < v.size(); i++)
    if(v[i] == false)
      return false;

  return true;
}

这是头文件和构造函数:

// definition of weighted digraph

#define NO_NODES   1    // default size for no of nodes in digraph
#define LINK_PROB  0.25 // prob of having direct link between nodes
#define MAX_WEIGHT 10   // max weight factor for links
class wdigraph {
public:
    wdigraph ( int = NO_NODES );            // default constructor
    ~wdigraph ( ) { };                      // destructor
    int get_size ( ) const { return size; } // returns size of digraph

    void depth_first ( int ) const;// traverses graph using depth-first search
    void print_graph ( ) const;    // prints adjacency matrix of digraph

private:
    int size;                               // size of digraph
    vector < char > label;                  // node labels
    vector < vector < int > > adj_matrix;   // adjacency matrix
};

// default class constructor

wdigraph :: wdigraph ( int n ) : size ( n )
{
    // allocate dynamic memory

    label = vector < char > ( size );
    adj_matrix = vector < vector < int > > ( size );
    for ( int i = 0; i < size; i++ )
        adj_matrix [ i ] = vector < int > ( size );

    // assign labels to each node

    label [ 0 ] = 'A';
    for ( int i = 1; i < size; i++ )
        label [ i ] = label [ i - 1 ] + 1;

    // determine weights for links between nodes randomly
    // and build adjacency matrix

    srand ( 1 );
    for ( int i = 0; i < size; i++ ) {
        adj_matrix [ i ] [ i ] = 0;
        bool flag = false;
        for ( int j = 0; j < size; j++ ) {
            if ( j == i ) continue;
            double r = ( double ) rand ( ) / RAND_MAX;
            adj_matrix [ i ] [ j ] =
                ( r <= LINK_PROB ) ? rand ( ) % MAX_WEIGHT + 1 : 0;
            if ( adj_matrix [ i ] [ j ] > 0 ) flag = true;
        }

        // if node is not connected to any other node, then
        // connect this node to random node

        if ( size > 1 && !flag ) {
            int k; while ( ( k = rand ( ) % size ) == i ) ;
            adj_matrix [ i ] [ k ] = rand ( ) % MAX_WEIGHT + 1;
        }
    }
}

这是主要程序:

#define M  3   // print every M-th node's path when traversing
#define N2 5   // number of nodes in second graph
#define N3 20  // number of nodes in third graph


void proc_graph(wdigraph&);       // function declaration

int main() {
  // create three weighted digraphs
  wdigraph graph1(NO_NODES);
  wdigraph graph2(N2);
  wdigraph graph3(N3);

  //proc_graph(graph1);   // print first graph
  proc_graph(graph2);   // print first graph
  //proc_graph(graph3);   // print first graph

  return 0;
}

void proc_graph(wdigraph &g) {
  cout << '\n';
  cout << "A Weighted Digraph" << endl;    // print header
  cout << "__________________" << endl;    // print header underline

  g.print_graph();                         // print graph

  cout << "Paths by Depth-First Search" << endl;
  for(int i = 0; i < g.get_size(); i += M)
    g.depth_first(i);
}

这是我得到的输出。该图显示了每条边的权重。 '-' 表示没有边缘。

A Weighted Digraph
__________________

No of Nodes = 5

Adjacency Matrix

  |  A  B  C  D  E
--|---------------
A |  -  -  -  6  -
  |
B |  -  -  8  -  -
  |
C |  7  -  -  -  -
  |
D |  7  9 10  -  1
  |
E |  4  - 10  -  -

Paths by Depth-First Search
A->D->B->C->E
Segmentation fault (core dumped)

如果我从 for 循环中删除 u = i 代码,那么我的程序可以正常运行。这是我尝试打印第三张图时的输出。请注意,我的遍历没有正确行进。

最佳答案

所以我使用以下算法解决了我的问题。希望这对遇到同样问题的人有所帮助。

push current onto stack
mark as visited
print current
while (stack is not empty) {
  current = stack top
  of N neighbors of current, find first that hasnt been visited
    if such neighbor exists
      add to stack
      mark as visited
      print
    if no neighbor exists
      pop from stack
}

关于c++ - 深度优先图遍历,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20292910/

有关c++ - 深度优先图遍历的更多相关文章

  1. ruby-on-rails - 在 Ruby 中循环遍历多个数组 - 2

    我有多个ActiveRecord子类Item的实例数组,我需要根据最早的事件循环打印。在这种情况下,我需要打印付款和维护日期,如下所示:ItemAmaintenancerequiredin5daysItemBpaymentrequiredin6daysItemApaymentrequiredin7daysItemBmaintenancerequiredin8days我目前有两个查询,用于查找maintenance和payment项目(非排他性查询),并输出如下内容:paymentrequiredin...maintenancerequiredin...有什么方法可以改善上述(丑陋的)代

  2. ruby-on-rails - 如何优雅地重启 thin + nginx? - 2

    我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server

  3. ruby - 使用 `+=` 和 `send` 方法 - 2

    如何将send与+=一起使用?a=20;a.send"+=",10undefinedmethod`+='for20:Fixnuma=20;a+=10=>30 最佳答案 恐怕你不能。+=不是方法,而是语法糖。参见http://www.ruby-doc.org/docs/ProgrammingRuby/html/tut_expressions.html它说Incommonwithmanyotherlanguages,Rubyhasasyntacticshortcut:a=a+2maybewrittenasa+=2.你能做的最好的事情是:

  4. 深度学习部署:Windows安装pycocotools报错解决方法 - 2

    深度学习部署:Windows安装pycocotools报错解决方法1.pycocotools库的简介2.pycocotools安装的坑3.解决办法更多Ai资讯:公主号AiCharm本系列是作者在跑一些深度学习实例时,遇到的各种各样的问题及解决办法,希望能够帮助到大家。ERROR:Commanderroredoutwithexitstatus1:'D:\Anaconda3\python.exe'-u-c'importsys,setuptools,tokenize;sys.argv[0]='"'"'C:\\Users\\46653\\AppData\\Local\\Temp\\pip-instal

  5. 【Java入门】使用Java实现文件夹的遍历 - 2

    遍历文件夹我们通常是使用递归进行操作,这种方式比较简单,也比较容易理解。本文为大家介绍另一种不使用递归的方式,由于没有使用递归,只用到了循环和集合,所以效率更高一些!一、使用递归遍历文件夹整体思路1、使用File封装初始目录,2、打印这个目录3、获取这个目录下所有的子文件和子目录的数组。4、遍历这个数组,取出每个File对象4-1、如果File是否是一个文件,打印4-2、否则就是一个目录,递归调用代码实现publicclassSearchFile{publicstaticvoidmain(String[]args){//初始目录Filedir=newFile("d:/Dev");Datebeg

  6. ruby - Chef Ruby 遍历 .erb 模板文件中的属性 - 2

    所以这可能有点令人困惑,但请耐心等待。简而言之,我想遍历具有特定键值的所有属性,然后如果值不为空,则将它们插入到模板中。这是我的代码:属性:#===DefaultfileConfigurations#default['elasticsearch']['default']['ES_USER']=''default['elasticsearch']['default']['ES_GROUP']=''default['elasticsearch']['default']['ES_HEAP_SIZE']=''default['elasticsearch']['default']['MAX_OP

  7. ruby - 如何计算 Liquid 中的变量 +1 - 2

    我对如何计算通过{%assignvar=0%}赋值的变量加一完全感到困惑。这应该是最简单的任务。到目前为止,这是我尝试过的:{%assignamount=0%}{%forvariantinproduct.variants%}{%assignamount=amount+1%}{%endfor%}Amount:{{amount}}结果总是0。也许我忽略了一些明显的东西。也许有更好的方法。我想要存档的只是获取运行的迭代次数。 最佳答案 因为{{incrementamount}}将输出您的变量值并且不会影响{%assign%}定义的变量,我

  8. ruby - 如何遍历 Ruby 中所有正则表达式匹配的字符串? - 2

    我们有一个字符串:“”这个正则表达式://i如何从当前字符串中获取所有匹配项? 最佳答案 "".scan(//)参见scan在ruby​​-docs上 关于ruby-如何遍历Ruby中所有正则表达式匹配的字符串?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/6857852/

  9. arrays - Ruby 数组 += vs 推送 - 2

    我有一个数组数组,想将元素附加到子数组。+=做我想做的,但我想了解为什么push不做。我期望的行为(并与+=一起工作):b=Array.new(3,[])b[0]+=["apple"]b[1]+=["orange"]b[2]+=["frog"]b=>[["苹果"],["橙子"],["Frog"]]通过推送,我将推送的元素附加到每个子数组(为什么?):a=Array.new(3,[])a[0].push("apple")a[1].push("orange")a[2].push("frog")a=>[[“苹果”、“橙子”、“Frog”]、[“苹果”、“橙子”、“Frog”]、[“苹果”、“

  10. += 的 Ruby 方法 - 2

    有没有办法让Ruby能够做这样的事情?classPlane@moved=0@x=0defx+=(v)#thisiserror@x+=v@moved+=1enddefto_s"moved#{@moved}times,currentxis#{@x}"endendplane=Plane.newplane.x+=5plane.x+=10putsplane.to_s#moved2times,currentxis15 最佳答案 您不能在Ruby中覆盖复合赋值运算符。任务在内部处理。您应该覆盖+,而不是+=。plane.a+=b与plane.a=

随机推荐