首页 > 编程语言 >《算法》——深度优先搜索

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

时间:2023-08-13 15:32:14浏览次数:32  
标签:优先 return String int private 算法 搜索 顶点 public

定义:

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

相关术语:

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

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

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

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

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

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

思路(类似走迷宫):

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;
    }
}

标签:优先,return,String,int,private,算法,搜索,顶点,public
From: https://blog.51cto.com/u_11906056/7067574

相关文章

  • 《算法》——广度优先搜索与找寻找路径
    单点路径问题在图的处理领域中十分重要,从输入流中读取一个图从从命令行得到一个起点,然后打印从起点到与它连通的每个顶点之间的一条路径。深度优先找路径下面扩展了尝试优先搜索代码,添加一一个实例变量edgeTo[]整型数组来起到Tremaux搜索中绳子的作用,这个数组可以找到从每个与......
  • 分治算法——241. 为运算表达式设计优先级
    分治思路:对于一个算式来说,总是可以根据运算符分为左右两部分算式,接着分别计算结果并合并;每一个结果都是一个数组,包含这个算式的所有可能结果,计算时将左右两部分排列组合;递归的终点是字符串是纯数字(即分到一个算式中只剩下一个数字),直接返回。 比如示例中的2*3-4*5,有下面的......
  • Raft 算法
    论文《InSearchofanUnderstandableConsensusAlgorithm》,发表于2014年相比于Paxos,Raft最大的特性就是易于理解。为了达到这个目标,Raft主要做了两方面的事情:问题分解:把共识算法分为三个子问题,分别是领导者选举(leaderlection)、日志复制(logreplication)、安全性(......
  • 文心一言 VS 讯飞星火 VS chatgpt (75)-- 算法导论7.2 4题
    四、如果用go语言,银行一般会按照交易时间来记录某一账户的交易情况。但是,很多人却喜欢收到的银行对账单是按照支票号码的顺序来排列的。这是因为,人们通常都是按照支票号码的顺序来开出支票的,而商人也通常都是根据支票编号的顺序兑付支票。这一问题是将按交易时间排序的序列转换成按......
  • 文心一言 VS 讯飞星火 VS chatgpt (75)-- 算法导论7.2 4题
    四、如果用go语言,银行一般会按照交易时间来记录某一账户的交易情况。但是,很多人却喜欢收到的银行对账单是按照支票号码的顺序来排列的。这是因为,人们通常都是按照支票号码的顺序来开出支票的,而商人也通常都是根据支票编号的顺序兑付支票。这一问题是将按交易时间排序的序列转换成......
  • 剑指 Offer 54. 二叉搜索树的第k大节点(简单)
    题目:classSolution{public:voidtraversal(TreeNode*cur,vector<int>&result){//本题利用二叉搜索树的排序性质if(cur==nullptr)return;traversal(cur->right,result);//唯一要注意的是题目要求第k大的,所以要把大的放在前面。遍历顺序......
  • 算法刷题:数组题(持续更)
    算法刷题系列:算法刷题:链表题(持续更)力扣链接:删除有序数组中的重复项删除排序链表中的重复元素移除元素移除链表元素两数之和反转字符串反转链表验证回文串验证回文串II目录快速排序原理代码实现快慢指针注意事项异步移动删除有序数组的重复项代码实现对比链表的删......
  • C#快速排序算法
    快速排序实现原理快速排序(QuickSort)是一种常用的排序算法,它基于分治的思想,通过将一个无序的序列分割成两个子序列,并递归地对子序列进行排序,最终完成整个序列的排序。其基本思路如下:选择数组中的一个元素作为基准(pivot)。将数组中小于等于基准的元素放在基准的左边,将大于基......
  • [算法考研笔记]mm算法随笔[成绩划分][回溯0-1][得分][字段和][聪明小偷][股票买卖]
    mm算法随笔学习笔记(回溯算法)回溯<---->递归1.递归的下面就是回溯的过程回溯法是一个纯暴力的搜索、有的时候暴力求解都没有办法,用回溯可以解决。回溯法解决的问题:组合问题如:1234两两组合切割问题如:一个字符串有多少个切割方式,或者切割出来是回文子集问题:1......
  • 前端开发工程师需要掌握哪些算法?
    一个程序员一生中可能会邂逅各种各样的算法,但总有那么几种,是作为一个程序员一定会遇见且大概率需要掌握的算法。作为一名前端开发工程师,今天就通过这个话题和文章来聊聊前端开发工程师需要掌握的算法有哪些呢。......