0
点赞
收藏
分享

微信扫一扫

《算法》——深度优先搜索

林塬 2023-08-13 阅读 78
javaspring

定义:

图是由一组顶点和一组能够将两个顶点相连的边组成的

相关术语:

  • 当两个顶点通过一条边相连时,我们称这两个顶点是相邻的,并称这条边依附于这两个顶点
  • 某个顶点的度数即为依附于它的边的总数。
  • 子图是由一幅图的所有边的一个子集(以及它们所依附的所有的顶点)组成的图。

在图中,路径是由边顺序连接的一系列顶点。

简单路径是一条没有重复顶点的路径。

是一条至少含有一条边且起点和终点相同的路径。

简单环是一条(除了起点和终点必须相同之外)不含有重复顶点和边的环。

路径或者环的长度为其中所包含的边数。

思路(类似走迷宫):

1、选择一条没有标记过的通道,在你走过的路上铺一条绳子

2、标记所有你第一次路过的路口和通道

3、如果来到的路口被标记过了,就回退到上个路口

4、回退的路口已没有可走的通道时继续回退

相关数据类型

package algorithm.graph;

import java.util.Iterator;

/**
 * 描述:
 * Created by zjw on 2021/7/25 12:29
 */
public class Bag<Item> implements Iterable<Item> {
	private Node first;//持有空引用
    private class Node{
    	Item item;
    	Node next;
    }
    public void add(Item item){
    	Node oldNode = new Node();
        first.item = item;
        first.next = oldNode; //在头部添加节点
    }
	@Override
	public Iterator<Item> iterator() { 
		return new ListIterator();
	}
    private class ListIterator<Item> implements Iterator<Item>{ 
    	//保留指向链表的节点的引用first
		private Node curNode = first;
    	@Override
		public boolean hasNext() {  
			return curNode != null;
		}

		@Override
		public Item next() { 
			Item item = (Item) curNode.item;
			curNode = curNode.next;
			return item;
		}
    	
    }
	public static void main(String[] args) {
		  Bag<Integer> bag = new Bag<Integer>();
		  for(int i = 0; i < 10; i++)
		      bag.add(i);
		  for(Integer i : bag)
			      System.out.print(i+" ");
	}

}
--------------------------------------
public class In  implements Iterable<Integer>{
    private String infile;    //图文件输入
    private Integer[] IntegerArr;    //使用数组存储单个数字顶点
    private String[] stringArr; //使用字符数组存储
    private String[] lineArr; //使用数组存储每行顶点 
    private int index;  
    private int sindex;
    private int line;
    public In(String infile) throws IOException{
    	this.infile = infile;
    	this.index = 0;
    	this.sindex = 0;
    	BufferedReader bf = new BufferedReader(new FileReader(infile));   
    	String textLine;  
    	StringBuffer sb = new StringBuffer();
    	StringBuffer sbLine = new StringBuffer();
		while((textLine=bf.readLine()) != null){
			//逐个字符读取
			sb.append(textLine.replaceAll(" +", ",") + ","); //去除每行数字中所有空格并以,切分
			//sb.append(","); 
			//逐行读取
			sbLine.append(textLine.replaceAll("\\s", " ") + "\n"); //去除每行数字中所有空格并以tab换行
		}  
		//System.out.println(sb.toString());
		String[]  strVal = sb.toString().split(",");   
		Integer[] numVal = new Integer[strVal.length]; 
		for (int i = 0; i < strVal.length; i++) 
			if(!containsDouble(sb.toString()) && !containsString(sb.toString())) 
				numVal[i] = Integer.parseInt(strVal[i]);
			
		this.IntegerArr = numVal;
		
		String[] strLineVal = sbLine.toString().split("\n"); //逐行存储字符串 
		
		this.stringArr = strVal; //顶点字符串的数组存储
		this.lineArr = strLineVal;
		bf.close();
    }
    //该方法只针对不含权重的图文件读取;
    public Integer[] getArr(){
    	return this.IntegerArr;
    }
    //逐个读取数字顶点(该方法只针对不含权重的图文件读取;)
    public int readInt(){ 
    	if(index < IntegerArr.length && index > -1)
    		return IntegerArr[index++];
    	return -1;
    } 
    public boolean hasNextInt(){//当前是否还有可取值
    	if(index < IntegerArr.length && index > -1)
		    return true; 
    	return false;
    } 
    
    public String[] getStr(){
    	return this.stringArr;
    }
    //逐个读取字符顶点
    public String readStr(){  
    	if(sindex < stringArr.length && sindex > -1)
    		return stringArr[sindex++];
    	return null;
    } 
    public boolean hasNextStr(){//当前是否还有可取值
    	if(sindex < stringArr.length && sindex > -1)
		    return true; 
    	return false;
    }  
    //返回存储每行顶点的数组
    public String[] getLineArr(){
    	return this.lineArr;
    }
    
    public boolean hasNextLine(){
    	if(line < lineArr.length) return true;
    	return false;
    }
    //读取行字符串
    public String readLine() {
    	if(line < lineArr.length)
    		return lineArr[line++];
    	return null;
    }
  //使In类实现迭代器接口
    @Override
	public Iterator<Integer> iterator() { 
		return new Iterator<Integer>(){ 
			int indexIt = 2;  //去除前两个数字,即顶点数和边数
			@Override
			public boolean hasNext() { //当前是否还有可取值
				if(indexIt < IntegerArr.length && indexIt > 1)
				    return true;
				return false;
			} 
			@Override
			public Integer next() { 
				if(indexIt < IntegerArr.length && indexIt > -1)
				   return IntegerArr[indexIt++];
				return -1;
			} 
		};
    }	
    
    public static boolean containsInteger(String str){
    	boolean isDigit = false;                    
        //String str = "aaasss8fff";                
        for(int i = 0 ; i < str.length(); i++){     
            if(Character.isDigit(str.charAt(i))){
            	isDigit = true;  
            	break;
            }    
        } 
       return isDigit;
    }
    public static boolean containsDouble(String str){
    	boolean isDouble = false;                    
        //String str = "abc2.0f";        
    	for(int i = 0 ; i < str.length(); i++){           
            if(str.contains(".")){
            	isDouble = true; 
            	break;
            }   
        }      
        return isDouble;
    }
    public static boolean containsString(String str){ 
        boolean isLetter = false;                     
        //String str = "aaasss8fff";  				  
        for(int i = 0 ; i < str.length(); i++){           
            if(Character.isLetter(str.charAt(i))){
            	isLetter = true; 
            	break;
            }   
        } 
       return isLetter;
    }  

深度优先搜索

定义

1、递归遍历所有顶点

2、将它标记为已访问

3、递归地访问它的所有没有被标记过的邻居顶点

package algorithm.graph;

/**
 * 描述:深度优先搜索
 *
 * Created by zjw on 2021/7/25 12:38
 */
public class DepthFirstSearch {
    private boolean[] marked;
    private int count;

    public DepthFirstSearch(Graph G, int s) {
        marked = new boolean[G.V()];
        dfs(G, s);
    }

    private void dfs(Graph G, int v) {
        marked[v] = true;
        count++;
        for (Integer w : G.adj(v)) {
            if (!marked[w]) dfs(G, w);
        }
    }

    public boolean marked(int w) {
        return marked[w];
    }
    public int count() {
        return count;
    }
}
举报

相关推荐

0 条评论