github.com/searKing/golang/go@v1.2.117/container/traversal/bfs.go (about)

     1  // Copyright 2020 The searKing Author. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  // https://en.wikipedia.org/wiki/Breadth-first_search
     6  package traversal
     7  
     8  // Breadth-first search (BFS)
     9  // 1. Check if the current depth level is empty or null.
    10  // 2. Display the data part of all of the neighbor nodes at the present depth.
    11  // 2. Traverse the next depth level by recursively calling the bfs-order function.
    12  // Implement:
    13  //	procedure BreadthFirstSearch(G,start_v):
    14  //		let Q be a queue
    15  //		label start_v as discovered
    16  //		Q.enqueue(start_v)
    17  //		while Q is not empty
    18  //			v = Q.dequeue()
    19  //			if v is the goal:
    20  //				return v
    21  //			for all edges from v to w in G.adjacentEdges(v) do
    22  //				if w is not labeled as discovered:
    23  //					label w as discovered
    24  //					w.parent = v
    25  //					Q.enqueue(w)
    26  
    27  // TODO template in Go2.0 is expected
    28  // BreadthFirstSearchOrder traversals from node ele by Breadth-first search (BFS)
    29  // ele is a node which may have some interfaces implemented:
    30  // LeftNodes|MiddleNodes|RightNodes
    31  func BreadthFirstSearchOrder(node any, handler Handler) {
    32  	traversal(node, traversalerFunc(bfs), handler)
    33  }
    34  
    35  func bfs(currents []levelNode, handler levelNodeHandler) (goon bool) {
    36  	if len(currents) == 0 {
    37  		return true
    38  	}
    39  	// Step 1: brothers layer
    40  	var nextBrothers []levelNode
    41  	for _, node := range currents {
    42  		if node.visited {
    43  			continue
    44  		}
    45  		if !handler.Handle(node) {
    46  			return false
    47  		}
    48  		// filter brothers
    49  		nextBrothers = append(nextBrothers, node)
    50  	}
    51  
    52  	// Step 2: children layer
    53  	var nextChildren []levelNode
    54  	// filter children
    55  	for _, node := range nextBrothers {
    56  		// Scan node for nodes to include.
    57  		nextChildren = append(nextChildren, node.leftLevelNodes()...)
    58  		nextChildren = append(nextChildren, node.middleLevelNodes()...)
    59  		nextChildren = append(nextChildren, node.rightLevelNodes()...)
    60  	}
    61  
    62  	return bfs(nextChildren, handler)
    63  }