btree: store strings via "data" struct
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
This commit is contained in:
parent
5fccf8c6ec
commit
bb83664e87
113
btree/btree.go
113
btree/btree.go
@ -2,21 +2,26 @@ package btree
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type data struct {
|
||||||
|
key string
|
||||||
|
value string
|
||||||
|
}
|
||||||
|
|
||||||
// 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
|
t int // Minimum degree
|
||||||
}
|
}
|
||||||
|
|
||||||
// Node is a Node of a Btree
|
type node struct {
|
||||||
type Node struct {
|
|
||||||
numberOfKeys int // The number of keys really stored
|
numberOfKeys int // The number of keys really stored
|
||||||
degree int // The value of degree dependes upon disk blok size
|
degree int // The value of degree dependes upon disk blok size
|
||||||
isLeaf bool
|
isLeaf bool
|
||||||
keys []int
|
keys []*data
|
||||||
children []*Node
|
children []*node
|
||||||
}
|
}
|
||||||
|
|
||||||
// Constructors
|
// Constructors
|
||||||
@ -30,17 +35,31 @@ func NewBtree(t int) *Tree {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func newNode(degree int, isLeaf bool) *Node {
|
func newNode(degree int, isLeaf bool) *node {
|
||||||
|
|
||||||
return &Node{
|
return &node{
|
||||||
numberOfKeys: 0,
|
numberOfKeys: 0,
|
||||||
degree: degree,
|
degree: degree,
|
||||||
isLeaf: isLeaf,
|
isLeaf: isLeaf,
|
||||||
keys: make([]int, 2*degree-1),
|
keys: make([]*data, 2*degree-1),
|
||||||
children: make([]*Node, 2*degree),
|
children: make([]*node, 2*degree),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Data methods
|
||||||
|
|
||||||
|
func (a *data) eq(b *data) bool {
|
||||||
|
return strings.Compare(a.key, b.key) == 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *data) lt(b *data) bool {
|
||||||
|
return strings.Compare(a.key, b.key) == -1
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *data) gt(b *data) bool {
|
||||||
|
return strings.Compare(a.key, b.key) == 1
|
||||||
|
}
|
||||||
|
|
||||||
// Tree methods
|
// Tree methods
|
||||||
|
|
||||||
// Traverse the tree
|
// Traverse the tree
|
||||||
@ -52,20 +71,22 @@ func (t *Tree) Traverse() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Search k in the tree
|
// Search k in the tree
|
||||||
func (t *Tree) Search(k int) *Node {
|
func (t *Tree) Search(k string) (string, error) {
|
||||||
|
|
||||||
if t.root == nil {
|
if t.root == nil {
|
||||||
return nil
|
return "", fmt.Errorf("The key %s does not exist", k)
|
||||||
}
|
}
|
||||||
|
|
||||||
return t.root.search(k)
|
return t.root.search(&data{key: k})
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove k in the tree
|
// Remove k in the tree
|
||||||
func (t *Tree) Remove(k int) error {
|
func (t *Tree) Remove(key string) error {
|
||||||
|
|
||||||
if t.root == nil {
|
if t.root == nil {
|
||||||
return fmt.Errorf("The tree is empty")
|
return fmt.Errorf("The tree is empty")
|
||||||
}
|
}
|
||||||
|
k := &data{key: key}
|
||||||
|
|
||||||
err := t.root.remove(k)
|
err := t.root.remove(k)
|
||||||
|
|
||||||
@ -83,7 +104,13 @@ func (t *Tree) Remove(k int) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Insert k in the tree
|
// Insert k in the tree
|
||||||
func (t *Tree) Insert(k int) {
|
func (t *Tree) Insert(key, value string) {
|
||||||
|
|
||||||
|
k := &data{
|
||||||
|
key: key,
|
||||||
|
value: value,
|
||||||
|
}
|
||||||
|
|
||||||
// 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.t, true)
|
||||||
@ -111,7 +138,7 @@ func (t *Tree) Insert(k int) {
|
|||||||
// The new root has two children now.
|
// The new root has two children now.
|
||||||
// We decide which of the two children is going to have the new key
|
// We decide which of the two children is going to have the new key
|
||||||
i := 0
|
i := 0
|
||||||
if s.keys[0] < k {
|
if s.keys[0].lt(k) {
|
||||||
i++
|
i++
|
||||||
}
|
}
|
||||||
s.children[i].insertNonFull(k)
|
s.children[i].insertNonFull(k)
|
||||||
@ -120,10 +147,10 @@ func (t *Tree) Insert(k int) {
|
|||||||
t.root = s
|
t.root = s
|
||||||
}
|
}
|
||||||
|
|
||||||
// Node methods
|
// node methods
|
||||||
|
|
||||||
// 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() {
|
||||||
|
|
||||||
// There are n entries and n+1 children, treverse trough n keys and n first children
|
// There are n entries and n+1 children, treverse trough n keys and n first children
|
||||||
for i := 0; i < n.numberOfKeys; i++ {
|
for i := 0; i < n.numberOfKeys; i++ {
|
||||||
@ -131,7 +158,7 @@ func (n *Node) traverse() {
|
|||||||
if !n.isLeaf {
|
if !n.isLeaf {
|
||||||
n.children[i].traverse()
|
n.children[i].traverse()
|
||||||
}
|
}
|
||||||
fmt.Printf(" %d", n.keys[i])
|
fmt.Printf(" %s:%s", n.keys[i].key, n.keys[i].value)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Print the subtree rooted with the last child
|
// Print the subtree rooted with the last child
|
||||||
@ -141,33 +168,33 @@ func (n *Node) traverse() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// search k in the subtree rooted with this node
|
// search k in the subtree rooted with this node
|
||||||
func (n *Node) search(k int) *Node {
|
func (n *node) search(k *data) (string, error) {
|
||||||
|
|
||||||
// Find the first entry greater than or equal to k
|
// Find the first entry greater than or equal to k
|
||||||
i := 0
|
i := 0
|
||||||
for i < n.numberOfKeys && k > n.keys[i] {
|
for i < n.numberOfKeys && k.gt(n.keys[i]) {
|
||||||
i++
|
i++
|
||||||
}
|
}
|
||||||
|
|
||||||
// If theh found key is equal to k, return this node
|
// If the found key is equal to k, return this node
|
||||||
if n.keys[i] == k {
|
if n.keys[i] != nil && k.eq(n.keys[i]) {
|
||||||
return n
|
return n.keys[i].value, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the key is not found here and this is a leaf node
|
// If the key is not found here and this is a leaf node
|
||||||
if n.isLeaf {
|
if n.isLeaf {
|
||||||
return nil
|
return "", fmt.Errorf("The key %s does not exist", k.key)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Go to the approipriate child
|
// Go to the approipriate child
|
||||||
return n.children[i].search(k)
|
return n.children[i].search(k)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *Node) isFull() bool {
|
func (n *node) isFull() bool {
|
||||||
return n.numberOfKeys == 2*n.degree-1
|
return n.numberOfKeys == 2*n.degree-1
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *Node) insertNonFull(k int) {
|
func (n *node) insertNonFull(k *data) {
|
||||||
|
|
||||||
// Initialize the index as the index of the rightmost element
|
// Initialize the index as the index of the rightmost element
|
||||||
i := n.numberOfKeys - 1
|
i := n.numberOfKeys - 1
|
||||||
@ -176,7 +203,7 @@ func (n *Node) insertNonFull(k int) {
|
|||||||
if n.isLeaf {
|
if n.isLeaf {
|
||||||
// Finds the location of the new key to be inserted
|
// Finds the location of the new key to be inserted
|
||||||
// Moves all greater keys to one place ahead
|
// Moves all greater keys to one place ahead
|
||||||
for i >= 0 && n.keys[i] > k {
|
for i >= 0 && n.keys[i].gt(k) {
|
||||||
n.keys[i+1] = n.keys[i]
|
n.keys[i+1] = n.keys[i]
|
||||||
i--
|
i--
|
||||||
}
|
}
|
||||||
@ -189,7 +216,7 @@ func (n *Node) insertNonFull(k int) {
|
|||||||
|
|
||||||
// If this is not a leaf
|
// If this is not a leaf
|
||||||
// Finds the child wich is going to have the new key
|
// Finds the child wich is going to have the new key
|
||||||
for i >= 0 && n.keys[i] > k {
|
for i >= 0 && n.keys[i].gt(k) {
|
||||||
i--
|
i--
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -201,7 +228,7 @@ func (n *Node) insertNonFull(k int) {
|
|||||||
// After the split, the middle key of children[i] goes up and
|
// After the split, the middle key of children[i] goes up and
|
||||||
// children[i] is splitted into two
|
// children[i] is splitted into two
|
||||||
// See which of those two is going to have the new key
|
// See which of those two is going to have the new key
|
||||||
if n.keys[i+1] < k {
|
if n.keys[i+1].lt(k) {
|
||||||
i++
|
i++
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -209,7 +236,7 @@ func (n *Node) insertNonFull(k int) {
|
|||||||
n.children[i+1].insertNonFull(k)
|
n.children[i+1].insertNonFull(k)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *Node) splitChild(i int, y *Node) {
|
func (n *node) splitChild(i int, y *node) {
|
||||||
|
|
||||||
// Create a new node that will store (t-1) keys of y
|
// Create a new node that will store (t-1) keys of y
|
||||||
z := newNode(y.degree, y.isLeaf)
|
z := newNode(y.degree, y.isLeaf)
|
||||||
@ -253,22 +280,22 @@ func (n *Node) splitChild(i int, y *Node) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// findKey returns the index of the first key that is greater than or equal to k
|
// findKey returns the index of the first key that is greater than or equal to k
|
||||||
func (n *Node) findKey(k int) int {
|
func (n *node) findKey(k *data) int {
|
||||||
|
|
||||||
index := 0
|
index := 0
|
||||||
for index < n.numberOfKeys && n.keys[index] < k {
|
for index < n.numberOfKeys && n.keys[index].lt(k) {
|
||||||
index++
|
index++
|
||||||
}
|
}
|
||||||
return index
|
return index
|
||||||
}
|
}
|
||||||
|
|
||||||
// remove the key k from the sub-tree rooted with this node
|
// remove the key k from the sub-tree rooted with this node
|
||||||
func (n *Node) remove(k int) error {
|
func (n *node) remove(k *data) error {
|
||||||
|
|
||||||
index := n.findKey(k)
|
index := n.findKey(k)
|
||||||
|
|
||||||
// The key to be removed is in this node
|
// The key to be removed is in this node
|
||||||
if index < n.numberOfKeys && n.keys[index] == k {
|
if index < n.numberOfKeys && n.keys[index].eq(k) {
|
||||||
if n.isLeaf {
|
if n.isLeaf {
|
||||||
return n.removeFromLeaf(index)
|
return n.removeFromLeaf(index)
|
||||||
}
|
}
|
||||||
@ -277,7 +304,7 @@ func (n *Node) remove(k int) error {
|
|||||||
|
|
||||||
// If this is a leaf, the key is not in the tree
|
// If this is a leaf, the key is not in the tree
|
||||||
if n.isLeaf {
|
if n.isLeaf {
|
||||||
return fmt.Errorf("The key %d does not exist in the tree", k)
|
return fmt.Errorf("The key %s does not exist in the tree", k)
|
||||||
}
|
}
|
||||||
|
|
||||||
isInLastChild := false
|
isInLastChild := false
|
||||||
@ -301,7 +328,7 @@ func (n *Node) remove(k int) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// removeFromLeaf the index-th key from this node which is a leaf node
|
// removeFromLeaf the index-th key from this node which is a leaf node
|
||||||
func (n *Node) removeFromLeaf(index int) error {
|
func (n *node) removeFromLeaf(index int) error {
|
||||||
|
|
||||||
// Move all the keys after the index-th position one place backward
|
// Move all the keys after the index-th position one place backward
|
||||||
for i := index + 1; i < n.numberOfKeys; i++ {
|
for i := index + 1; i < n.numberOfKeys; i++ {
|
||||||
@ -313,7 +340,7 @@ func (n *Node) removeFromLeaf(index int) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// removeFromNonLeaf the index-th key from this node which is not a leaf node
|
// removeFromNonLeaf the index-th key from this node which is not a leaf node
|
||||||
func (n *Node) removeFromNonLeaf(index int) error {
|
func (n *node) removeFromNonLeaf(index int) error {
|
||||||
|
|
||||||
k := n.keys[index]
|
k := n.keys[index]
|
||||||
|
|
||||||
@ -342,7 +369,7 @@ func (n *Node) removeFromNonLeaf(index int) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// getPred returns the predecessor of keys[index]
|
// getPred returns the predecessor of keys[index]
|
||||||
func (n *Node) getPred(index int) int {
|
func (n *node) getPred(index int) *data {
|
||||||
|
|
||||||
// Keep moving to the rightmost node until we reach a leaf
|
// Keep moving to the rightmost node until we reach a leaf
|
||||||
current := n.children[index]
|
current := n.children[index]
|
||||||
@ -355,7 +382,7 @@ func (n *Node) getPred(index int) int {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// getSucc returns the successor of keys[index]
|
// getSucc returns the successor of keys[index]
|
||||||
func (n *Node) getSucc(index int) int {
|
func (n *node) getSucc(index int) *data {
|
||||||
|
|
||||||
// Keep moving to the leftmost node starting from children[index+1] until we reach a leaf
|
// Keep moving to the leftmost node starting from children[index+1] until we reach a leaf
|
||||||
current := n.children[index+1]
|
current := n.children[index+1]
|
||||||
@ -368,7 +395,7 @@ func (n *Node) getSucc(index int) int {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// fill child children[index] which has less than t-1 keys
|
// fill child children[index] which has less than t-1 keys
|
||||||
func (n *Node) fill(index int) {
|
func (n *node) fill(index int) {
|
||||||
|
|
||||||
// If the previous child has more than t-1 keys, borrow a key from that child
|
// If the previous child has more than t-1 keys, borrow a key from that child
|
||||||
if index != 0 && n.children[index-1].numberOfKeys >= n.degree {
|
if index != 0 && n.children[index-1].numberOfKeys >= n.degree {
|
||||||
@ -393,7 +420,7 @@ func (n *Node) fill(index int) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// borrowFromPrev takes a key from children[index+1] and insert it in children[index]
|
// borrowFromPrev takes a key from children[index+1] and insert it in children[index]
|
||||||
func (n *Node) borrowFromPrev(index int) {
|
func (n *node) borrowFromPrev(index int) {
|
||||||
|
|
||||||
child := n.children[index]
|
child := n.children[index]
|
||||||
sibling := n.children[index-1]
|
sibling := n.children[index-1]
|
||||||
@ -426,7 +453,7 @@ func (n *Node) borrowFromPrev(index int) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// borrowFromNext takes a key from children[index+1] and insert it in children[index]
|
// borrowFromNext takes a key from children[index+1] and insert it in children[index]
|
||||||
func (n *Node) borrowFromNext(index int) {
|
func (n *node) borrowFromNext(index int) {
|
||||||
|
|
||||||
child := n.children[index]
|
child := n.children[index]
|
||||||
sibling := n.children[index+1]
|
sibling := n.children[index+1]
|
||||||
@ -460,7 +487,7 @@ func (n *Node) borrowFromNext(index int) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// merge children[index] with children[index+1]
|
// merge children[index] with children[index+1]
|
||||||
func (n *Node) merge(index int) {
|
func (n *node) merge(index int) {
|
||||||
|
|
||||||
child := n.children[index]
|
child := n.children[index]
|
||||||
sibling := n.children[index+1]
|
sibling := n.children[index+1]
|
||||||
|
@ -7,59 +7,75 @@ import (
|
|||||||
|
|
||||||
func TestTree_Search(t *testing.T) {
|
func TestTree_Search(t *testing.T) {
|
||||||
tree := NewBtree(3)
|
tree := NewBtree(3)
|
||||||
tree.Insert(6)
|
tree.Insert("A", "a")
|
||||||
|
|
||||||
k := 6
|
k := "A"
|
||||||
if tree.Search(k) == nil {
|
if _, err := tree.Search(k); err != nil {
|
||||||
t.Errorf("Not present %d", k)
|
t.Errorf("Not present %s", k)
|
||||||
}
|
}
|
||||||
|
|
||||||
k = 15
|
k = "bike"
|
||||||
if tree.Search(k) != nil {
|
if val, err := tree.Search(k); err == nil {
|
||||||
t.Errorf("Present %d", k)
|
t.Errorf("Present %s with value %s", k, val)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestTree_Remove(t *testing.T) {
|
func TestTree_Remove(t *testing.T) {
|
||||||
tree := NewBtree(3)
|
tree := NewBtree(3)
|
||||||
toInsert := []int{10, 20, 5, 6, 12, 30, 7, 17}
|
toInsert := [][]string{
|
||||||
|
[]string{"Monday", "Lundi"},
|
||||||
|
[]string{"Tuesday", "Mardi"},
|
||||||
|
[]string{"Wednesday", "Mercredi"},
|
||||||
|
[]string{"Thursday", "Jeudi"},
|
||||||
|
[]string{"Friday", "Vendredi"},
|
||||||
|
[]string{"Saturday", "Samedi"},
|
||||||
|
[]string{"Sunday", "Dimanche"},
|
||||||
|
}
|
||||||
|
|
||||||
for _, k := range toInsert {
|
for _, k := range toInsert {
|
||||||
tree.Insert(k)
|
tree.Insert(k[0], k[1])
|
||||||
}
|
}
|
||||||
|
|
||||||
tree.Remove(toInsert[0])
|
tree.Remove("Monday")
|
||||||
for _, k := range toInsert[1:] {
|
for _, k := range toInsert[1:] {
|
||||||
if tree.Search(k) == nil {
|
if _, err := tree.Search(k[0]); err != nil {
|
||||||
t.Errorf("Not present %d", k)
|
t.Errorf("Not present %s", k)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if tree.Search(toInsert[0]) != nil {
|
if val, err := tree.Search("Monday"); err == nil {
|
||||||
t.Errorf("Present %d", toInsert[0])
|
t.Errorf("Present %s with value %s", toInsert[0], val)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestTree_Insert(t *testing.T) {
|
func TestTree_Insert(t *testing.T) {
|
||||||
tree := NewBtree(3)
|
tree := NewBtree(3)
|
||||||
toInsert := []int{10, 20, 5, 6, 12, 30, 7, 17, 20}
|
toInsert := [][]string{
|
||||||
|
[]string{"Monday", "Lundi"},
|
||||||
|
[]string{"Tuesday", "Mardi"},
|
||||||
|
[]string{"Wednesday", "Mercredi"},
|
||||||
|
[]string{"Thursday", "Jeudi"},
|
||||||
|
[]string{"Friday", "Vendredi"},
|
||||||
|
[]string{"Saturday", "Samedi"},
|
||||||
|
[]string{"Sunday", "Dimanche"},
|
||||||
|
}
|
||||||
|
|
||||||
// Test before insertion
|
// Test before insertion
|
||||||
for _, k := range toInsert {
|
for _, k := range toInsert {
|
||||||
if tree.Search(k) != nil {
|
if val, err := tree.Search(k[0]); err == nil {
|
||||||
t.Errorf("Present %d", k)
|
t.Errorf("Present %s with value %s", k[0], val)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, k := range toInsert {
|
for _, k := range toInsert {
|
||||||
tree.Insert(k)
|
tree.Insert(k[0], k[1])
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test after insertion
|
// Test after insertion
|
||||||
for _, k := range toInsert {
|
for _, k := range toInsert {
|
||||||
if tree.Search(k) == nil {
|
if _, err := tree.Search(k[0]); err != nil {
|
||||||
t.Errorf("Not present %d", k)
|
t.Errorf("Not present %s", k)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -67,43 +83,61 @@ func TestTree_Insert(t *testing.T) {
|
|||||||
func ExampleTree_Traverse() {
|
func ExampleTree_Traverse() {
|
||||||
tree := NewBtree(3)
|
tree := NewBtree(3)
|
||||||
|
|
||||||
toInsert := []int{1, 3, 7, 10, 11, 13, 14, 15, 18, 16, 19, 24, 25, 26, 21, 4, 5, 20, 22, 2, 17, 12, 6}
|
toInsert := [][]string{
|
||||||
|
[]string{"a", "A"},
|
||||||
|
[]string{"b", "B"},
|
||||||
|
[]string{"c", "C"},
|
||||||
|
[]string{"d", "D"},
|
||||||
|
[]string{"e", "E"},
|
||||||
|
[]string{"f", "F"},
|
||||||
|
[]string{"g", "G"},
|
||||||
|
[]string{"h", "H"},
|
||||||
|
[]string{"i", "I"},
|
||||||
|
[]string{"j", "J"},
|
||||||
|
[]string{"k", "K"},
|
||||||
|
[]string{"l", "L"},
|
||||||
|
[]string{"m", "M"},
|
||||||
|
[]string{"n", "N"},
|
||||||
|
[]string{"o", "O"},
|
||||||
|
[]string{"p", "P"},
|
||||||
|
[]string{"q", "Q"},
|
||||||
|
}
|
||||||
for _, k := range toInsert {
|
for _, k := range toInsert {
|
||||||
tree.Insert(k)
|
tree.Insert(k[0], k[1])
|
||||||
}
|
}
|
||||||
|
|
||||||
tree.Traverse()
|
tree.Traverse()
|
||||||
fmt.Println("")
|
fmt.Println("")
|
||||||
|
|
||||||
tree.Remove(6)
|
tree.Remove("e")
|
||||||
tree.Traverse()
|
tree.Traverse()
|
||||||
fmt.Println("")
|
fmt.Println("")
|
||||||
|
|
||||||
tree.Remove(13)
|
tree.Remove("j")
|
||||||
tree.Traverse()
|
tree.Traverse()
|
||||||
fmt.Println("")
|
fmt.Println("")
|
||||||
|
|
||||||
tree.Remove(7)
|
tree.Remove("a")
|
||||||
tree.Traverse()
|
tree.Traverse()
|
||||||
fmt.Println("")
|
fmt.Println("")
|
||||||
|
|
||||||
tree.Remove(4)
|
tree.Remove("b")
|
||||||
tree.Traverse()
|
tree.Traverse()
|
||||||
fmt.Println("")
|
fmt.Println("")
|
||||||
|
|
||||||
tree.Remove(2)
|
tree.Remove("d")
|
||||||
tree.Traverse()
|
tree.Traverse()
|
||||||
fmt.Println("")
|
fmt.Println("")
|
||||||
|
|
||||||
tree.Remove(16)
|
tree.Remove("f")
|
||||||
tree.Traverse()
|
tree.Traverse()
|
||||||
|
|
||||||
// Output:
|
// Output:
|
||||||
// 1 2 3 4 5 6 7 10 11 12 13 14 15 16 17 18 19 20 21 22 24 25 26
|
// 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
|
||||||
// 1 2 3 4 5 7 10 11 12 13 14 15 16 17 18 19 20 21 22 24 25 26
|
// 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
|
||||||
// 1 2 3 4 5 7 10 11 12 14 15 16 17 18 19 20 21 22 24 25 26
|
// 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
|
||||||
// 1 2 3 4 5 10 11 12 14 15 16 17 18 19 20 21 22 24 25 26
|
// 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
|
||||||
// 1 2 3 5 10 11 12 14 15 16 17 18 19 20 21 22 24 25 26
|
// 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
|
||||||
// 1 3 5 10 11 12 14 15 16 17 18 19 20 21 22 24 25 26
|
// c:C f:F g:G h:H i:I k:K l:L m:M n:N o:O p:P q:Q
|
||||||
// 1 3 5 10 11 12 14 15 17 18 19 20 21 22 24 25 26
|
// c:C g:G h:H i:I k:K l:L m:M n:N o:O p:P q:Q
|
||||||
}
|
}
|
||||||
|
31
main.go
31
main.go
@ -7,30 +7,29 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
|
||||||
|
// Example program
|
||||||
t := btree.NewBtree(3)
|
t := btree.NewBtree(3)
|
||||||
t.Insert(10)
|
t.Insert("animal", "dog")
|
||||||
t.Insert(20)
|
t.Insert("potato", "fries")
|
||||||
t.Insert(5)
|
t.Insert("6", "number")
|
||||||
t.Insert(6)
|
t.Insert("12", "number")
|
||||||
t.Insert(12)
|
t.Insert("car", "ferrari")
|
||||||
t.Insert(30)
|
t.Insert("7", "number")
|
||||||
t.Insert(7)
|
t.Insert("plane", "airbus")
|
||||||
t.Insert(17)
|
|
||||||
|
|
||||||
fmt.Print("Traversal of the constructed tree is")
|
fmt.Print("Traversal of the constructed tree is")
|
||||||
t.Traverse()
|
t.Traverse()
|
||||||
|
|
||||||
k := 6
|
if val, err := t.Search("6"); err != nil {
|
||||||
if t.Search(k) != nil {
|
|
||||||
fmt.Print("\nPresent")
|
|
||||||
} else {
|
|
||||||
fmt.Print("\nNot Present")
|
fmt.Print("\nNot Present")
|
||||||
|
} else {
|
||||||
|
fmt.Printf("\nPresent: value '%s'", val)
|
||||||
}
|
}
|
||||||
|
|
||||||
k = 15
|
if val, err := t.Search("15"); err != nil {
|
||||||
if t.Search(k) != nil {
|
|
||||||
fmt.Print("\nPresent")
|
|
||||||
} else {
|
|
||||||
fmt.Print("\nNot Present")
|
fmt.Print("\nNot Present")
|
||||||
|
} else {
|
||||||
|
fmt.Printf("\nPresent: value '%s'", val)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user