dataspace
/
node.go
149 строк · 3.1 Кб
1package dataspace
2
3type node struct {
4hash uint64 // хеш
5key []byte // ключ
6value []byte // значение
7element *element // элемент списка
8left *node // указатель на л. лист
9right *node // указатель на п. лист
10height int // ширина
11}
12
13// Метод ищет ноду по ключу.
14func (n *node) search(h uint64) *node {
15if n == nil {
16return nil
17}
18switch {
19case h < n.hash:
20return n.left.search(h)
21case h == n.hash:
22return n
23case h > n.hash:
24return n.right.search(h)
25}
26return nil
27}
28
29// Метод записывает ноду в дерево.
30func (n *node) add(h uint64, k, v []byte, e *element) *node {
31if n == nil {
32return &node{h, k, v, e, nil, nil, 1}
33}
34switch {
35case h < n.hash:
36n.left = n.left.add(h, k, v, e)
37case h == n.hash:
38n = &node{h, k, v, e, n.left, n.right, n.height}
39case h > n.hash:
40n.right = n.right.add(h, k, v, e)
41}
42return n.rebalance()
43}
44
45// Метод удаляет ноду из дерева.
46func (n *node) remove(h uint64) *node {
47if n == nil {
48return nil
49}
50switch {
51case h < n.hash:
52n.left = n.left.remove(h)
53case h == n.hash:
54switch {
55case n.left != nil && n.right != nil:
56r := n.right.findMinimalNode()
57n = &node{
58r.hash,
59r.key,
60r.value,
61r.element,
62n.left,
63n.right.remove(r.hash),
64n.height,
65}
66case n.left != nil:
67n = n.left
68case n.right != nil:
69n = n.right
70default:
71return nil
72}
73case h > n.hash:
74n.right = n.right.remove(h)
75}
76return n.rebalance()
77}
78
79// Метод ищет минимальную ноду в ветке.
80func (n *node) findMinimalNode() *node {
81if n.left == nil {
82return n
83}
84return n.left.findMinimalNode()
85}
86
87// Метод получает ширину ветви.
88func (n *node) getHeight() int {
89if n == nil {
90return 0
91}
92return n.height
93}
94
95// Метод устанавливает ширину ноды.
96func (n *node) setHeight() {
97n.height = 1 + max(n.left.getHeight(), n.right.getHeight())
98}
99
100// Метод поворачивает дерево влево.
101func (n *node) rotateLeft() *node {
102r := n.right
103n.right = r.left
104r.left = n
105n.setHeight()
106r.setHeight()
107return r
108}
109
110// Метод поворачивает дерево вправо.
111func (n *node) rotateRight() *node {
112l := n.left
113n.left = l.right
114l.right = n
115n.setHeight()
116l.setHeight()
117return l
118}
119
120// Метод балансирует дерево.
121func (n *node) rebalance() *node {
122if n == nil {
123return nil
124}
125n.setHeight()
126switch n.left.getHeight() - n.right.getHeight() {
127case -2:
128if n.right.left.getHeight() > n.right.right.getHeight() {
129n.right = n.right.rotateRight()
130}
131return n.rotateLeft()
132case 2:
133if n.left.right.getHeight() > n.left.left.getHeight() {
134n.left = n.left.rotateLeft()
135}
136return n.rotateRight()
137}
138return n
139}
140
141// Функция считает количество веток дерева.
142func countBranches(root *node) int64 {
143if root == nil {
144return 0
145}
146l := countBranches(root.left)
147r := countBranches(root.right)
148return max(l, r) + 1
149}
150