btree: add a way to visualize the tree

This commit is contained in:
Antoine Bartuccio 2019-07-31 14:09:13 +02:00
parent bb83664e87
commit d99fc856c3
Signed by: klmp200
GPG Key ID: E7245548C53F904B
3 changed files with 73 additions and 10 deletions

View File

@ -12,8 +12,8 @@ type data struct {
// Tree is the tree itself // Tree is the tree itself
type Tree struct { type Tree struct {
root *node // Pointer to the node root root *node // Pointer to the node root
t int // Minimum degree degree int // Minimum degree
} }
type node struct { type node struct {
@ -27,11 +27,11 @@ type node struct {
// Constructors // Constructors
// NewBtree creates a new btree // NewBtree creates a new btree
func NewBtree(t int) *Tree { func NewBtree(degree int) *Tree {
return &Tree{ return &Tree{
root: nil, root: nil,
t: t, degree: degree,
} }
} }
@ -62,6 +62,15 @@ func (a *data) gt(b *data) bool {
// Tree methods // Tree methods
// Visualize the tree
func (t *Tree) Visualize() {
if t.root == nil {
fmt.Println("The tree is empty")
return
}
t.root.visualize("", true)
}
// Traverse the tree // Traverse the tree
func (t *Tree) Traverse() { func (t *Tree) Traverse() {
@ -113,8 +122,8 @@ func (t *Tree) Insert(key, value string) {
// If the tree is empty // If the tree is empty
if t.root == nil { if t.root == nil {
t.root = newNode(t.t, true) t.root = newNode(t.degree, true)
t.root.keys[0] = k t.root.insertKey(0, k)
t.root.numberOfKeys = 1 t.root.numberOfKeys = 1
return return
} }
@ -127,7 +136,7 @@ func (t *Tree) Insert(key, value string) {
} }
// If the root is full, then the tree grows in height // If the root is full, then the tree grows in height
s := newNode(t.t, false) s := newNode(t.degree, false)
// Make the old root as a child of the new root // Make the old root as a child of the new root
s.children[0] = t.root s.children[0] = t.root
@ -149,6 +158,37 @@ func (t *Tree) Insert(key, value string) {
// node methods // node methods
// insertKey at i place in the node
func (n *node) insertKey(i int, k *data) {
n.keys[i] = k
}
func (n *node) visualize(prefix string, isEnd bool) {
fmt.Print(prefix)
nextPrefix := " "
if isEnd {
fmt.Print("└── ")
} else {
fmt.Print("├── ")
nextPrefix = "│ "
}
for i := 0; i < n.numberOfKeys-1; i++ {
fmt.Printf("%s:%s ", n.keys[i].key, n.keys[i].value)
}
fmt.Printf("%s:%s", n.keys[n.numberOfKeys-1].key, n.keys[n.numberOfKeys-1].value)
fmt.Printf("\n")
if n.isLeaf {
return
}
for i := 0; i < n.numberOfKeys; i++ {
n.children[i].visualize(fmt.Sprintf("%s%s", prefix, nextPrefix), false)
}
n.children[n.numberOfKeys].visualize(fmt.Sprintf("%s%s", prefix, nextPrefix), true)
}
// traverse all nodes in a subtree rooted with this node // traverse all nodes in a subtree rooted with this node
func (n *node) traverse() { func (n *node) traverse() {
@ -209,7 +249,7 @@ func (n *node) insertNonFull(k *data) {
} }
// Insert the new key at the found location // Insert the new key at the found location
n.keys[i+1] = k n.insertKey(i+1, k)
n.numberOfKeys++ n.numberOfKeys++
return return
} }

View File

@ -106,6 +106,9 @@ func ExampleTree_Traverse() {
tree.Insert(k[0], k[1]) tree.Insert(k[0], k[1])
} }
tree.Visualize()
fmt.Println("")
tree.Traverse() tree.Traverse()
fmt.Println("") fmt.Println("")
@ -133,7 +136,14 @@ func ExampleTree_Traverse() {
tree.Traverse() tree.Traverse()
// Output: // Output:
// a:A b:B c:C d:D e:E f:F g:G h:H i:I j:J k:K l:L m:M n:N o:O p:P q:Q // └── c:C f:F i:I l:L
// ├── a:A b:B
// ├── d:D e:E
// ├── g:G h:H
// ├── j:J k:K
// └── m:M n:N o:O p:P q:Q
//
// a:A b:B c:C d:D e:E f:F g:G h:H i:I j:J k:K l:L m:M n:N o:O p:P q:Q
// a:A b:B c:C d:D f:F g:G h:H i:I j:J k:K l:L m:M n:N o:O p:P q:Q // a:A b:B c:C d:D f:F g:G h:H i:I j:J k:K l:L m:M n:N o:O p:P q:Q
// a:A b:B c:C d:D f:F g:G h:H i:I k:K l:L m:M n:N o:O p:P q:Q // a:A b:B c:C d:D f:F g:G h:H i:I k:K l:L m:M n:N o:O p:P q:Q
// b:B c:C d:D f:F g:G h:H i:I k:K l:L m:M n:N o:O p:P q:Q // b:B c:C d:D f:F g:G h:H i:I k:K l:L m:M n:N o:O p:P q:Q

13
main.go
View File

@ -11,16 +11,28 @@ func main() {
// Example program // Example program
t := btree.NewBtree(3) t := btree.NewBtree(3)
t.Insert("animal", "dog") t.Insert("animal", "dog")
s, _ := t.Search("animal")
fmt.Println(s)
t.Insert("potato", "fries") t.Insert("potato", "fries")
t.Insert("6", "number") t.Insert("6", "number")
t.Insert("12", "number") t.Insert("12", "number")
t.Insert("car", "ferrari") t.Insert("car", "ferrari")
t.Insert("7", "number") t.Insert("7", "number")
t.Insert("plane", "airbus") t.Insert("plane", "airbus")
t.Insert("animal", "cat")
s, _ = t.Search("animal")
fmt.Println(s)
fmt.Print("Traversal of the constructed tree is") fmt.Print("Traversal of the constructed tree is")
t.Traverse() t.Traverse()
fmt.Println("")
t.Visualize()
if val, err := t.Search("6"); err != nil { if val, err := t.Search("6"); err != nil {
fmt.Print("\nNot Present") fmt.Print("\nNot Present")
} else { } else {
@ -32,4 +44,5 @@ func main() {
} else { } else {
fmt.Printf("\nPresent: value '%s'", val) fmt.Printf("\nPresent: value '%s'", val)
} }
} }