我想使 DFS 与相邻矩阵具有相邻列表的 DFS 能力

问题描述

请告诉我如何通过插入任何代码性能从 O(n^2) 更改为 O(n+e) .. 无需修改

typedef struct GraphType 
{ 
    int n; //the number of vertex GraphNode
    int adj_mat[50][50]; 
} GraphType;

void dfs_mat(GraphType* g,int v)
{
   int w;
   visited[v] = TRUE; // Show Visits at Vertex v
   print("visit %d ->",v); print visited vertex
   for(w = 0; w<g->n; w++) // search adjacent vertex
      if(g->adj_mat[v][w] && !visited[w])
         dfs_mat(g,w); // restart from vertex w
}

void graph_init(GraphType *g)
{
   int r,c;
   g->n=0;
   for(r=0;r<50;r++)
      for(c=0;c<50;c++)
         g->adj_mat[r][c]=0;
}

void insert_vertex(GraphType *g,int v)
{
   if(((g->n)+1)>50){
      printf("error");
      return;
   }
g->n++;
}

void insert_edge(GraphType *g,int start,int end)
{
   if(start >= g->n || end >= g->n){
      printf("error");
      return;
   }
   g->adj_mat[start][end] = 1;
   g->adj_mat[end][start] = 1;
}

int main(void){
   int i;
   GraphType g;

   graph_init(&g);
   for(i=0;i<4;i++)
      insert_vertex(&g,i);
   insert_edge(&g,1);
   insert_edge(&g,1,0);
   insert_edge(&g,3);
   insert_edge(&g,3,2);
   insert_edge(&g,2,2);
   dfs_mat(&g,0);
}

首先,递归发生的次数与顶点数一样多,因为我们需要检查边。

问题是当程序访问了所有顶点时。即使已经访问了所有顶点,仍会执行其余的迭代操作。我想我必须在迭代语句的操作中包含条件。但我不知道。

请救救我。

解决方法

您可以初始化一个变量,例如 visited_count 并将其设置为节点数。在每次访问操作时递减此变量。每次检查 visited_count 是否等于零,如果是,则跳出循环。检查注释中带有 ////////////////// CHANGE 的行。

#include <stdio.h>
#include <stdbool.h>


typedef struct GraphType 
{ 
    int n; //the number of vertex GraphNode
    int adj_mat[50][50]; 
} GraphType;

static bool visited[50] = {false};
static int visited_count;            ////////////////// CHANGE

void dfs_mat(GraphType* g,int v)
{
   int w;
   visited[v] = true; // Show Visits at Vertex v
   visited_count--;         ////////////////// CHANGE
   printf("=== visit %d ===\n",v); // print visited vertex
   for(w = 0; w<g->n && visited_count; w++) // search adjacent vertex        ////////////////// CHANGE
   {
       if (v != w)         ////////////////// CHANGE
       {
          printf("Processing node: %d,neighbor = %d\n",v,w);      ////////////////// CHANGE - added for debugging
          if(g->adj_mat[v][w] && !visited[w])
             dfs_mat(g,w); // restart from vertex w
       }
   }
}

void graph_init(GraphType *g)
{
   int r,c;
   g->n=0;
   for(r=0;r<50;r++)
      for(c=0;c<50;c++)
         g->adj_mat[r][c]=0;
}

void insert_vertex(GraphType *g,int v)
{
   if(((g->n)+1)>50){
      printf("error");
      return;
   }
g->n++;
}

void insert_edge(GraphType *g,int start,int end)
{
   if(start >= g->n || end >= g->n){
      printf("error");
      return;
   }
   g->adj_mat[start][end] = 1;
   g->adj_mat[end][start] = 1;
}

int main(void){
   int i;
   GraphType g;

   graph_init(&g);
   visited_count = 4;        ////////////////// CHANGE
   for(i=0;i<4;i++)
      insert_vertex(&g,i);
   insert_edge(&g,1);
   insert_edge(&g,1,0);
   insert_edge(&g,3);
   insert_edge(&g,3,2);
   insert_edge(&g,2,2);
   dfs_mat(&g,0);
}