回顾;上一节课中,我们学习了图这种比较复杂的非线性结构的基础,以及表示方法,以及他在社交网络中的应用,其中这种数据结构存储数据的方式有领连接矩阵存储和领连接链表存储,分别采用空间换时间和时间换空间的思想,其中采用领连接矩阵存储具有更广的应用,只是他的底层以矩阵进行描述,可以进行多种矩阵的计算,达到我们的业务目的.
1>提出问题,什么是搜索算法
要想搞清楚这个问题,我还是先讲讲大家常用的qq是如何实现好友进行推荐的,比如说,A添加了B,B添加了C,C添加了D,其中B,C,D分别是A的一度好友,二度好友,三度好友,qq软件就是通过这种方式现实呢qq可能认识的好友进行推荐.
所谓针对图的搜索算法很直观的理解,从图找某一点出发,找到我们需要说的顶点的路径,这就是图的搜索算法,比较有名的是图的广度优先算法,和深度优先算法,当然还有其他算法,今天我们重点讲一下图的广度优先算法
2>广度优先算法(简称BFS)的原理:即就是先寻找其实起点最近的点,然后次近的,以此往外搜索,我们来看一下下面的一张图的搜索原理
a>在初始状态下,从顶点1开始,其中队列放入1即queue = {1};
b>访问1的临近顶点,1出队,且变黑,2,3入队,此时queue={2,3}
c>访问2的临近顶点,2出队,且变黑,4入队,此时queue={3,4}
d>访问3的临近顶点,3出队,且变黑,此时queue={4}
e>访问4的临近顶点,4出队,且变黑,此时queue={}
f:>节点5对于节点1来说不可达
3>广度优先搜索算法的实现代码
import java.util.LinkedList;
import java.util.Queue;
public class Graph1 {
/*
采用领连接链表法来表示一个图
*/
private int v;//图中顶点的个数
private LinkedList<Integer> list[];
public Graph1(int n){
for(int i=1;i<= n;i++){
list[i] = new LinkedList<Integer>();//有多少个顶点就有多少个链表
}
}
public void addGraph(int s,int t){//在无向图中需要存储2条边
list[s].add(t);
list[t].add(s);
}
//广度优先算法实现代码
public void bfs(int s,int t) {
if (s == t) return;
boolean[] visited = new boolean[v]; //该visited表示已经被访问的元素
visited[s] = true;//起初第一个起始节点被标记为true;
Queue<Integer> queue = new LinkedList<>();
queue.add(s);//该队列存储的是已经被访问,且相邻顶点还没有被访问的顶点
int[] prew = new int[v];
for (int i=1;i<=v;++i){
prew[i] = -1;
}
while (queue.size() != 0){
int w = queue.poll();//从队列尾部取出元素
for(int i=0;i<=list[w].size();i++){
int q = list[w].get(i);
if(!visited[q]);
prew[q] = w;
if(q ==t){
System.out.println(prew + "=" +s + "="+t);
return;
}
visited[q] = true;
queue.add(q);
}
}
}
private void printt(int[] prew,int s,int t){
if(prew[t] != -1 && t != s){
System.out.println(prew + "=" + s + "=" + prew[t]);
}
}
}
4>广度优先算法的复杂度
在最坏的情况下,我们所需要寻找的距离最远,每个顶点都要访问一遍,每一条边都要走,这是的时间复杂度为O(X+S)。X表示顶点的个数,E表示边的个数,,即可是表示为O(S);
广度优先算法所有数据的存储都不会超过顶点的个数,所以空间复杂度为O(X)