深度优先搜索:检查电路

时间:2015-10-12 00:32:41

标签: java matrix graph depth-first-search

我有这个代码,我正在寻找树内的电路。我无法弄清楚该怎么做。我想知道我是否有不好的实施。绕过变量是非常混乱的。如何检查此输入是否包含电路?

package circuitfinder;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

/**
 *
 * @author
 */
class TheStack
   {
   private final int HEIGHT = 20;
   private int[] st;
   private int top;

   public TheStack()           
      {
      st = new int[HEIGHT];    
      top = -1;
      }

   public void push(int j)   
      { st[++top] = j; }

   public int pop()          
      { return st[top--]; }

   public int peek()         
      { return st[top]; }

   public boolean isEmpty()  
      { return (top == -1); }

   }  
class Nodes
   {
   public char label;        
   public boolean wasVisited;

   public Nodes(char lab)   
      {
      label = lab;
      wasVisited = false;
      }

   }  
class TheGraph
   {
   private final int MAX_VERTS = 20;
   private Nodes[] nodeList; 
   private int[][] adjacencym;      
   private int numberOfVertices;          
   private TheStack theStack;
   public boolean circuit;
   ArrayList<Integer> searcher = new ArrayList<Integer>();

   public TheGraph()               
      {
       circuit = false;

      nodeList = new Nodes[MAX_VERTS];

      adjacencym = new int[MAX_VERTS][MAX_VERTS];
      numberOfVertices = 0;
      for(int y=0; y<MAX_VERTS; y++)      
         for(int x=0; x<MAX_VERTS; x++)   
            adjacencym[x][y] = 0;
      theStack = new TheStack();
      }  // end constructor

   public void addNode(char lab)
      {
      nodeList[numberOfVertices++] = new Nodes(lab);
      }

   public void addEdge(int start, int end)
      {
      adjacencym[start][end] = 1;
      adjacencym[end][start] = 1;
      }

   public void dephthSearch() 
      {                                
      nodeList[0].wasVisited = true;  

      theStack.push(0);                

      while( !theStack.isEmpty() )     
         {


         int v = getAdjUnvisitedVertex( theStack.peek());

         if(v == -1){ 

            theStack.pop();
         }
         else                          
            {

            nodeList[v].wasVisited = true;  

            theStack.push(v);                
            }


         }  


      for(int j=0; j<numberOfVertices; j++)          
         nodeList[j].wasVisited = false;
      } 


   public int getAdjUnvisitedVertex(int v)
      {



      for(int j=0; j<numberOfVertices; j++){


         if(adjacencym[v][j]==0 && nodeList[j].wasVisited==false){


            return j;
         }}

      return -1;
      }  


   }  
class CircuitFinder
   {
   public static void main(String[] args)
      {
      TheGraph graphs = new TheGraph();
      graphs.addNode('1');   
      graphs.addNode('2');    
      graphs.addNode('3');    
      graphs.addNode('4');    


      graphs.addEdge(0, 1);    
      graphs.addEdge(1, 2);     
      graphs.addEdge(0, 3);     
      graphs.addEdge(3, 4);     
      graphs.addEdge(4, 0);

      graphs.dephthSearch();             
      System.out.println("Graph has  Circuit: "+graphs.circuit);






      }  
   }  

2 个答案:

答案 0 :(得分:0)

您可以保留一个包含您已访问过的节点的布尔数组。当您在depthSearch中处理节点并遇到您已访问过的节点时,您将找到一个循环。
或者你可以在你的节点类中保留一个标志来实现同样的目标。

基本的想法是,如果你遇到一个已被访问过的节点,你就会陷入循环,因为你遇到了一个后沿。
这个链接会更清楚。 http://www.geeksforgeeks.org/detect-cycle-in-a-graph/这是一个图表,但请记住,图形和树之间的主要区别在于前者可以包含循环,您将能够弄清楚它。

答案 1 :(得分:0)

你没有在你的代码中操纵电路,而这正是你在主方法中寻找的。所以我的想法是:

<java>
   public void dephthSearch() 
  {                                
  nodeList[0].wasVisited = true;  

  theStack.push(0);                

  while( !theStack.isEmpty() )     
     {


     int v = getAdjUnvisitedVertex( theStack.peek());

     if(nodeList[v].wasVisited) {  //If node is visited again you set circuit = true
        circuit = true; // Since finding cycle is your job,you can break from this while loop as soon as you hit circuit = true.
        break;
      }  
     if(v == -1){ 

        theStack.pop();
     }
     else                          
        {

        nodeList[v].wasVisited = true;  

        theStack.push(v);                
        }


     }  


  for(int j=0; j<numberOfVertices; j++)          
     nodeList[j].wasVisited = false;
  }
}</java>

现在你的getAdjUnvisitedVertex.Assuming你存储1的边缘,你必须改变以下代码

<java>for(int j=0; j<numberOfVertices; j++){


     if(adjacencym[v][j]==0 && nodeList[j].wasVisited==false){


        return j;
     }</java>

to

<java>
   for(int j=0; j<numberOfVertices; j++){


     if(adjacencym[v][j]==1){ //If there exists an edge you return j.The later half is removed because if nodeList[j] was true then it means there exists a cycle which you check in depthSearch();


        return j;
     }</java>