Sobes.tech
Middle

Jak funguje hledání v stromu?

sobes.tech AI

Odpověď od AI

Hledání v stromu závisí na jeho struktuře a cíli hledání.

Hlavní způsoby hledání:

  1. Hledání do hloubky (DFS - Depth-First Search): Jde maximálně do hloubky jednoho větve, než přejde k sousední. Implementuje se pomocí zásobníku (explicitně nebo rekurzí).

    • Předběžný průchod (Pre-order): Navštívit kořen, poté levý podstrom, poté pravý podstrom.
    • In-order průchod: Navštívit levý podstrom, pak kořen, pak pravý podstrom. Používá se u binárních vyhledávacích stromů pro získání seřazeného seznamu prvků.
    • Post-order: Navštívit levý podstrom, pravý podstrom, pak kořen.
  2. Hledání do šířky (BFS - Breadth-First Search): Prozkoumá všechny sousedy na jedné úrovni před přechodem na další. Implementuje se pomocí fronty.

Příklad DFS (In-order) pro binární strom:

// TreeNode představuje uzel binárního stromu
type TreeNode struct {
	Val   int
	Left  *TreeNode
	Right *TreeNode
}

// InOrderTraversal provádí inorder průchod
func InOrderTraversal(root *TreeNode) []int {
	var result []int
	if root == nil {
		return result
	}

	// Rekurzivní volání pro levé podstrom
	result = append(result, InOrderTraversal(root.Left)...)
	// Návštěva aktuálního uzlu
	result = append(result, root.Val)
	// Rekurzivní volání pro pravé podstrom
	result = append(result, InOrderTraversal(root.Right)...)

	return result
}

Příklad BFS:

// TreeNode představuje uzel binárního stromu
type TreeNode struct {
	Val   int
	Left  *TreeNode
	Right *TreeNode
}

// BFSTraversal provádí BFS průchod
func BFSTraversal(root *TreeNode) []int {
	var result []int
	if root == nil {
		return result
	}

	// Fronta pro uložení uzlů na aktuální úrovni
	queue := []*TreeNode{root}

	for len(queue) > 0 {
		// Odebrat první prvek z fronty
		node := queue[0]
		queue = queue[1:]

		// Přidat hodnotu uzlu do výsledku
		result = append(result, node.Val)

		// Přidat levého potomka do fronty, pokud existuje
		if node.Left != nil {
			queue = append(queue, node.Left)
		}
		// Přidat pravého potomka do fronty, pokud existuje
		if node.Right != nil {
			queue = append(queue, node.Right)
		}
	}
	return result
}

Pro binární vyhledávací stromy (BST), kde levé podstrom je menší než kořen a pravé větší:

  1. Binární hledání: Při hledání konkrétní hodnoty ji porovnáváme s kořenem. Pokud je menší, hledáme v levém podstromu; pokud je větší, v pravém. Toto je nejefektivnější strategie hledání v BST.
// TreeNode představuje uzel binárního vyhledávacího stromu
type TreeNode struct {
	Val   int
	Left  *TreeNode
	Right *TreeNode
}

// SearchBST provádí binární hledání v BST
func SearchBST(root *TreeNode, target int) *TreeNode {
	if root == nil || root.Val == target {
		return root // Uzlík nalezen nebo strom je prázdný
	}

	if target < root.Val {
		// Hledat v levém podstromu
		return SearchBST(root.Left, target)
	}
	// Hledat v pravém podstromu
	return SearchBST(root.Right, target)
}

Volba algoritmu hledání závisí na úloze a vlastnostech stromu. DFS je vhodný pro případy, kdy je třeba jít hluboko do větve nebo najít cestu k cíli. BFS je vhodný pro hledání nejkratší cesty nebo průchod úrovněmi. Binární hledání je efektivní pro hledání konkrétní hodnoty v seřazených strukturách, jako je BST.