0
0

More than 1 year has passed since last update.

Btreeの実装例(golang)

Posted at

何が書いてあるか

BtreeのGoでの実装例。備忘録。

// 節・葉に持たせる機能のインターフェース
type Item interface {
    Eq(Item)   bool
    Less(Item) bool
}
// インターフェースの実装
type Int int
func (n Int) Eq(m Item) bool {
    return n == m.(Int)
}
func (n Int) Less(m Item) bool {
    return n < m.(Int)
}
// 節・葉の構造
type Node struct {
    item Item
    left, right *Node
}
// 節・葉の作成
func newNode(x Item) *Node {
    p := new(Node)
    p.item = x
    return p
}
// 二分木
type Tree struct {
    root *Node
}
// 二分木の生成
func newTree() *Tree {
    return new(Tree)
}
// データの探索
func (t *Tree) searchTree(x Item) bool {
    return searchNode(t.root, x)
}
// 木への挿入
func (t *Tree) insertTree(x Item) {
    t.root = insertNode(t.root, x)
}
// 節・葉の挿入
func insertNode(node *Node, x Item) *Node {
    switch {
    case node == nil: return newNode(x)
    case x.Eq(node.item): return node
    case x.Less(node.item):
        node.left = insertNode(node.left, x)
    default:
        node.right = insertNode(node.right, x)
    }
    return node
}
// 節・葉の探索
func searchNode(node *Node, x Item) bool {
    for node != nil {
        switch {
        case x.Eq(node.item): return true
        case x.Less(node.item): node = node.left
        default: node = node.right
        }
    }
    return false
}
// 木のダンプ
func (t *Tree) printTree() {
    t.foreachTree(func(x Item) { fmt.Print(x, " ") })
    fmt.Println("")
}
// 木からの削除
func (t *Tree) deleteTree(x Item) {
    t.root = deleteNode(t.root, x)
}
// 節・葉の削除
func deleteNode(node *Node, x Item) *Node {
    if node != nil {
        if x.Eq(node.item) {
            if node.left == nil {
                return node.right
            } else if node.right == nil {
                return node.left
            } else {
                node.item = searchMin(node.right)
                node.right = deleteMin(node.right)
            }
        } else if x.Less(node.item) {
            node.left = deleteNode(node.left, x)
        } else {
            node.right = deleteNode(node.right, x)
        }
    }
    return node
}
// 最小値を求める
func searchMin(node *Node) Item {
    if node.left == nil {
        return node.item
    }
    return searchMin(node.left)
}
// 最小値を削除する
func deleteMin(node *Node) *Node {
    if node.left == nil {
        return node.right
    }
    node.left = deleteMin(node.left)
    return node
}
// 巡回
func foreachNode(f func(Item), node *Node) {
    if node != nil {
        foreachNode(f, node.left)
        f(node.item)
        foreachNode(f, node.right)
    }
}
func (t *Tree) foreachTree(f func(Item)) {
    foreachNode(f, t.root)
}

func main(){
    a := newTree()
    for _, v := range []int{5,6,4,7,3,8,2,9,1,0} {
        a.insertTree(Int(v))
    }
    a.printTree()
    for i := 0; i < 10; i++ {
        fmt.Println(a.searchTree(Int(i)))
    }
    for i := 0; i < 10; i++ {
        a.deleteTree(Int(i))
        a.printTree()
    }
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0