树的广度优先与深度优先遍历

194 阅读2分钟

BFS

树的广度优先遍历(Breadth-First Search, BFS)是一种用于遍历或搜索树数据结构的算法。 在广度优先遍历中,从根节点开始,按层级顺序逐层访问节点,先访问当前层级的所有节点,然后再访问下一层级的节点。

js代码实现

function bfs(root) {
    let queue = [root];
    while (queue.length) {
        let node = queue.shift();
        console.log(node.val);
        if (node.children) {
            node.children.forEach(child => {
                queue.push(child);
            })
        }
    }
}

const tree = {
    val: 'a',
    children: [
        {
            val: 'b',
            children: [
                {
                    val: 'd'
                },
                {
                    val: 'e'
                }
            ]
        },
        {
            val: 'c',
            children: [
                {
                    val: 'f'
                },
                {
                    val: 'g'
                }
            ]
        }
    ]
}

bfs(tree); // a b c d e f g

go代码实现

package main

import "fmt"

type Node struct {
	Val   string
	Child []*Node
}

func newNode(val string) *Node {
	return &Node{
		Val:   val,
		Child: make([]*Node, 0),
	}
}

func (n *Node) AddChild(children ...*Node) {
	n.Child = append(n.Child, children...)
}

func Bfs(root *Node) {
	queue := make([]*Node, 0)
	queue = append(queue, root)
	for len(queue) > 0 {
		node := queue[0]
		queue = queue[1:]
		fmt.Println(node.Val)
		if len(node.Child) > 0 {
			for _, child := range node.Child {
				queue = append(queue, child)
			}
		}
	}
}

func main() {
	a := newNode("a")
	b := newNode("b")
	c := newNode("c")
	d := newNode("d")
	e := newNode("e")
	f := newNode("f")
	g := newNode("g")
	a.AddChild(b, c)
	b.AddChild(d, e)
	c.AddChild(f, g)

	Bfs(a) // a b c d e f g
}

DFS

树的深度优先遍历(Depth-First Search, DFS)是一种用于遍历或搜索树数据结构的算法。 在深度优先遍历中,从根节点开始,先访问当前节点,然后递归地访问其子节点,直到到达叶子节点。 然后回溯到上一级节点,继续访问其未被访问的子节点。

js代码实现

const tree = {
    val: 'a',
    children: [
        {
            val: 'b',
            children: [
                {
                    val: 'd'
                },
                {
                    val: 'e'
                }
            ]
        },
        {
            val: 'c',
            children: [
                {
                    val: 'f'
                },
                {
                    val: 'g'
                }
            ]
        }
    ]
}

// 递归实现
function dfs(root) {
    console.log(root.val);
    if (root.children) {
        root.children.forEach(child => {
            dfs(child);
        })
    }
}

// 栈实现
function dfsStack(root) {
    let stack = [root];
    while (stack.length > 0) {
        let node = stack.pop();
        console.log(node.val);
        if (node.children) {
            const children = node.children;
            // 为了保证和递归的访问顺序一致,反向遍历
            for (let i = children.length - 1; i >= 0; i--) {
                stack.push(children[i]);
            }
        }
    }
}

go代码实现

package main

import "fmt"

type Node struct {
	Val   string
	Child []*Node
}

func newNode(val string) *Node {
	return &Node{
		Val:   val,
		Child: make([]*Node, 0),
	}
}

func (n *Node) AddChild(children ...*Node) {
	n.Child = append(n.Child, children...)
}

func Dfs(root *Node) {
	fmt.Println(root.Val)
	if len(root.Child) > 0 {
		for _, child := range root.Child {
			Dfs(child)
		}
	}
}

func DfsStack(root *Node) {
	stack := make([]*Node, 0)
	stack = append(stack, root)
	for len(stack) > 0 {
		node := stack[len(stack)-1]
		stack = stack[:len(stack)-1]
		fmt.Println(node.Val)
		if len(node.Child) > 0 {
			for i := len(node.Child) - 1; i >= 0; i-- {
				stack = append(stack, node.Child[i])
			}
		}
	}
}

func main() {
	a := newNode("a")
	b := newNode("b")
	c := newNode("c")
	d := newNode("d")
	e := newNode("e")
	f := newNode("f")
	g := newNode("g")
	a.AddChild(b, c)
	b.AddChild(d, e)
	c.AddChild(f, g)
	
	Dfs(a) // a b d e c f g

	fmt.Println("--------------")
	
	DfsStack(a) // a b d e c f g
}