luoheng
8/10/2019 - 1:31 PM

B树(待debug)

// BNode for BTree
type BNode struct {
	n    int // number of keys
	keys []rune
	leaf bool     // leaf or not
	c    []*BNode // children (n+1)
}

// BTree is b tree
type BTree struct {
	root *BNode
	t    int
}

func diskRead(x *BNode, c *BNode) {}
func diskWrite(x *BNode)          {}

// CreateNode return a node
func (b *BTree) CreateNode() *BNode {
	return &BNode{
		n:    0,
		keys: make([]rune, 2*b.t-1),
		leaf: true,
		c:    make([]*BNode, 2*b.t),
	}
}

// CreateTree returns a BTree
func CreateTree(t int) BTree {
	b := BTree{}
	b.t = t
	b.root = b.CreateNode()
	return b
}

// Search for keys
func (b *BTree) Search(x *BNode, k rune) (*BNode, rune) {
	i := 0
	for i = 0; i < x.n && k > x.keys[i]; i++ {
	}
	if i < x.n && k == x.keys[i] {
		return x, x.keys[i]
	} else if x.leaf {
		return nil, 0
	}
	diskRead(x, x.c[i])
	return b.Search(x.c[i], k)
}

func (b *BTree) splitChild(x *BNode, i int) {
	y := x.c[i]
	z := b.CreateNode()
	copy(z.keys, y.keys[b.t:y.n])
	if !y.leaf {
		copy(z.c, y.c[b.t:y.n+1])
	}
	z.n = b.t - 1
	y.n = b.t - 1
	x.n++
	copy(x.c[i+2:x.n+1], x.c[i+1:x.n])
	x.c[i+1] = z
	copy(x.keys[i+1:x.n], x.keys[i:x.n-1])
	x.keys[i] = y.keys[y.n]
	diskWrite(y)
	diskWrite(z)
	diskWrite(x)
}

// Insert a node
func (b *BTree) Insert(k rune) {
	r := b.root
	if r.n == 2*b.t-1 {
		s := b.CreateNode()
		b.root = s
		s.c[0] = r
		s.leaf = false
		b.splitChild(s, 0)
		b.insertNotFull(s, k)
	} else {
		b.insertNotFull(r, k)
	}
}

func (b *BTree) insertNotFull(x *BNode, k rune) {
	i := x.n - 1
	if x.leaf {
		for i >= 0 && k < x.keys[i] {
			x.keys[i+1] = x.keys[i]
			i--
		}
		x.keys[i+1] = k
		x.n++
		diskWrite(x)
	} else {
		for i >= 0 && k < x.keys[i] {
			i--
		}
		i++
		diskRead(x, x.c[i])
		if x.c[i].n == 2*b.t-1 {
			b.splitChild(x, i)
			if k > x.keys[i] {
				i++
			}
		}
		b.insertNotFull(x.c[i], k)
	}
}

// Delete a node
func (b *BTree) Delete(x *BNode, k rune){
	i := 0
	for ; i < x.n; i++ {
		if x.keys[i] >= k {
			break
		}
	}
	if i < x.n && x.keys[i] == k {
		if x.leaf {
			copy(x.keys[i:], x.keys[i+1:])
			x.n--
		} else if x.c[i].n >= b.t {
			x.keys[i] = x.c[i].keys[x.c[i].n-1]
			b.Delete(x.c[i], x.keys[i])
		} else if x.c[i+1].n >= b.t {
			x.keys[i] = x.c[i+1].keys[0]
			b.Delete(x.c[i+1], x.keys[i])
		} else {
			x.c[i].keys[x.c[i].n] = x.keys[i]
			x.c[i].n++
			copy(x.c[i].keys[x.c[i].n:], x.c[i+1].keys[:x.c[i+1].n])
			x.c[i].n += x.c[i+1].n
			copy(x.c[i].c[x.n+1:], x.c[i+1].c[:x.c[i+1].n+1])
			copy(x.keys[i:], x.keys[i+1:])
			copy(x.c[i+1:], x.c[i+2:])
			x.n--
			b.Delete(x.c[i], k)
		}
	} else if i < x.n && x.keys[i] > k && !x.leaf {
		if x.c[i].n < b.t {
			x.c[i].keys[x.c[i].n] = x.keys[i]
			x.c[i].n++
			if x.c[i+1].n >= b.t {
				x.keys[i] = x.c[i+1].keys[0]
				x.c[i].c[x.c[i].n++] = x.c[i+1].c[0] 
				b.Delete(x.c[i+1], x.keys[i])
				b.Delete(x.c[i], k)
			} else {
				copy(x.c[i].keys[x.c[i].n:], x.c[i+1].keys[:x.c[i+1].n])
				x.c[i].n += x.c[i+1].n
				copy(x.c[i].c[x.n+1:], x.c[i+1].c[:x.c[i+1].n+1])
				copy(x.keys[i:], x.keys[i+1:])
				copy(x.c[i+1:], x.c[i+2:])
				x.n--
			}
		}
		b.Delete(x.c[i], k)
	}
	if x.n == 0 && x == b.root {
		b.root = x.c[0]
	}
}

func (b *BTree) inOrder(s *BNode) []rune {
	A := make([]rune, 0, 4)
	if s != nil {
		for i, key := range s.keys {
			if i < s.n {
				A = append(A, b.inOrder(s.c[i])...)
				A = append(A, key)
			}
		}
		A = append(A, b.inOrder(s.c[s.n])...)
	}
	return A
}