• Binary Search Tree


    Terms
    Path - Path refers to the sequence of nodes along the edges of a tree
    Root - The node at the top of the tree is called root.
             . There is ONLY one root per tree
             . There is Only one path from root node to any node.

    Parent - Any node ( except the root node) has one edge upward to a node called parent.
    Child  - The node below a given node connected by its edge downward is called its child node.
    Leaf - The node which does not have any child node is called the leaf node.
    Subtree - Subtree represents the descendants of a node.
    Visiting - Visiting refers to checking the value of a node when control is on the node.
    Traversing - Traversing means passing through nodes in a specific order.
    Levels - Level of a node represents the generation of a node. If the root node is at level 0, then its next child is at level1,
             its grandchild is at level 2, and so on.
             this is height of a three, from 0.
    Keys - Key represents a value of a node based on which a search operation is to be carried out for a node.


    Binary Search Tree Representation
    A node's left child must have a value less than its parent's value and the node's right child must have a value greater than its parent value.


    golang code

    Basic Operations
    Insert                         - Insert an element in a tree/create a tree
    Search                       - Searches an element in a tree
    Preorder Traversal    - Traverses a tree in a pre-order manner.
    Inorder Traversal      - Traverses a tree in an in-order manner.
    Postorder Traversal - Traverses a tree in a post-order manner.


    Insert Operation
    The very first insertion creates the tree. Afterwards, whenever an element is to be inserted, first locate its proper location.
    Start searching from the root node, the if the data is less than the key value, search for the empty location in the left subtree and insert the data.
    Otherwise, search for the empty location in the right subtree and insert the data.

    golang code

    Search Operation
    Whenever an element is to be searched, start searching fromo the root node, then if the data is less than the key value, search for the element in the left
    subtree. Otherwise, search for the element in the right subtree. Follow the same algorighm for each node.

    golang code


    Traverse Operation
    Traversal is a process to visit all the nodes of a tree.Because, all nodes are connected via edges we always start from the root node.
    That is, we cannot randomly access a node in a tree. There are three ways which we use to traverse a tree:
      .In-order Traversal
      .Pre-order Traversal
      .Post-order Traversal

    In-order Traversal
    In this traversal method, the left subtree is visited first, then the root and later the right subtree.
    * We should always remember that every node may represent a subtree itself.

    If a binary tree is traversed in-order, the output will produce sorted key values in an ascending order.



    We start from A, and following in-order traversal, we move to its left subtree B. B is also traversed in-order.
    The process goes on until all the nodes are visited. The output of inorder traversal of this tree will be:
    D -> B -> E -> A -> F -> C -> G


    Pre-order Traversal
    In this traversal method, the root node is visited first, then the left subtree and finally the right subtree.
    We start from A, and following pre-order traversal, we first visit A itself and then move to its left subtree B.
    B is also traversed pre-order. The process goes on until all the nodes are visited.
    The output of pre-order traversal of this tree will be:
    A -> B -> D -> E -> C -> F -> G


    Post-order Traversal
    In this traversal method, the root node is visited last, hense the name.
    First we traverse the left subtree, then the right subtree and finally the root node.
    We start from A, and following Post-order traversal, we first visit the left subtree B.
    B is also traversed post-order. The process goes on until all the nodes are visited.
    The output of post-order traversal of this tree will be:
    D -> E -> B -> F -> G -> C -> A

     Golang:

      1 package binary_search_tree
      2 
      3 import (
      4     "fmt"
      5 )
      6 
      7 type Node struct {
      8     Data       int
      9     LeftChild  *Node
     10     RightChild *Node
     11 }
     12 
     13 type BinarySearchTree struct {
     14     Root *Node
     15 }
     16 
     17 func (bst *BinarySearchTree) Insert(data int) {
     18     tmpNode := &Node{data, nil, nil}
     19 
     20     if bst.Root == nil {
     21         bst.Root = tmpNode // create root node
     22         return
     23     }
     24 
     25     var parent *Node
     26     current := bst.Root
     27 
     28     for true {
     29         parent = current
     30         if data < parent.Data {
     31             current = parent.LeftChild
     32             if current == nil {
     33                 parent.LeftChild = tmpNode
     34                 return
     35             }
     36         } else {
     37             current = parent.RightChild
     38             if current == nil {
     39                 parent.RightChild = tmpNode
     40                 return
     41             }
     42         }
     43     }
     44 }
     45 
     46 func (bst *BinarySearchTree) Search(data int) *Node {
     47     if bst.Root == nil {
     48         fmt.Println("binary search tree is empty.")
     49         return nil
     50     }
     51 
     52     fmt.Printf("Visiting elements %d, path:", data)
     53     current := bst.Root
     54 
     55     for current.Data != data {
     56         if current != nil {
     57             fmt.Printf(" -> %d", current.Data)
     58         }
     59 
     60         if data < current.Data {
     61             current = current.LeftChild
     62         } else {
     63             current = current.RightChild
     64         }
     65 
     66         if current == nil {
     67             fmt.Printf(" >> %d not found
    ", data)
     68             return nil
     69         }
     70     }
     71 
     72     fmt.Printf(" -> %d found
    ", data)
     73     return current
     74 }
     75 
     76 func traverseInOrder(root *Node) {
     77     if root == nil {
     78         return
     79     }
     80 
     81     // visit left child
     82     if root.LeftChild != nil {
     83         traverseInOrder(root.LeftChild)
     84     }
     85 
     86     // visit root
     87     fmt.Printf(" %d", root.Data)
     88 
     89     // visit right child
     90     if root.RightChild != nil {
     91         traverseInOrder(root.RightChild)
     92     }
     93 }
     94 
     95 func traversePreOrder(root *Node) {
     96     if root == nil {
     97         return
     98     }
     99 
    100     // visit root
    101     fmt.Printf(" %d", root.Data)
    102 
    103     // visit left child
    104     if root.LeftChild != nil {
    105         traversePreOrder(root.LeftChild)
    106     }
    107 
    108     // visit right child
    109     if root.RightChild != nil {
    110         traversePreOrder(root.RightChild)
    111     }
    112 }
    113 
    114 func traversePostOrder(root *Node) {
    115     if root == nil {
    116         return
    117     }
    118 
    119     // visit left child
    120     if root.LeftChild != nil {
    121         traversePostOrder(root.LeftChild)
    122     }
    123 
    124     // visit right child
    125     if root.RightChild != nil {
    126         traversePostOrder(root.RightChild)
    127     }
    128 
    129     // visit root
    130     fmt.Printf(" %d", root.Data)
    131 }
    132 
    133 func (bst *BinarySearchTree) TraverseInOrder() {
    134     if bst.Root == nil {
    135         fmt.Println("tree is empty.")
    136     }
    137     fmt.Print("inorder traversal: ")
    138     traverseInOrder(bst.Root)
    139     fmt.Println("")
    140 }
    141 
    142 func (bst *BinarySearchTree) TraversePreOrder() {
    143     if bst.Root == nil {
    144         fmt.Println("tree is empty.")
    145     }
    146     fmt.Print("preorder traversal: ")
    147     traversePreOrder(bst.Root)
    148     fmt.Println("")
    149 }
    150 
    151 func (bst *BinarySearchTree) TraversePostOrder() {
    152     if bst.Root == nil {
    153         fmt.Println("tree is empty.")
    154     }
    155     fmt.Print("postorder traversal: ")
    156     traversePostOrder(bst.Root)
    157     fmt.Println(" ")
    158 }

    Test:

    package main
    
    import (
        bst "binary_search_tree"
    )
    
    func createTree(bst *bst.BinarySearchTree) {
        bst.Insert(27)
        bst.Insert(35)
        bst.Insert(14)
        bst.Insert(19)
        bst.Insert(42)
        bst.Insert(31)
        bst.Insert(10)
        bst.Insert(8)
        bst.Insert(74)
        bst.Insert(40)
        bst.Insert(23)
        bst.Insert(18)
    }
    
    func search(bst *bst.BinarySearchTree) {
        bst.Search(31)
        bst.Search(19)
        bst.Search(42)
        bst.Search(10)
        bst.Search(16)
        bst.Search(8)
        bst.Search(74)
        bst.Search(23)
        bst.Search(71)
    }
    
    func traverse(bst *bst.BinarySearchTree) {
        bst.TraverseInOrder()
        bst.TraversePreOrder()
        bst.TraversePostOrder()
    }
    

    func main() { bst := &bst.BinarySearchTree{} // 27 // / // 14 35 // / / // 10 19 31 42 // / / / // 8 18 23 40 74 createTree(bst) search(bst) traverse(bst) }

    output:

    Visiting elements 31, path: -> 27 -> 35 -> 31 found
    Visiting elements 19, path: -> 27 -> 14 -> 19 found
    Visiting elements 42, path: -> 27 -> 35 -> 42 found
    Visiting elements 10, path: -> 27 -> 14 -> 10 found
    Visiting elements 16, path: -> 27 -> 14 -> 19 -> 18 >> 16 not found
    Visiting elements 8, path: -> 27 -> 14 -> 10 -> 8 found
    Visiting elements 74, path: -> 27 -> 35 -> 42 -> 74 found
    Visiting elements 23, path: -> 27 -> 14 -> 19 -> 23 found
    Visiting elements 71, path: -> 27 -> 35 -> 42 -> 74 >> 71 not found
    inorder traversal:  8 10 14 18 19 23 27 31 35 40 42 74
    preorder traversal:  27 14 10 8 19 18 23 35 31 42 40 74
    postorder traversal:  8 10 18 23 19 14 31 40 74 42 35 27 
  • 相关阅读:
    sphinx的配置和管理
    linux 性能分析
    17个非常有用的PHP类和库
    webkit webApp 开发技术要点总结
    国外十大流行的服务器监控工具
    lnmp环境搭建,超详细教程
    nginx在window下的服务安装
    HBase源代码阅读与理解
    找出1到N中缺少的數?
    插入排序 (insertion_sort)與 合並排序 (mergesort)
  • 原文地址:https://www.cnblogs.com/bear129/p/8545486.html
Copyright © 2020-2023  润新知