btree: avoid duplication of keys
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
d99fc856c3
commit
d8313c758e
@ -86,7 +86,11 @@ func (t *Tree) Search(k string) (string, error) {
|
|||||||
return "", fmt.Errorf("The key %s does not exist", k)
|
return "", fmt.Errorf("The key %s does not exist", k)
|
||||||
}
|
}
|
||||||
|
|
||||||
return t.root.search(&data{key: k})
|
if n, i := t.root.search(&data{key: k}); n != nil {
|
||||||
|
return n.keys[i].value, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return "", fmt.Errorf("The key %s does not exist", k)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove k in the tree
|
// Remove k in the tree
|
||||||
@ -123,11 +127,17 @@ 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.degree, true)
|
t.root = newNode(t.degree, true)
|
||||||
t.root.insertKey(0, k)
|
t.root.writeKey(0, k)
|
||||||
t.root.numberOfKeys = 1
|
t.root.numberOfKeys = 1
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Search for an existing key and replace it
|
||||||
|
if node, i := t.root.search(k); node != nil {
|
||||||
|
node.writeKey(i, k)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
// If the tree is not empty
|
// If the tree is not empty
|
||||||
if !t.root.isFull() {
|
if !t.root.isFull() {
|
||||||
// If root is not full, insert in non full root
|
// If root is not full, insert in non full root
|
||||||
@ -158,8 +168,8 @@ func (t *Tree) Insert(key, value string) {
|
|||||||
|
|
||||||
// node methods
|
// node methods
|
||||||
|
|
||||||
// insertKey at i place in the node
|
// writeKey at i place in the node
|
||||||
func (n *node) insertKey(i int, k *data) {
|
func (n *node) writeKey(i int, k *data) {
|
||||||
n.keys[i] = k
|
n.keys[i] = k
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -192,7 +202,7 @@ func (n *node) visualize(prefix string, isEnd bool) {
|
|||||||
// 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, traverse trough n keys and n first children
|
||||||
for i := 0; i < n.numberOfKeys; i++ {
|
for i := 0; i < n.numberOfKeys; i++ {
|
||||||
// If this is not a leaf, then traverse the subtree before printing the key
|
// If this is not a leaf, then traverse the subtree before printing the key
|
||||||
if !n.isLeaf {
|
if !n.isLeaf {
|
||||||
@ -208,7 +218,7 @@ 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 *data) (string, error) {
|
func (n *node) search(k *data) (*node, int) {
|
||||||
|
|
||||||
// Find the first entry greater than or equal to k
|
// Find the first entry greater than or equal to k
|
||||||
i := 0
|
i := 0
|
||||||
@ -217,16 +227,16 @@ func (n *node) search(k *data) (string, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// If the found key is equal to k, return this node
|
// If the found key is equal to k, return this node
|
||||||
if n.keys[i] != nil && k.eq(n.keys[i]) {
|
if i < n.numberOfKeys && k.eq(n.keys[i]) {
|
||||||
return n.keys[i].value, nil
|
return n, i
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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 "", fmt.Errorf("The key %s does not exist", k.key)
|
return nil, -1
|
||||||
}
|
}
|
||||||
|
|
||||||
// Go to the approipriate child
|
// Go to the appropriate child
|
||||||
return n.children[i].search(k)
|
return n.children[i].search(k)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -249,24 +259,24 @@ func (n *node) insertNonFull(k *data) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Insert the new key at the found location
|
// Insert the new key at the found location
|
||||||
n.insertKey(i+1, k)
|
n.writeKey(i+1, k)
|
||||||
n.numberOfKeys++
|
n.numberOfKeys++
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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 which is going to have the new key
|
||||||
for i >= 0 && n.keys[i].gt(k) {
|
for i >= 0 && n.keys[i].gt(k) {
|
||||||
i--
|
i--
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if the found chird is full
|
// Check if the found child is full
|
||||||
if n.children[i+1].isFull() {
|
if n.children[i+1].isFull() {
|
||||||
// If the child is full, then split it
|
// If the child is full, then split it
|
||||||
n.splitChild(i+1, n.children[i+1])
|
n.splitChild(i+1, n.children[i+1])
|
||||||
|
|
||||||
// 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 splited 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].lt(k) {
|
if n.keys[i+1].lt(k) {
|
||||||
i++
|
i++
|
||||||
@ -352,7 +362,7 @@ func (n *node) remove(k *data) error {
|
|||||||
isInLastChild = true
|
isInLastChild = true
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the child where is the key has less than t keys, wi fill it
|
// If the child where is the key has less than t keys, we fill it
|
||||||
if n.children[index].numberOfKeys < n.degree {
|
if n.children[index].numberOfKeys < n.degree {
|
||||||
n.fill(index)
|
n.fill(index)
|
||||||
}
|
}
|
||||||
|
@ -84,7 +84,7 @@ func ExampleTree_Traverse() {
|
|||||||
tree := NewBtree(3)
|
tree := NewBtree(3)
|
||||||
|
|
||||||
toInsert := [][]string{
|
toInsert := [][]string{
|
||||||
[]string{"a", "A"},
|
[]string{"a", "C"},
|
||||||
[]string{"b", "B"},
|
[]string{"b", "B"},
|
||||||
[]string{"c", "C"},
|
[]string{"c", "C"},
|
||||||
[]string{"d", "D"},
|
[]string{"d", "D"},
|
||||||
@ -106,6 +106,8 @@ func ExampleTree_Traverse() {
|
|||||||
tree.Insert(k[0], k[1])
|
tree.Insert(k[0], k[1])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tree.Insert("a", "A")
|
||||||
|
|
||||||
tree.Visualize()
|
tree.Visualize()
|
||||||
fmt.Println("")
|
fmt.Println("")
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user