您的位置:首页 > 其它

图--1.广度优先搜索和深度优先搜

2017-03-16 20:16 615 查看
1.图的表示

(1)图G的顶点数有n个,边数e,则无向图满足0<=e<=n(n-1)/2 ; 有向图满足 0<=e<=n(n-1) ;如果边满的话就叫完全图

(2)子图、连通图、强连通图这里不再强调了

(3)图的表示:邻接矩阵和邻接表,这里不再重复了。对于无向图 邻接矩阵第i行中非0的个数和=节点vi的度,有向图就是出度,邻接矩阵占用空间O(n^2)

(4)一个图的邻接矩阵是唯一的,但是邻接表不是,因为邻接表表示中,各边表节点的链接次序取决于建立邻接表的算法以及边的输入次序。邻接表的空间复杂度O(n+e) 

2.广度优先搜索(BFS)

广度优先搜索类似于树的层次遍历,尽可能的横向进行搜索:首先访问节点vi 得到它的所有邻接点w1...wt,然后再依次访问w1...wt,所以采用队列来保存被访问过的节点



A -> C -> D -> F -> B -> G -> E



A -> B -> C -> E -> F -> D -> G(以上两幅图来自网友,表示感谢)

每个顶点最多入队出队一次,遍历图的过程实际就是寻找队列中顶点的邻接点的过程,当图以邻接表存储时时间复杂度为O(v+e),空间复杂度为O(n)队列 。经BFS搜索得到BFS序列,该序列不是唯一的,与出发点和图的存储结构有关。

3.深度优先搜索(DFS)

深度优先搜索尽可能纵深方向进行搜索:先访问节点vi, 然后从 vi 出发开始搜索它的一个邻接点 vj,如果vj没访问过 搜索vj的邻接点。



A->C->B->D->F->G->E



a b c e d f g

当以双链式结构作为图的结构存储时,深度优先的复杂度是O(v+e),

图的深度优先也可以使用栈以非递归的形式实现:初始节点入栈,当栈不空时,重复处理栈顶元素,若未访问,访问并设置访问标识,将其未访问的邻接点入栈

/**
*
*/
package graph_search;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;
import java.util.Stack;

/**
* 邻接表表示的无向图
* @author LingLee
*
*/
class GraphNode{//节点类
public List<GraphEdge> edgeList=null;
private String label="";
public GraphNode(String label){
this.label=label;
if(edgeList==null){
edgeList=new ArrayList();
}
}

//给当前节点添加一条边
public void addEdgeList(GraphEdge edge){
edgeList.add(edge);
}

public String getLabel(){
return label;
}
}
class GraphEdge{//边类
private GraphNode left;//左边的点
4000

private GraphNode right;

public GraphEdge(GraphNode left,GraphNode right){
this.left=left;
this.right=right;
}
public GraphNode getLeft(){
return left;
}
public GraphNode getRight(){
return right;
}
}
public class ListUDG {//图结构
private List<GraphNode> nodes=null;//图中点集合

public void initGraph(int n){
if(nodes==null){
nodes=new ArrayList();
}
GraphNode node=null;
for(int i=0;i<n;i++){
node=new GraphNode(String.valueOf(i));
nodes.add(node);
}
}
public void initGraph(int n,boolean b){
initGraph(n);
GraphEdge edge01 = new GraphEdge(nodes.get(0), nodes.get(1));
GraphEdge edge02 = new GraphEdge(nodes.get(0), nodes.get(2));
GraphEdge edge13 = new GraphEdge(nodes.get(1), nodes.get(3));
GraphEdge edge14 = new GraphEdge(nodes.get(1), nodes.get(4));
GraphEdge edge25 = new GraphEdge(nodes.get(2), nodes.get(5));
GraphEdge edge26 = new GraphEdge(nodes.get(2), nodes.get(6));
GraphEdge edge37 = new GraphEdge(nodes.get(3), nodes.get(7));
GraphEdge edge47 = new GraphEdge(nodes.get(4), nodes.get(7));
GraphEdge edge56 = new GraphEdge(nodes.get(5), nodes.get(6));

nodes.get(0).addEdgeList(edge01);
nodes.get(0).addEdgeList(edge02);
nodes.get(1).addEdgeList(edge13);
nodes.get(1).addEdgeList(edge14);
nodes.get(2).addEdgeList(edge25);
nodes.get(2).addEdgeList(edge26);
nodes.get(3).addEdgeList(edge37);
nodes.get(4).addEdgeList(edge47);
nodes.get(5).addEdgeList(edge56);
}
public void initGraph(){
initGraph(8,false);
}

//广度优先
public void BFS(GraphNode node){
List<GraphNode> visited=new ArrayList();//已访问过的节点
Queue<GraphNode> q=new LinkedList();//d队列存储依次要遍历的元素
q.offer(node);//根节点加入队列
while(!q.isEmpty()){
GraphNode curNode=q.poll();//队首元素 也是目前该访问的节点
if(!visited.contains(curNode)){//没有访问过
visited.add(curNode);
System.out.print(curNode.getLabel()+"->");
for(int i=0;i<curNode.edgeList.size();i++){//访问节点curnode的所有邻接点
q.offer(curNode.edgeList.get(i).getRight());//将邻接点加入队列中
}
}
}
}

//深度优先
public void DFS(GraphNode node,List<GraphNode> visited){//递归法
if(visited.contains(node)){
return;
}
visited.add(node);//
System.out.print(node.getLabel()+"->");
for(int i=0;i<node.edgeList.size();i++){
DFS(node.edgeList.get(i).getRight(),visited);//对节点node的邻接点递归深度搜索
}
}

//深度优先非递归方法 借助栈
public void DFS2(GraphNode node){
List<GraphNode> visited=new ArrayList();
LinkedList s=new LinkedList();
s.push(node);
while(!s.isEmpty()){
GraphNode curNode=(GraphNode)s.pop();
if(!visited.contains(curNode)){
visited.add(curNode);
System.out.print(curNode.getLabel()+"->");
for(int i=0;i<curNode.edgeList.size();i++){
GraphNode next=curNode.edgeList.get(i).getRight();
//System.out.println("节点:"+i);
if(!visited.contains(next)){//如果邻接点没访问过 则压入栈
s.push(next);
//System.out.println("节点:"+i+"入栈");
}
}
}
}
}

public static void main(String[] args){
ListUDG udg=new ListUDG();
udg.initGraph();
GraphNode node=new GraphNode(String.valueOf(0));
System.out.println("广度优先搜索:");
udg.BFS(udg.nodes.get(0));
System.out.println();
System.out.println("递归深度优先搜索:");
List<GraphNode> visited=new ArrayList();
udg.DFS(udg.nodes.get(0), visited);
System.out.println();
System.out.println("非递归深度优先搜索:");
udg.DFS2(udg.nodes.get(0));
}
}



 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: