算法学习记录-图

  我,算法渣渣,打钱。

  停了好长一段时间算法学习了,上个学期学完数据结构以后,学的时候还是清晰的,写也会写一点,但是现在,连图的基本构造我都忘得一干二净了。今天又开始看视频,算法的学习是打算视频讲一个点,我听完之后找一些题目做来加固训练这样子。今天看的是关于图的基本构造,以及深度和广度优先搜索算法和拓扑排序。

  这是我根据视频写(按照记忆记下来)的算法,我觉得还是要记录一下,才能加深我的印象。

   1.首先是图的基本结构,点,边。

ackage graph;

import java.util.ArrayList;

public class Node {
	public int value;//权值
	public int in;//入度
	public int out;//出度
	public ArrayList<Node> nodes;//点集
	public ArrayList<Edge> edges;//边集
	
	public Node(){
		this.value = 0;
		this.in = 0;
		this.out = 0;
		this.nodes = new ArrayList<>();
		this.edges = new ArrayList<>();
	}
	

}
public class Edge {//边
	public Node from;//起点
	public Node to;//终点
	public int weight;//权值
	
	public Edge(Node from,Node to,int weight){
		this.from = from;
		this.to = to;
		this.weight = weight;
	}
	
	public Edge(){
		this.from = new Node();
		this.to = new Node();
		this.weight = 0;
	}

}


public class Graph {//图
	public HashMap<Integer, Node> nodes;//图的点集
	public HashSet<Edge> edges;//图的边集
	
	public Graph(){
		this.nodes = new HashMap<>();
		this.edges = new HashSet<>();
	}

}


以上是图的全部结构,下面是广度和深度优先遍历算法

广度优先遍历:①从图中v0点开始遍历 ②依次遍历与v0相邻的未访问的节点 ③重复步骤2,直到所有节点被访问

public class BFS {
	
	public void bfs(graph.Node node){
		if(node == null){
			return;
		}
		Queue<Node> queue = new LinkedList<>();
		HashSet<Node> map = new HashSet<>();//此map用来记录已经访问过的节点,避免重复访问
//		for(graph.Node node2 : node.nodes){
//			if(!map.contains(node2)){
//				map.add(node2);
//				queue.add(node2);
//				System.out.println(node2.value);
//			}
//			
		queue.add(node);
		map.add(node);
		while(!queue.isEmpty()){
			Node get = queue.poll();
			System.out.println(get.value);
			for(Node node2 : get.nodes){
				if(!map.contains(node2)){
					map.add(node2);
					queue.add(node2);
					}
				}
			}
		}		
	}


深度优先遍历:①以v0节点开始遍历 ②从v0中选取一个与其相连的点v1进行访问,并从v1中选取一个与v1相连的点进行访问,一直下去直到此路径没有节点可以访问,再退回到v0选取另外与其相连的点。③重复②步骤,直到所有的点都被访问。


public class DFS {
	
	public void dfs(Node node){
		if(node == null){
			return;
		}
		Stack<Node> stack = new Stack<>();
		HashSet<Node> set = new HashSet<>();//同样是为了标识已访问的节点,防止重复访问
		stack.add(node);
		set.add(node);
		while(!stack.isEmpty()){
			Node cur = stack.pop();
			for(Node next : cur.nodes){
				if(!set.contains(next)){
					stack.push(cur);//重复插入,确保这个节点的其他岔路可以走,直到没有岔路才拿出来
					stack.push(next);
					set.add(next);
					System.out.println(next.value);
					break;
				}
			}
		}
	}

}


拓扑排序:适用于有向无环图

	public List<Node> topoSort(Graph graph){
		//1.把所有入度点情况存到map
		//2.把所有入度点为0的node存到queue
		//3.从入度点为0的node出发,依次把点放入result。
		//4.当node被选取,则与其相连的点的入度都要-1,此时继续重复步骤2,3,4。
		Map<Node,Integer> inMap = new HashMap<Node, Integer>();
		Queue<Node> zeroInNode = new LinkedList<Node>();
		List<Node> result = new ArrayList<Node>();
		for(Node node : graph.nodes.values()){//这里要取values(),因为这个nodes()是一个hashMap,我们要取得是它里面存放的value,即node
			inMap.put(node, node.in);
			if(node.in == 0){
				zeroInNode.add(node);
			}
		}
		
		while(!zeroInNode.isEmpty()){
			Node cur = zeroInNode.poll();
			result.add(cur);
			for(Node next : cur.nodes){
				inMap.put(next,inMap.get(next)-1);//注意这里不是next.in-1,不可以改变next
				if(inMap.get(next) == 0){
					zeroInNode.add(next);
				}
			}
		}
		return result;
		
	}

}


猜你喜欢

转载自blog.csdn.net/lianup/article/details/79771374
今日推荐