1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
| /**
* 插入键值对
*/
public V put(K key, V value) {
if (key == null) {
throw new IllegalArgumentException("键不能为null");
}
LeafNode<K, V> leaf = findLeafNode(key);
V oldValue = null;
// 检查键是否已存在
int index = leaf.findKeyIndex(key);
if (index < leaf.keyCount && leaf.keys[index].equals(key)) {
oldValue = leaf.getValue(index);
leaf.setValue(index, value);
return oldValue;
}
// 尝试在叶子节点中插入
if (leaf.insertKeyValue(key, value)) {
size++;
return null;
}
// 叶子节点已满,需要分裂
splitLeafNode(leaf, key, value);
size++;
return null;
}
/**
* 分裂叶子节点
*/
private void splitLeafNode(LeafNode<K, V> leaf, K key, V value) {
// 创建新的叶子节点
LeafNode<K, V> newLeaf = new LeafNode<>(order);
// 临时数组存储所有键值对
int totalKeys = leaf.keyCount + 1;
@SuppressWarnings("unchecked")
K[] tempKeys = (K[]) new Comparable[totalKeys];
@SuppressWarnings("unchecked")
V[] tempValues = (V[]) new Object[totalKeys];
// 合并原有键值对和新键值对
int insertIndex = leaf.findKeyIndex(key);
int tempIndex = 0;
for (int i = 0; i < leaf.keyCount; i++) {
if (i == insertIndex) {
tempKeys[tempIndex] = key;
tempValues[tempIndex] = value;
tempIndex++;
}
tempKeys[tempIndex] = leaf.keys[i];
tempValues[tempIndex] = leaf.getValue(i);
tempIndex++;
}
if (insertIndex == leaf.keyCount) {
tempKeys[tempIndex] = key;
tempValues[tempIndex] = value;
}
// 分割键值对
int mid = totalKeys / 2;
// 清空原叶子节点
leaf.keyCount = 0;
for (int i = 0; i < mid; i++) {
leaf.keys[i] = tempKeys[i];
leaf.setValue(i, tempValues[i]);
leaf.keyCount++;
}
// 填充新叶子节点
for (int i = mid; i < totalKeys; i++) {
newLeaf.keys[i - mid] = tempKeys[i];
newLeaf.setValue(i - mid, tempValues[i]);
newLeaf.keyCount++;
}
// 更新叶子节点链表
newLeaf.setNext(leaf.getNext());
leaf.setNext(newLeaf);
// 获取要上升到父节点的键
K promotedKey = newLeaf.keys[0];
// 如果当前叶子节点是根节点,创建新的根节点
if (leaf.parent == null) {
InternalNode<K, V> newRoot = new InternalNode<>(order);
newRoot.keys[0] = promotedKey;
newRoot.setChild(0, leaf);
newRoot.setChild(1, newLeaf);
newRoot.keyCount = 1;
root = newRoot;
} else {
// 在父节点中插入提升的键
insertIntoParent(leaf.parent, promotedKey, newLeaf);
}
}
/**
* 在父节点中插入键和子节点
*/
private void insertIntoParent(InternalNode<K, V> parent, K key, Node<K, V> rightChild) {
// 如果父节点未满,直接插入
if (!parent.isFull()) {
int index = parent.findKeyIndex(key);
parent.insertKeyAndChild(key, rightChild, index);
return;
}
// 父节点已满,需要分裂
splitInternalNode(parent, key, rightChild);
}
/**
* 分裂内部节点
*/
private void splitInternalNode(InternalNode<K, V> internal, K key, Node<K, V> rightChild) {
// 创建新的内部节点
InternalNode<K, V> newInternal = new InternalNode<>(order);
// 临时数组存储所有键和子节点
int totalKeys = internal.keyCount + 1;
@SuppressWarnings("unchecked")
K[] tempKeys = (K[]) new Comparable[totalKeys];
@SuppressWarnings("unchecked")
Node<K, V>[] tempChildren = new Node[totalKeys + 1];
// 找到插入位置
int insertIndex = internal.findKeyIndex(key);
// 复制键
System.arraycopy(internal.keys, 0, tempKeys, 0, insertIndex);
tempKeys[insertIndex] = key;
System.arraycopy(internal.keys, insertIndex, tempKeys, insertIndex + 1,
internal.keyCount - insertIndex);
// 复制子节点
System.arraycopy(internal.children, 0, tempChildren, 0, insertIndex + 1);
tempChildren[insertIndex + 1] = rightChild;
System.arraycopy(internal.children, insertIndex + 1, tempChildren, insertIndex + 2,
internal.keyCount - insertIndex);
// 计算分割点
int mid = totalKeys / 2;
K promotedKey = tempKeys[mid];
// 清空原内部节点
internal.keyCount = 0;
// 重新分配键和子节点
for (int i = 0; i < mid; i++) {
internal.keys[i] = tempKeys[i];
internal.setChild(i, tempChildren[i]);
internal.keyCount++;
}
internal.setChild(mid, tempChildren[mid]);
// 填充新内部节点
for (int i = mid + 1; i < totalKeys; i++) {
newInternal.keys[i - mid - 1] = tempKeys[i];
newInternal.setChild(i - mid - 1, tempChildren[i]);
newInternal.keyCount++;
}
newInternal.setChild(newInternal.keyCount, tempChildren[totalKeys]);
// 如果当前内部节点是根节点,创建新的根节点
if (internal.parent == null) {
InternalNode<K, V> newRoot = new InternalNode<>(order);
newRoot.keys[0] = promotedKey;
newRoot.setChild(0, internal);
newRoot.setChild(1, newInternal);
newRoot.keyCount = 1;
root = newRoot;
} else {
// 在父节点中插入提升的键
insertIntoParent(internal.parent, promotedKey, newInternal);
}
}
|