github.com/searKing/golang/go@v1.2.117/container/traversal/dfs.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/Depth-first_search
     6  package traversal
     7  
     8  // Depth-first search (DFS)
     9  // 1. Check if the current node is empty or null.
    10  // 2. Display the data part of the root (or current node).
    11  // 3. Traverse the middle subtree by recursively calling the dfs-order function.
    12  // 4. Traverse the left subtree by recursively calling the dfs-order function.
    13  // 5. Traverse the right subtree by recursively calling the dfs-order function.
    14  // Implement:
    15  //	procedure DFS(G,v):
    16  //		label v as discovered
    17  //		for all directed edges from v to w that are in G.adjacentEdges(v) do
    18  //			if vertex w is not labeled as discovered then
    19  //				recursively call DFS(G,w)
    20  
    21  // TODO template in Go2.0 is expected
    22  // DepthFirstSearchOrder traversals from node ele by Depth-first search (DFS)
    23  // ele is a node which may have some interfaces implemented:
    24  // LeftNodes|MiddleNodes|RightNodes
    25  func DepthFirstSearchOrder(node any, handler Handler) {
    26  	traversal(node, traversalerFunc(dfs), handler)
    27  }
    28  
    29  func dfs(currents []levelNode, handler levelNodeHandler) (goon bool) {
    30  	if len(currents) == 0 {
    31  		return true
    32  	}
    33  	// Step 1: brothers
    34  	for _, node := range currents {
    35  		if node.visited {
    36  			continue
    37  		}
    38  		if !handler.Handle(node) {
    39  			return false
    40  		}
    41  		if !dfs(node.middleLevelNodes(), handler) {
    42  			return false
    43  		}
    44  		if !dfs(node.leftLevelNodes(), handler) {
    45  			return false
    46  		}
    47  		if !dfs(node.rightLevelNodes(), handler) {
    48  			return false
    49  		}
    50  	}
    51  	return true
    52  }