图形的遍历方法之先广后深法

        上篇博文介绍了采用先深后广的方式遍历图形,本文介绍采用先广后深的方式来遍历图形。所谓先广后深法,就是优先遍历列表中当前访问链接的所有节点,再访问其他链接的节点。与先深后广法访问的顺序采用了堆栈结构不同,先广后深法采用的是队列的结构。也即,将当前访问节点相连的所有节点放入队列,访问队列头,再将与当前访问的节点相连且未被访问过的节点放入队列,循环执行此步骤,直至队列为空。依然以以下两个图形为例:

    

对于左图,若以A为起点,则有:

step 1:选取A,将未被访问的相邻节点B,D,E送入队列,同时标记B,D,E为已被访问

BDE

step 2:选取B,将未被访问的相邻节点C送入队列,同时标记C为已被访问
DEC
step 3:选取D,发现D已经没有未被访问的相邻节点,因此不需要采取任何操作
EC
step 4:选取E,同样E已经没有未被访问的相邻节点,因此不需要采取任何操作
C
step 5:选取“C,此时队列以已空,图形遍历完。

具体实现代码如下:

package javaTest;

import java.util.Arrays;

public class BFS {
	static int queueSize = 10;
	static int[] queue = new int[queueSize];//定义队列
	static int queueHead = -1;//队列头指针
	static int queueTail = -1;//队列尾指针
	public static void queueReset(){//重置队列
		Arrays.fill(queue, 0);
		queueHead = -1;
		queueTail = -1;
	}
	public static void queueAdd(int value){//往队列添加数据
		queueTail++;
		queue[queueTail] = value;
	}
	public static int queueGet(){//从队列中取数据
		if(queueHead==queueTail){
			System.out.println("The queue is empty");
			return -1;
		}
		queueHead++;
		return(queue[queueHead]);
	}
	public static void bfs(int x, GraphList list){
		System.out.print("["+x+"] ");
		list.state[x] = 1;
		Node tempNode = list.links[x].head;
		while(tempNode!=null){//将与当前访问节点相连的节点依次放入队列
			if(list.state[tempNode.value]==0){
				queueAdd(tempNode.value);
				list.state[tempNode.value] = 1;
			}			
			tempNode = tempNode.nextNode;
		}
		if(queueHead!=queueTail){//如果队列不为空,则继续从队列取数据和放入数据的操作
			bfs(queueGet(), list);
		}
	}
	
	public static void main(String[] args){
		int[][] data1 = {  
	            {1,2},{2,1},{1,4},{4,1},  
	            {1,5},{5,1},{2,3},{3,2},  
	            {2,4},{4,2},{3,4},{4,3},  
	            {3,5},{5,3}
		};
		int[][] data2 = {  
                {1,2},{1,5},{2,4},{3,2},  
                {3,4},{4,1},{5,3}  
        };  
		System.out.println("Breadth-first search of the undirected graph:");
		GraphList list1 = new GraphList(data1);
        bfs(1,list1);
        System.out.println();
        queueReset();
        System.out.println("Breadth-first search of the directed graph:");
        GraphList list2 = new GraphList(data2);
        bfs(1,list2);
	}
}
class GraphList {//列表类,每一个列表有n个链接类构成,n为节点的个数  
	int nodeNumber;
	int[] state;
	GraphLink[] links;
    public GraphList(int[][] data){  
        nodeNumber = 0;  
        for(int i=0; i<data.length; i++){//判断初始数据中提供的节点的个数  
            for(int j=0; j<data[i].length; j++){  
                if(nodeNumber<data[i][j]){  
                    nodeNumber = data[i][j];  
                }  
            }  
        }
        state = new int[nodeNumber+1];
        links = new GraphLink[nodeNumber+1];  
        for(int i=1; i<links.length; i++){  
        	state[i] = 0;
            links[i] = new GraphLink();  
            for(int j=0; j<data.length; j++){  
                if(data[j][0]==i){  
                    links[i].insert(data[j][1]);  
                }
            }        
        }  
    }  
          
          
}  
  
class Node{//节点类  
    int value;  
    Node nextNode;  
    public Node(int value){  
        this.value = value;  
        nextNode = null;  
    }  
}  
  
class GraphLink{//链接类  
    Node head;  
    Node tail;  
    public boolean isEmpty(){  
        return head==null;    
    }  
    public void print(){//打印链接  
        Node tempNode = head;  
        while(tempNode != null){  
            System.out.print("["+tempNode.value+"] ");  
            tempNode = tempNode.nextNode;  
        }  
    }  
    public void insert(int value){//往链接中插入节点  
        Node tempNode = new Node(value);  
        if(this.isEmpty()){  
            head = tempNode;  
            tail = tempNode;  
        }  
        else{  
            tail.nextNode = tempNode;  
            tail = tempNode;  
        }  
    }  
}  
程序输出:

Breadth-first search of the undirected graph:
[1] [2] [4] [5] [3] 
Breadth-first search of the directed graph:
[1] [2] [5] [4] [3] 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值