图概念:定点+边(+方向+权值)
图的深度优先(DFS)
深度优先遍历HSP可以打印出图中孤立的所有图–(栈实现的有待学习利用栈实现)
下图的例子针对连通图:A–B–C–(回溯到B)–D–(回溯到B)–E
//深度优先遍历---针对多张孤立的图---(将没有边连接的点也打印出来了)
public void DFSorder(){
//防止出现第一个序号为0的节点是个孤立的节点
for (int i = 0; i < vertexlist.size(); i++) {
if(!isvisited[i]){
DFSoneTime(isvisited,i);
}
//打印过得节点就直接遍历列表结点中的下一个节点,找到图中下一个孤立的节点图
}
}
//深度优先遍历准备工作:针对单张的连接图的情况,针对一张孤立的图
//当遍历完这张孤立的图就会终止
//注意:保证这个刚进来的i是个没有访问过的!!!
public void DFSoneTime(boolean[] isvisited,int i){
//注意保证这个刚进来的i是个没有访问过的
System.out.println(getVertex(i)+"->");
isvisited[i]=true;//这个节点置位访问过的节点
int w=getFisrtNB(i);
//可能完全没找到(没有进入while循环,直接退出方法,类似直接return)
// 找到了本节点的下一个节点--打印输出(即利用递归进行相同的操作)
while(w!=-1){//递归结束的标志&&回溯结束的标志
//递归--1.打印节点w;2.进行纵向遍历:深度遍历w的下一个邻接点
DFSoneTime(isvisited,w);//不能深度递归就会终止
//*****开始回溯到本节点i,继续寻找没有访问过的邻接点,更新w ****************
w=getFisrtNB(i);
//如果寻找到最后,遍历完所有的列表,也没有找到此时w=-1
//需要退出循环,此时我们需要回溯到当前节点的前一个节点,继续寻找没有遍历过的节点
}
}
//寻找当前节点的最近的没有访问过的临节点
public int getFisrtNB(int index){
for (int i = 0; i < vertexlist.size(); i++) {
if(edges[index][i]==1&&!isvisited[i]){
return i;//找到了节点并返回序号
}
}
return -1;//没有这样子的节点
}
图的广度优先(BFS)
此时广度优先遍历的例子输出过程:针对连通图:A–(从A)–B–(从A)–C–(从B)–D–(从B)—E
//针对多个孤立图的广度优先遍历
public void broadOrder(){
for (int i = 0; i < vertexlist.size(); i++) {
if(!isvisited[i]){
broadOneTime(isvisited,i);
}
}
}
//广度优先遍历----对一个节点进行(利用队列:每输出一个元素,就会向队列的尾部加这个元素)
public void broadOneTime(boolean[] isvisited,int i){
int u;//存储队列的头元素
int w;//每次的邻接点
LinkedList queue=new LinkedList();//构造一个队列
//初始化队列的第一个元素
System.out.println(getVertex(i)+"=>");
isvisited[i]=true;
queue.addLast(i);//在队尾添加元素
//横向遍历:队列的头元素,每次前一个u遍历完所有的邻接点就会弹出一个头元素
//访问下一层的可达邻接点
while(!queue.isEmpty()){
u=(Integer) queue.removeFirst();
w=getFisrtNB(u);//访问下一个未访问的邻接点
//访问本层节点的可达邻接点
while(w!=-1){
System.out.println(getVertex(w)+"=>");
isvisited[w]=true;//有输出语句执行过的就是访问了的,那么改变状态
queue.addLast(w);//添加元素至队尾,为了后续的回溯
//仍然寻找当前的这个u节点的下一个未被访问过得邻接点(全部找出并打印输出)
w=getFisrtNB(u);
}
}
}
程序运行结果: