第7章 查找代码
使用建议
- 先配合对应章节阅读:第7章 查找 正文
- 这一页优先提供站内可直接查看的代码版本,适合网页阅读和搜索。
- 这一页主要用于网页阅读,建议结合对应正文与逐行注释版一起使用。
文件位置
- 普通代码版:
第7章普通代码版
- 逐行注释版:
第7章逐行注释版代码
- 兼容编码版:
第7章兼容编码版逐行注释代码
普通代码版
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_BLOCKS 10
#define MAX_HASH_SIZE 13
#define EMPTY_SLOT (-1)
/* 分块索引项:记录某一块的最大关键字,以及该块在原表中的起止下标。 */
typedef struct {
int max_key;
int start;
int end;
} BlockIndex;
/* 二叉排序树结点:key 保存关键字,left/right 分别指向左右子树。 */
typedef struct BSTNode {
int key;
struct BSTNode *left;
struct BSTNode *right;
} BSTNode;
/* AVL 结点:在 BST 结点基础上多维护一个高度字段。 */
typedef struct AVLNode {
int key;
int height;
struct AVLNode *left;
struct AVLNode *right;
} AVLNode;
typedef enum {
RB_RED,
RB_BLACK
} RBColor;
typedef struct RBNode {
int key;
RBColor color;
struct RBNode *left;
struct RBNode *right;
} RBNode;
#define BTREE_MIN_DEGREE 2
#define BTREE_MAX_KEYS (2 * BTREE_MIN_DEGREE - 1)
#define BTREE_MAX_CHILDREN (2 * BTREE_MIN_DEGREE)
typedef struct BTreeNode {
int key_count;
int keys[BTREE_MAX_KEYS];
bool leaf;
struct BTreeNode *children[BTREE_MAX_CHILDREN];
} BTreeNode;
typedef struct BPlusNode {
bool leaf;
int key_count;
int keys[BTREE_MAX_KEYS + 1];
struct BPlusNode *children[BTREE_MAX_CHILDREN + 1];
struct BPlusNode *next;
} BPlusNode;
/* 开放定址散列表:data 存关键字,occupied 表示是否曾经占用,deleted 表示逻辑删除。 */
typedef struct {
int data[MAX_HASH_SIZE];
bool occupied[MAX_HASH_SIZE];
bool deleted[MAX_HASH_SIZE];
} HashOpenTable;
/* 拉链法结点:key 存关键字,next 指向同义词链上的下一个结点。 */
typedef struct ChainNode {
int key;
struct ChainNode *next;
} ChainNode;
/* 拉链法散列表:buckets 中每个桶都是一个链表头指针。 */
typedef struct {
ChainNode *buckets[MAX_HASH_SIZE];
} ChainHashTable;
/* 顺序查找:从头到尾逐个比较,找到目标就返回下标,否则返回 -1。 */
int SeqSearch(const int *array, int length, int target) {
int i;
if (array == NULL || length <= 0) {
return -1;
}
for (i = 0; i < length; i++) {
if (array[i] == target) {
return i;
}
}
return -1;
}
/* 折半查找非递归版:要求数组有序,通过不断缩小区间定位目标。 */
int BinarySearchIter(const int *array, int length, int target) {
int low;
int high;
int mid;
if (array == NULL || length <= 0) {
return -1;
}
low = 0;
high = length - 1;
while (low <= high) {
mid = low + (high - low) / 2;
if (array[mid] == target) {
return mid;
}
if (array[mid] < target) {
low = mid + 1;
} else {
high = mid - 1;
}
}
return -1;
}
/* 折半查找递归版:逻辑和非递归版一致,只是把“缩区间”交给递归。 */
int BinarySearchRecursive(const int *array, int low, int high, int target) {
int mid;
if (array == NULL || low > high) {
return -1;
}
mid = low + (high - low) / 2;
if (array[mid] == target) {
return mid;
}
if (array[mid] < target) {
return BinarySearchRecursive(array, mid + 1, high, target);
}
return BinarySearchRecursive(array, low, mid - 1, target);
}
/* 分块查找:先扫描索引块,再在目标块内部顺序查找。 */
int BlockSearch(const int *array, int length, const BlockIndex *index, int block_count, int target) {
int i;
int start;
int end;
if (array == NULL || index == NULL || length <= 0 || block_count <= 0) {
return -1;
}
for (i = 0; i < block_count; i++) {
if (target <= index[i].max_key) {
start = index[i].start;
end = index[i].end;
if (start < 0) {
start = 0;
}
if (end >= length) {
end = length - 1;
}
for (; start <= end; start++) {
if (array[start] == target) {
return start;
}
}
return -1;
}
}
return -1;
}
/* 创建 BST 结点:后续插入、删除都基于这个基础构造函数。 */
BSTNode *CreateBSTNode(int key) {
BSTNode *node;
node = (BSTNode *)malloc(sizeof(BSTNode));
if (node == NULL) {
return NULL;
}
node->key = key;
node->left = NULL;
node->right = NULL;
return node;
}
/* BST 查找:小了往左,大了往右,相等就返回当前结点。 */
BSTNode *BSTSearch(BSTNode *root, int key) {
BSTNode *current;
current = root;
while (current != NULL) {
if (key == current->key) {
return current;
}
if (key < current->key) {
current = current->left;
} else {
current = current->right;
}
}
return NULL;
}
/* BST 插入:找到空位置后挂上新结点,重复关键字不再插入。 */
BSTNode *BSTInsert(BSTNode *root, int key) {
if (root == NULL) {
return CreateBSTNode(key);
}
if (key < root->key) {
root->left = BSTInsert(root->left, key);
} else if (key > root->key) {
root->right = BSTInsert(root->right, key);
}
return root;
}
/* 找 BST 中的最小结点:一路向左走到尽头。 */
BSTNode *BSTFindMin(BSTNode *root) {
BSTNode *current;
current = root;
if (current == NULL) {
return NULL;
}
while (current->left != NULL) {
current = current->left;
}
return current;
}
/* BST 删除:分叶子、单孩子、双孩子三种情况处理。 */
BSTNode *BSTDelete(BSTNode *root, int key) {
BSTNode *successor;
if (root == NULL) {
return NULL;
}
if (key < root->key) {
root->left = BSTDelete(root->left, key);
return root;
}
if (key > root->key) {
root->right = BSTDelete(root->right, key);
return root;
}
if (root->left == NULL && root->right == NULL) {
free(root);
return NULL;
}
if (root->left == NULL) {
BSTNode *right_child;
right_child = root->right;
free(root);
return right_child;
}
if (root->right == NULL) {
BSTNode *left_child;
left_child = root->left;
free(root);
return left_child;
}
successor = BSTFindMin(root->right);
root->key = successor->key;
root->right = BSTDelete(root->right, successor->key);
return root;
}
/* 中序遍历 BST:可以直接验证 BST 输出是否递增有序。 */
void BSTInorder(const BSTNode *root) {
if (root == NULL) {
return;
}
BSTInorder(root->left);
printf("%d ", root->key);
BSTInorder(root->right);
}
/* 释放 BST:后序递归释放整棵树,避免内存泄漏。 */
void DestroyBST(BSTNode *root) {
if (root == NULL) {
return;
}
DestroyBST(root->left);
DestroyBST(root->right);
free(root);
}
/* 取 AVL 结点高度:空树高度记为 0。 */
int AVLHeight(const AVLNode *node) {
if (node == NULL) {
return 0;
}
return node->height;
}
/* 求两个整数的较大值:更新 AVL 高度时会用到。 */
int MaxInt(int a, int b) {
return a > b ? a : b;
}
/* 创建 AVL 结点:默认作为叶子结点,高度初始化为 1。 */
AVLNode *CreateAVLNode(int key) {
AVLNode *node;
node = (AVLNode *)malloc(sizeof(AVLNode));
if (node == NULL) {
return NULL;
}
node->key = key;
node->height = 1;
node->left = NULL;
node->right = NULL;
return node;
}
/* 更新 AVL 结点高度:左右子树较高者加 1。 */
void UpdateAVLHeight(AVLNode *node) {
if (node == NULL) {
return;
}
node->height = MaxInt(AVLHeight(node->left), AVLHeight(node->right)) + 1;
}
/* 计算 AVL 平衡因子:左高减右高。 */
int GetBalanceFactor(const AVLNode *node) {
if (node == NULL) {
return 0;
}
return AVLHeight(node->left) - AVLHeight(node->right);
}
/* 右旋:修复 LL 型失衡,也可作为 LR 调整中的第二步。 */
AVLNode *RotateRight(AVLNode *y) {
AVLNode *x;
AVLNode *t2;
if (y == NULL || y->left == NULL) {
return y;
}
x = y->left;
t2 = x->right;
x->right = y;
y->left = t2;
UpdateAVLHeight(y);
UpdateAVLHeight(x);
return x;
}
/* 左旋:修复 RR 型失衡,也可作为 RL 调整中的第二步。 */
AVLNode *RotateLeft(AVLNode *x) {
AVLNode *y;
AVLNode *t2;
if (x == NULL || x->right == NULL) {
return x;
}
y = x->right;
t2 = y->left;
y->left = x;
x->right = t2;
UpdateAVLHeight(x);
UpdateAVLHeight(y);
return y;
}
/* AVL 插入:先按 BST 插入,再根据失衡类型旋转恢复平衡。 */
AVLNode *AVLInsert(AVLNode *node, int key) {
int balance;
if (node == NULL) {
return CreateAVLNode(key);
}
if (key < node->key) {
node->left = AVLInsert(node->left, key);
} else if (key > node->key) {
node->right = AVLInsert(node->right, key);
} else {
return node;
}
UpdateAVLHeight(node);
balance = GetBalanceFactor(node);
if (balance > 1 && key < node->left->key) {
return RotateRight(node);
}
if (balance < -1 && key > node->right->key) {
return RotateLeft(node);
}
if (balance > 1 && key > node->left->key) {
node->left = RotateLeft(node->left);
return RotateRight(node);
}
if (balance < -1 && key < node->right->key) {
node->right = RotateRight(node->right);
return RotateLeft(node);
}
return node;
}
/* AVL 查找:查找路径和 BST 相同,只是树更不容易退化。 */
AVLNode *AVLSearch(AVLNode *root, int key) {
AVLNode *current;
current = root;
while (current != NULL) {
if (key == current->key) {
return current;
}
if (key < current->key) {
current = current->left;
} else {
current = current->right;
}
}
return NULL;
}
/* AVL 先序遍历:便于观察旋转后根和子树位置的变化。 */
void AVLPreorder(const AVLNode *root) {
if (root == NULL) {
return;
}
printf("%d ", root->key);
AVLPreorder(root->left);
AVLPreorder(root->right);
}
/* 释放 AVL:和 BST 一样做后序释放。 */
void DestroyAVL(AVLNode *root) {
if (root == NULL) {
return;
}
DestroyAVL(root->left);
DestroyAVL(root->right);
free(root);
}
bool IsRedRB(const RBNode *node) {
return node != NULL && node->color == RB_RED;
}
RBNode *CreateRBNode(int key) {
RBNode *node;
node = (RBNode *)malloc(sizeof(RBNode));
if (node == NULL) {
return NULL;
}
node->key = key;
node->color = RB_RED;
node->left = NULL;
node->right = NULL;
return node;
}
RBNode *RBRotateLeft(RBNode *node) {
RBNode *right_child;
right_child = node->right;
node->right = right_child->left;
right_child->left = node;
right_child->color = node->color;
node->color = RB_RED;
return right_child;
}
RBNode *RBRotateRight(RBNode *node) {
RBNode *left_child;
left_child = node->left;
node->left = left_child->right;
left_child->right = node;
left_child->color = node->color;
node->color = RB_RED;
return left_child;
}
void RBFlipColors(RBNode *node) {
if (node == NULL || node->left == NULL || node->right == NULL) {
return;
}
node->color = node->color == RB_RED ? RB_BLACK : RB_RED;
node->left->color = node->left->color == RB_RED ? RB_BLACK : RB_RED;
node->right->color = node->right->color == RB_RED ? RB_BLACK : RB_RED;
}
RBNode *RBInsert(RBNode *root, int key) {
if (root == NULL) {
return CreateRBNode(key);
}
if (key < root->key) {
root->left = RBInsert(root->left, key);
} else if (key > root->key) {
root->right = RBInsert(root->right, key);
}
if (IsRedRB(root->right) && !IsRedRB(root->left)) {
root = RBRotateLeft(root);
}
if (IsRedRB(root->left) && IsRedRB(root->left->left)) {
root = RBRotateRight(root);
}
if (IsRedRB(root->left) && IsRedRB(root->right)) {
RBFlipColors(root);
}
return root;
}
RBNode *RBSearch(RBNode *root, int key) {
RBNode *current;
current = root;
while (current != NULL) {
if (key == current->key) {
return current;
}
if (key < current->key) {
current = current->left;
} else {
current = current->right;
}
}
return NULL;
}
RBNode *RBMoveRedLeft(RBNode *node) {
RBFlipColors(node);
if (node->right != NULL && IsRedRB(node->right->left)) {
node->right = RBRotateRight(node->right);
node = RBRotateLeft(node);
RBFlipColors(node);
}
return node;
}
RBNode *RBMoveRedRight(RBNode *node) {
RBFlipColors(node);
if (node->left != NULL && IsRedRB(node->left->left)) {
node = RBRotateRight(node);
RBFlipColors(node);
}
return node;
}
RBNode *RBFixUp(RBNode *node) {
if (node == NULL) {
return NULL;
}
if (IsRedRB(node->right)) {
node = RBRotateLeft(node);
}
if (IsRedRB(node->left) && IsRedRB(node->left->left)) {
node = RBRotateRight(node);
}
if (IsRedRB(node->left) && IsRedRB(node->right)) {
RBFlipColors(node);
}
return node;
}
RBNode *RBMin(RBNode *node) {
RBNode *current;
current = node;
while (current != NULL && current->left != NULL) {
current = current->left;
}
return current;
}
RBNode *RBDeleteMin(RBNode *node) {
if (node == NULL) {
return NULL;
}
if (node->left == NULL) {
free(node);
return NULL;
}
if (!IsRedRB(node->left) && !IsRedRB(node->left->left)) {
node = RBMoveRedLeft(node);
}
node->left = RBDeleteMin(node->left);
return RBFixUp(node);
}
RBNode *RBDelete(RBNode *node, int key) {
RBNode *min_node;
if (node == NULL) {
return NULL;
}
if (key < node->key) {
if (node->left != NULL) {
if (!IsRedRB(node->left) && !IsRedRB(node->left->left)) {
node = RBMoveRedLeft(node);
}
node->left = RBDelete(node->left, key);
}
} else {
if (IsRedRB(node->left)) {
node = RBRotateRight(node);
}
if (key == node->key && node->right == NULL) {
free(node);
return NULL;
}
if (node->right != NULL) {
if (!IsRedRB(node->right) && !IsRedRB(node->right->left)) {
node = RBMoveRedRight(node);
}
if (key == node->key) {
min_node = RBMin(node->right);
if (min_node != NULL) {
node->key = min_node->key;
}
node->right = RBDeleteMin(node->right);
} else {
node->right = RBDelete(node->right, key);
}
}
}
return RBFixUp(node);
}
void RBInorder(const RBNode *root) {
if (root == NULL) {
return;
}
RBInorder(root->left);
printf("%d(%c) ", root->key, root->color == RB_RED ? 'R' : 'B');
RBInorder(root->right);
}
void DestroyRB(RBNode *root) {
if (root == NULL) {
return;
}
DestroyRB(root->left);
DestroyRB(root->right);
free(root);
}
BTreeNode *CreateBTreeNode(bool leaf) {
BTreeNode *node;
int i;
node = (BTreeNode *)malloc(sizeof(BTreeNode));
if (node == NULL) {
return NULL;
}
node->key_count = 0;
node->leaf = leaf;
for (i = 0; i < BTREE_MAX_CHILDREN; i++) {
node->children[i] = NULL;
}
return node;
}
BTreeNode *BTreeSearch(BTreeNode *root, int key, int *index) {
int i;
if (root == NULL) {
return NULL;
}
i = 0;
while (i < root->key_count && key > root->keys[i]) {
i++;
}
if (i < root->key_count && key == root->keys[i]) {
if (index != NULL) {
*index = i;
}
return root;
}
if (root->leaf) {
return NULL;
}
return BTreeSearch(root->children[i], key, index);
}
void BTreeSplitChild(BTreeNode *parent, int child_index) {
BTreeNode *full_child;
BTreeNode *new_child;
int i;
full_child = parent->children[child_index];
new_child = CreateBTreeNode(full_child->leaf);
if (new_child == NULL) {
return;
}
new_child->key_count = BTREE_MIN_DEGREE - 1;
for (i = 0; i < BTREE_MIN_DEGREE - 1; i++) {
new_child->keys[i] = full_child->keys[i + BTREE_MIN_DEGREE];
}
if (!full_child->leaf) {
for (i = 0; i < BTREE_MIN_DEGREE; i++) {
new_child->children[i] = full_child->children[i + BTREE_MIN_DEGREE];
}
}
full_child->key_count = BTREE_MIN_DEGREE - 1;
for (i = parent->key_count; i >= child_index + 1; i--) {
parent->children[i + 1] = parent->children[i];
}
parent->children[child_index + 1] = new_child;
for (i = parent->key_count - 1; i >= child_index; i--) {
parent->keys[i + 1] = parent->keys[i];
}
parent->keys[child_index] = full_child->keys[BTREE_MIN_DEGREE - 1];
parent->key_count++;
}
void BTreeInsertNonFull(BTreeNode *node, int key) {
int i;
i = node->key_count - 1;
if (node->leaf) {
while (i >= 0 && key < node->keys[i]) {
node->keys[i + 1] = node->keys[i];
i--;
}
node->keys[i + 1] = key;
node->key_count++;
return;
}
while (i >= 0 && key < node->keys[i]) {
i--;
}
i++;
if (node->children[i] != NULL && node->children[i]->key_count == BTREE_MAX_KEYS) {
BTreeSplitChild(node, i);
if (key > node->keys[i]) {
i++;
}
}
BTreeInsertNonFull(node->children[i], key);
}
BTreeNode *BTreeInsert(BTreeNode *root, int key) {
BTreeNode *new_root;
if (root == NULL) {
root = CreateBTreeNode(true);
if (root == NULL) {
return NULL;
}
root->keys[0] = key;
root->key_count = 1;
return root;
}
if (root->key_count == BTREE_MAX_KEYS) {
new_root = CreateBTreeNode(false);
if (new_root == NULL) {
return root;
}
new_root->children[0] = root;
BTreeSplitChild(new_root, 0);
BTreeInsertNonFull(new_root, key);
return new_root;
}
BTreeInsertNonFull(root, key);
return root;
}
int BTreeFindKey(const BTreeNode *node, int key) {
int index;
index = 0;
while (index < node->key_count && node->keys[index] < key) {
index++;
}
return index;
}
int BTreeGetPredecessor(BTreeNode *node) {
BTreeNode *current;
current = node;
while (!current->leaf) {
current = current->children[current->key_count];
}
return current->keys[current->key_count - 1];
}
int BTreeGetSuccessor(BTreeNode *node) {
BTreeNode *current;
current = node;
while (!current->leaf) {
current = current->children[0];
}
return current->keys[0];
}
void BTreeMergeChildren(BTreeNode *node, int index) {
BTreeNode *left_child;
BTreeNode *right_child;
int i;
left_child = node->children[index];
right_child = node->children[index + 1];
if (left_child == NULL || right_child == NULL) {
return;
}
left_child->keys[BTREE_MIN_DEGREE - 1] = node->keys[index];
for (i = 0; i < right_child->key_count; i++) {
left_child->keys[i + BTREE_MIN_DEGREE] = right_child->keys[i];
}
if (!left_child->leaf) {
for (i = 0; i <= right_child->key_count; i++) {
left_child->children[i + BTREE_MIN_DEGREE] = right_child->children[i];
}
}
left_child->key_count += right_child->key_count + 1;
for (i = index + 1; i < node->key_count; i++) {
node->keys[i - 1] = node->keys[i];
}
for (i = index + 2; i <= node->key_count; i++) {
node->children[i - 1] = node->children[i];
}
node->key_count--;
free(right_child);
}
void BTreeBorrowFromPrev(BTreeNode *node, int index) {
BTreeNode *child;
BTreeNode *sibling;
int i;
child = node->children[index];
sibling = node->children[index - 1];
if (child == NULL || sibling == NULL) {
return;
}
for (i = child->key_count - 1; i >= 0; i--) {
child->keys[i + 1] = child->keys[i];
}
if (!child->leaf) {
for (i = child->key_count; i >= 0; i--) {
child->children[i + 1] = child->children[i];
}
}
child->keys[0] = node->keys[index - 1];
if (!child->leaf) {
child->children[0] = sibling->children[sibling->key_count];
}
node->keys[index - 1] = sibling->keys[sibling->key_count - 1];
child->key_count++;
sibling->key_count--;
}
void BTreeBorrowFromNext(BTreeNode *node, int index) {
BTreeNode *child;
BTreeNode *sibling;
int i;
child = node->children[index];
sibling = node->children[index + 1];
if (child == NULL || sibling == NULL) {
return;
}
child->keys[child->key_count] = node->keys[index];
if (!child->leaf) {
child->children[child->key_count + 1] = sibling->children[0];
}
node->keys[index] = sibling->keys[0];
for (i = 1; i < sibling->key_count; i++) {
sibling->keys[i - 1] = sibling->keys[i];
}
if (!sibling->leaf) {
for (i = 1; i <= sibling->key_count; i++) {
sibling->children[i - 1] = sibling->children[i];
}
}
child->key_count++;
sibling->key_count--;
}
void BTreeFillChild(BTreeNode *node, int index) {
if (index > 0 && node->children[index - 1] != NULL &&
node->children[index - 1]->key_count >= BTREE_MIN_DEGREE) {
BTreeBorrowFromPrev(node, index);
} else if (index < node->key_count && node->children[index + 1] != NULL &&
node->children[index + 1]->key_count >= BTREE_MIN_DEGREE) {
BTreeBorrowFromNext(node, index);
} else if (index < node->key_count) {
BTreeMergeChildren(node, index);
} else {
BTreeMergeChildren(node, index - 1);
}
}
void BTreeDeleteFromNode(BTreeNode *node, int key) {
int index;
int predecessor;
int successor;
bool at_end;
if (node == NULL) {
return;
}
index = BTreeFindKey(node, key);
if (index < node->key_count && node->keys[index] == key) {
if (node->leaf) {
for (; index + 1 < node->key_count; index++) {
node->keys[index] = node->keys[index + 1];
}
node->key_count--;
return;
}
if (node->children[index] != NULL &&
node->children[index]->key_count >= BTREE_MIN_DEGREE) {
predecessor = BTreeGetPredecessor(node->children[index]);
node->keys[index] = predecessor;
BTreeDeleteFromNode(node->children[index], predecessor);
} else if (node->children[index + 1] != NULL &&
node->children[index + 1]->key_count >= BTREE_MIN_DEGREE) {
successor = BTreeGetSuccessor(node->children[index + 1]);
node->keys[index] = successor;
BTreeDeleteFromNode(node->children[index + 1], successor);
} else {
BTreeMergeChildren(node, index);
BTreeDeleteFromNode(node->children[index], key);
}
return;
}
if (node->leaf) {
return;
}
at_end = index == node->key_count;
if (node->children[index] != NULL &&
node->children[index]->key_count < BTREE_MIN_DEGREE) {
BTreeFillChild(node, index);
}
if (at_end && index > node->key_count) {
BTreeDeleteFromNode(node->children[index - 1], key);
} else {
BTreeDeleteFromNode(node->children[index], key);
}
}
BTreeNode *BTreeDelete(BTreeNode *root, int key) {
BTreeNode *new_root;
if (root == NULL) {
return NULL;
}
BTreeDeleteFromNode(root, key);
if (root->key_count > 0) {
return root;
}
if (root->leaf) {
free(root);
return NULL;
}
new_root = root->children[0];
free(root);
return new_root;
}
void BTreePrint(const BTreeNode *root, int depth) {
int i;
if (root == NULL) {
return;
}
for (i = 0; i < depth; i++) {
printf(" ");
}
printf("[");
for (i = 0; i < root->key_count; i++) {
printf("%d", root->keys[i]);
if (i + 1 < root->key_count) {
printf(" ");
}
}
printf("]\n");
if (!root->leaf) {
for (i = 0; i <= root->key_count; i++) {
BTreePrint(root->children[i], depth + 1);
}
}
}
void DestroyBTree(BTreeNode *root) {
int i;
if (root == NULL) {
return;
}
if (!root->leaf) {
for (i = 0; i <= root->key_count; i++) {
DestroyBTree(root->children[i]);
}
}
free(root);
}
BPlusNode *CreateBPlusNode(bool leaf) {
BPlusNode *node;
int i;
node = (BPlusNode *)malloc(sizeof(BPlusNode));
if (node == NULL) {
return NULL;
}
node->leaf = leaf;
node->key_count = 0;
node->next = NULL;
for (i = 0; i < BTREE_MAX_CHILDREN + 1; i++) {
node->children[i] = NULL;
}
return node;
}
BPlusNode *BPlusFindLeaf(BPlusNode *root, int key);
int BPlusFirstKey(BPlusNode *node) {
BPlusNode *current;
current = node;
while (current != NULL && !current->leaf) {
current = current->children[0];
}
if (current == NULL || current->key_count == 0) {
return 0;
}
return current->keys[0];
}
void BPlusRefreshKeys(BPlusNode *node) {
int i;
if (node == NULL || node->leaf) {
return;
}
for (i = 1; i <= node->key_count; i++) {
node->keys[i - 1] = BPlusFirstKey(node->children[i]);
}
}
void BPlusInsertIntoLeaf(BPlusNode *leaf, int key) {
int i;
i = leaf->key_count - 1;
while (i >= 0 && key < leaf->keys[i]) {
leaf->keys[i + 1] = leaf->keys[i];
i--;
}
leaf->keys[i + 1] = key;
leaf->key_count++;
}
bool BPlusInsertRecursive(BPlusNode *node, int key, int *promoted_key, BPlusNode **new_child) {
int i;
int child_count;
int split_index;
int right_child_count;
BPlusNode *right_node;
int child_promoted_key;
BPlusNode *child_new_node;
if (node == NULL) {
return false;
}
if (node->leaf) {
for (i = 0; i < node->key_count; i++) {
if (node->keys[i] == key) {
return false;
}
}
BPlusInsertIntoLeaf(node, key);
if (node->key_count <= BTREE_MAX_KEYS) {
return false;
}
right_node = CreateBPlusNode(true);
if (right_node == NULL) {
return false;
}
split_index = (node->key_count + 1) / 2;
right_node->key_count = node->key_count - split_index;
for (i = 0; i < right_node->key_count; i++) {
right_node->keys[i] = node->keys[split_index + i];
}
node->key_count = split_index;
right_node->next = node->next;
node->next = right_node;
*promoted_key = right_node->keys[0];
*new_child = right_node;
return true;
}
i = 0;
while (i < node->key_count && key >= node->keys[i]) {
i++;
}
child_new_node = NULL;
child_promoted_key = 0;
if (BPlusInsertRecursive(node->children[i], key, &child_promoted_key, &child_new_node)) {
for (child_count = node->key_count; child_count >= i; child_count--) {
node->keys[child_count] = node->keys[child_count - 1];
}
for (child_count = node->key_count + 1; child_count >= i + 1; child_count--) {
node->children[child_count + 1] = node->children[child_count];
}
node->children[i + 1] = child_new_node;
node->key_count++;
BPlusRefreshKeys(node);
} else {
BPlusRefreshKeys(node);
return false;
}
if (node->key_count <= BTREE_MAX_KEYS) {
BPlusRefreshKeys(node);
return false;
}
right_node = CreateBPlusNode(false);
if (right_node == NULL) {
BPlusRefreshKeys(node);
return false;
}
child_count = node->key_count + 1;
split_index = 3;
right_child_count = child_count - split_index;
for (i = 0; i < right_child_count; i++) {
right_node->children[i] = node->children[split_index + i];
node->children[split_index + i] = NULL;
}
node->key_count = split_index - 1;
right_node->key_count = right_child_count - 1;
BPlusRefreshKeys(node);
BPlusRefreshKeys(right_node);
*promoted_key = BPlusFirstKey(right_node);
*new_child = right_node;
return true;
}
BPlusNode *BPlusInsert(BPlusNode *root, int key) {
int promoted_key;
BPlusNode *new_child;
BPlusNode *new_root;
if (root == NULL) {
root = CreateBPlusNode(true);
if (root == NULL) {
return NULL;
}
root->keys[0] = key;
root->key_count = 1;
return root;
}
new_child = NULL;
promoted_key = 0;
if (!BPlusInsertRecursive(root, key, &promoted_key, &new_child)) {
return root;
}
new_root = CreateBPlusNode(false);
if (new_root == NULL) {
return root;
}
new_root->children[0] = root;
new_root->children[1] = new_child;
new_root->key_count = 1;
new_root->keys[0] = promoted_key;
return new_root;
}
void BPlusBorrowFromPrev(BPlusNode *parent, int index) {
BPlusNode *child;
BPlusNode *sibling;
int i;
child = parent->children[index];
sibling = parent->children[index - 1];
if (child == NULL || sibling == NULL) {
return;
}
if (child->leaf) {
for (i = child->key_count; i > 0; i--) {
child->keys[i] = child->keys[i - 1];
}
child->keys[0] = sibling->keys[sibling->key_count - 1];
child->key_count++;
sibling->key_count--;
} else {
for (i = child->key_count; i >= 0; i--) {
child->children[i + 1] = child->children[i];
}
child->children[0] = sibling->children[sibling->key_count];
sibling->children[sibling->key_count] = NULL;
child->key_count++;
sibling->key_count--;
BPlusRefreshKeys(sibling);
BPlusRefreshKeys(child);
}
BPlusRefreshKeys(parent);
}
void BPlusBorrowFromNext(BPlusNode *parent, int index) {
BPlusNode *child;
BPlusNode *sibling;
int i;
child = parent->children[index];
sibling = parent->children[index + 1];
if (child == NULL || sibling == NULL) {
return;
}
if (child->leaf) {
child->keys[child->key_count] = sibling->keys[0];
child->key_count++;
for (i = 1; i < sibling->key_count; i++) {
sibling->keys[i - 1] = sibling->keys[i];
}
sibling->key_count--;
} else {
child->children[child->key_count + 1] = sibling->children[0];
child->key_count++;
for (i = 1; i <= sibling->key_count; i++) {
sibling->children[i - 1] = sibling->children[i];
}
sibling->children[sibling->key_count] = NULL;
sibling->key_count--;
BPlusRefreshKeys(child);
BPlusRefreshKeys(sibling);
}
BPlusRefreshKeys(parent);
}
void BPlusMergeChildren(BPlusNode *parent, int index) {
BPlusNode *left_child;
BPlusNode *right_child;
int left_child_count;
int right_child_count;
int i;
left_child = parent->children[index];
right_child = parent->children[index + 1];
if (left_child == NULL || right_child == NULL) {
return;
}
if (left_child->leaf) {
for (i = 0; i < right_child->key_count; i++) {
left_child->keys[left_child->key_count + i] = right_child->keys[i];
}
left_child->key_count += right_child->key_count;
left_child->next = right_child->next;
} else {
left_child_count = left_child->key_count + 1;
right_child_count = right_child->key_count + 1;
for (i = 0; i < right_child_count; i++) {
left_child->children[left_child_count + i] = right_child->children[i];
}
left_child->key_count = left_child_count + right_child_count - 1;
BPlusRefreshKeys(left_child);
}
for (i = index + 1; i < parent->key_count; i++) {
parent->children[i] = parent->children[i + 1];
}
parent->children[parent->key_count] = NULL;
parent->key_count--;
BPlusRefreshKeys(parent);
free(right_child);
}
bool BPlusDeleteRecursive(BPlusNode *node, int key) {
int index;
int i;
if (node == NULL) {
return false;
}
if (node->leaf) {
for (index = 0; index < node->key_count; index++) {
if (node->keys[index] == key) {
for (i = index + 1; i < node->key_count; i++) {
node->keys[i - 1] = node->keys[i];
}
node->key_count--;
return true;
}
}
return false;
}
index = 0;
while (index < node->key_count && key >= node->keys[index]) {
index++;
}
if (!BPlusDeleteRecursive(node->children[index], key)) {
return false;
}
if (node->children[index] != NULL && node->children[index]->key_count == 0) {
if (index > 0 && node->children[index - 1] != NULL &&
node->children[index - 1]->key_count > 1) {
BPlusBorrowFromPrev(node, index);
} else if (index < node->key_count && node->children[index + 1] != NULL &&
node->children[index + 1]->key_count > 1) {
BPlusBorrowFromNext(node, index);
} else if (index > 0) {
BPlusMergeChildren(node, index - 1);
} else {
BPlusMergeChildren(node, index);
}
} else {
BPlusRefreshKeys(node);
}
return true;
}
BPlusNode *BPlusDelete(BPlusNode *root, int key) {
BPlusNode *new_root;
if (root == NULL) {
return NULL;
}
if (!BPlusDeleteRecursive(root, key)) {
return root;
}
if (root->leaf) {
if (root->key_count == 0) {
free(root);
return NULL;
}
return root;
}
if (root->key_count > 0) {
BPlusRefreshKeys(root);
return root;
}
new_root = root->children[0];
free(root);
return new_root;
}
BPlusNode *BuildSampleBPlusTree(void) {
int keys[] = {5, 12, 18, 24, 30, 37, 42, 50};
int i;
BPlusNode *root;
root = NULL;
for (i = 0; i < (int)(sizeof(keys) / sizeof(keys[0])); i++) {
root = BPlusInsert(root, keys[i]);
}
return root;
}
BPlusNode *BPlusFindLeaf(BPlusNode *root, int key) {
int i;
BPlusNode *current;
current = root;
while (current != NULL && !current->leaf) {
i = 0;
while (i < current->key_count && key >= current->keys[i]) {
i++;
}
current = current->children[i];
}
return current;
}
bool BPlusSearch(BPlusNode *root, int key) {
BPlusNode *leaf;
int i;
leaf = BPlusFindLeaf(root, key);
if (leaf == NULL) {
return false;
}
for (i = 0; i < leaf->key_count; i++) {
if (leaf->keys[i] == key) {
return true;
}
}
return false;
}
void BPlusPrintRange(BPlusNode *root, int low, int high) {
BPlusNode *leaf;
int i;
leaf = BPlusFindLeaf(root, low);
printf("B+ range [%d, %d]: ", low, high);
while (leaf != NULL) {
for (i = 0; i < leaf->key_count; i++) {
if (leaf->keys[i] >= low && leaf->keys[i] <= high) {
printf("%d ", leaf->keys[i]);
}
if (leaf->keys[i] > high) {
printf("\n");
return;
}
}
leaf = leaf->next;
}
printf("\n");
}
void BPlusPrintLeaves(BPlusNode *root) {
BPlusNode *current;
int i;
current = root;
while (current != NULL && !current->leaf) {
current = current->children[0];
}
printf("B+ leaves: ");
while (current != NULL) {
printf("[");
for (i = 0; i < current->key_count; i++) {
printf("%d", current->keys[i]);
if (i + 1 < current->key_count) {
printf(" ");
}
}
printf("] ");
current = current->next;
}
printf("\n");
}
void DestroyBPlusTree(BPlusNode *root) {
int i;
if (root == NULL) {
return;
}
if (!root->leaf) {
for (i = 0; i <= root->key_count; i++) {
DestroyBPlusTree(root->children[i]);
}
}
free(root);
}
/* 散列函数:这里用简单取模,便于演示冲突与探测。 */
int HashFunc(int key) {
if (key < 0) {
key = -key;
}
return key % MAX_HASH_SIZE;
}
/* 初始化开放定址表:所有位置先视为空槽。 */
void InitHashOpenTable(HashOpenTable *table) {
int i;
if (table == NULL) {
return;
}
for (i = 0; i < MAX_HASH_SIZE; i++) {
table->data[i] = EMPTY_SLOT;
table->occupied[i] = false;
table->deleted[i] = false;
}
}
/* 线性探测插入:发生冲突时顺着往后找空位。 */
bool HashOpenInsert(HashOpenTable *table, int key) {
int start;
int step;
int pos;
if (table == NULL) {
return false;
}
start = HashFunc(key);
for (step = 0; step < MAX_HASH_SIZE; step++) {
pos = (start + step) % MAX_HASH_SIZE;
if (!table->occupied[pos] || table->deleted[pos]) {
table->data[pos] = key;
table->occupied[pos] = true;
table->deleted[pos] = false;
return true;
}
if (table->data[pos] == key) {
return true;
}
}
return false;
}
/* 线性探测查找:遇到真正的空槽就可断定查找失败。 */
int HashOpenSearch(const HashOpenTable *table, int key) {
int start;
int step;
int pos;
if (table == NULL) {
return -1;
}
start = HashFunc(key);
for (step = 0; step < MAX_HASH_SIZE; step++) {
pos = (start + step) % MAX_HASH_SIZE;
if (!table->occupied[pos] && !table->deleted[pos]) {
return -1;
}
if (table->occupied[pos] && !table->deleted[pos] && table->data[pos] == key) {
return pos;
}
}
return -1;
}
/* 打印开放定址表:便于观察哪些关键字因为冲突被探测到后面。 */
void PrintHashOpenTable(const HashOpenTable *table) {
int i;
if (table == NULL) {
return;
}
printf("Open addressing hash table:\n");
for (i = 0; i < MAX_HASH_SIZE; i++) {
if (table->occupied[i] && !table->deleted[i]) {
printf("[%d]=%d ", i, table->data[i]);
} else {
printf("[%d]=- ", i);
}
}
printf("\n");
}
/* 创建拉链法结点:把新关键字挂到同义词链中。 */
ChainNode *CreateChainNode(int key) {
ChainNode *node;
node = (ChainNode *)malloc(sizeof(ChainNode));
if (node == NULL) {
return NULL;
}
node->key = key;
node->next = NULL;
return node;
}
/* 初始化拉链法散列表:所有桶头指针先置空。 */
void InitChainHashTable(ChainHashTable *table) {
int i;
if (table == NULL) {
return;
}
for (i = 0; i < MAX_HASH_SIZE; i++) {
table->buckets[i] = NULL;
}
}
/* 拉链法插入:直接头插到对应桶的链表里。 */
bool ChainHashInsert(ChainHashTable *table, int key) {
int index;
ChainNode *node;
if (table == NULL) {
return false;
}
index = HashFunc(key);
node = CreateChainNode(key);
if (node == NULL) {
return false;
}
node->next = table->buckets[index];
table->buckets[index] = node;
return true;
}
/* 拉链法查找:只在对应桶的链表中顺着找。 */
ChainNode *ChainHashSearch(const ChainHashTable *table, int key) {
int index;
ChainNode *current;
if (table == NULL) {
return NULL;
}
index = HashFunc(key);
current = table->buckets[index];
while (current != NULL) {
if (current->key == key) {
return current;
}
current = current->next;
}
return NULL;
}
/* 打印拉链法散列表:直观看每个桶上的同义词链。 */
void PrintChainHashTable(const ChainHashTable *table) {
int i;
ChainNode *current;
if (table == NULL) {
return;
}
printf("Chaining hash table:\n");
for (i = 0; i < MAX_HASH_SIZE; i++) {
printf("[%d] -> ", i);
current = table->buckets[i];
while (current != NULL) {
printf("%d ", current->key);
current = current->next;
}
printf("^\n");
}
}
/* 释放拉链法散列表:逐桶逐链释放动态结点。 */
void DestroyChainHashTable(ChainHashTable *table) {
int i;
ChainNode *current;
ChainNode *next;
if (table == NULL) {
return;
}
for (i = 0; i < MAX_HASH_SIZE; i++) {
current = table->buckets[i];
while (current != NULL) {
next = current->next;
free(current);
current = next;
}
table->buckets[i] = NULL;
}
}
/* 主函数:集中演示第 7 章启动版已经落地的查找结构和算法。 */
int main(void) {
int ordered_array[] = {5, 8, 12, 19, 23, 31, 45, 57, 68, 72};
int unordered_array[] = {19, 14, 23, 1, 68, 20, 84, 27, 55, 11, 10, 79};
BlockIndex blocks[MAX_BLOCKS] = {
{19, 0, 3},
{45, 4, 6},
{72, 7, 9}
};
int bst_keys[] = {45, 24, 53, 12, 37, 50, 61, 30, 40};
int avl_keys[] = {30, 20, 40, 10, 25, 35, 50, 5, 15, 27};
int rb_keys[] = {30, 20, 40, 10, 25, 35, 50, 5, 15, 27, 45};
int btree_keys[] = {20, 10, 30, 5, 15, 25, 35, 40, 50, 60, 70};
int bplus_extra_keys[] = {44, 46};
int hash_keys[] = {19, 14, 23, 1, 68, 20, 84, 27, 55, 11, 10, 79};
int i;
int seq_pos;
int binary_pos;
int binary_recursive_pos;
int block_pos;
int btree_index;
BSTNode *bst_root;
AVLNode *avl_root;
RBNode *rb_root;
BTreeNode *btree_root;
BTreeNode *btree_found;
BPlusNode *bplus_root;
HashOpenTable open_table;
ChainHashTable chain_table;
seq_pos = SeqSearch(unordered_array, (int)(sizeof(unordered_array) / sizeof(unordered_array[0])), 84);
binary_pos = BinarySearchIter(ordered_array, (int)(sizeof(ordered_array) / sizeof(ordered_array[0])), 31);
binary_recursive_pos = BinarySearchRecursive(
ordered_array,
0,
(int)(sizeof(ordered_array) / sizeof(ordered_array[0])) - 1,
68
);
block_pos = BlockSearch(ordered_array, (int)(sizeof(ordered_array) / sizeof(ordered_array[0])), blocks, 3, 57);
printf("Sequential search position of 84: %d\n", seq_pos);
printf("Binary search position of 31: %d\n", binary_pos);
printf("Recursive binary search position of 68: %d\n", binary_recursive_pos);
printf("Block search position of 57: %d\n", block_pos);
bst_root = NULL;
for (i = 0; i < (int)(sizeof(bst_keys) / sizeof(bst_keys[0])); i++) {
bst_root = BSTInsert(bst_root, bst_keys[i]);
}
printf("BST inorder before deletion: ");
BSTInorder(bst_root);
printf("\n");
printf("BST search 37: %s\n", BSTSearch(bst_root, 37) != NULL ? "found" : "not found");
bst_root = BSTDelete(bst_root, 24);
printf("BST inorder after deleting 24: ");
BSTInorder(bst_root);
printf("\n");
avl_root = NULL;
for (i = 0; i < (int)(sizeof(avl_keys) / sizeof(avl_keys[0])); i++) {
avl_root = AVLInsert(avl_root, avl_keys[i]);
}
printf("AVL preorder: ");
AVLPreorder(avl_root);
printf("\n");
printf("AVL search 27: %s\n", AVLSearch(avl_root, 27) != NULL ? "found" : "not found");
printf("AVL root = %d, height = %d\n", avl_root != NULL ? avl_root->key : -1, AVLHeight(avl_root));
rb_root = NULL;
for (i = 0; i < (int)(sizeof(rb_keys) / sizeof(rb_keys[0])); i++) {
rb_root = RBInsert(rb_root, rb_keys[i]);
}
if (rb_root != NULL) {
rb_root->color = RB_BLACK;
}
printf("Red-black inorder: ");
RBInorder(rb_root);
printf("\n");
printf("Red-black search 45: %s\n", RBSearch(rb_root, 45) != NULL ? "found" : "not found");
rb_root = RBDelete(rb_root, 20);
if (rb_root != NULL) {
rb_root->color = RB_BLACK;
}
printf("Red-black inorder after deleting 20: ");
RBInorder(rb_root);
printf("\n");
btree_root = NULL;
for (i = 0; i < (int)(sizeof(btree_keys) / sizeof(btree_keys[0])); i++) {
btree_root = BTreeInsert(btree_root, btree_keys[i]);
}
printf("B-tree structure:\n");
BTreePrint(btree_root, 0);
btree_index = -1;
btree_found = BTreeSearch(btree_root, 35, &btree_index);
printf("B-tree search 35: %s", btree_found != NULL ? "found" : "not found");
if (btree_found != NULL) {
printf(" in node slot %d", btree_index);
}
printf("\n");
btree_root = BTreeDelete(btree_root, 30);
printf("B-tree after deleting 30:\n");
BTreePrint(btree_root, 0);
bplus_root = BuildSampleBPlusTree();
BPlusPrintLeaves(bplus_root);
printf("B+ search 24: %s\n", BPlusSearch(bplus_root, 24) ? "found" : "not found");
BPlusPrintRange(bplus_root, 18, 42);
for (i = 0; i < (int)(sizeof(bplus_extra_keys) / sizeof(bplus_extra_keys[0])); i++) {
bplus_root = BPlusInsert(bplus_root, bplus_extra_keys[i]);
}
printf("After inserting 44 and 46:\n");
BPlusPrintLeaves(bplus_root);
bplus_root = BPlusDelete(bplus_root, 24);
printf("After deleting 24:\n");
BPlusPrintLeaves(bplus_root);
BPlusPrintRange(bplus_root, 18, 46);
InitHashOpenTable(&open_table);
InitChainHashTable(&chain_table);
for (i = 0; i < (int)(sizeof(hash_keys) / sizeof(hash_keys[0])); i++) {
HashOpenInsert(&open_table, hash_keys[i]);
ChainHashInsert(&chain_table, hash_keys[i]);
}
PrintHashOpenTable(&open_table);
printf("Open addressing search 84 -> slot %d\n", HashOpenSearch(&open_table, 84));
PrintChainHashTable(&chain_table);
printf("Chaining search 55: %s\n", ChainHashSearch(&chain_table, 55) != NULL ? "found" : "not found");
DestroyBST(bst_root);
DestroyAVL(avl_root);
DestroyRB(rb_root);
DestroyBTree(btree_root);
DestroyBPlusTree(bplus_root);
DestroyChainHashTable(&chain_table);
return 0;
}
逐行注释版
/* 绗?{number}琛岋細寮曞叆褰撳墠鏂囦欢闇€瑕佷娇鐢ㄧ殑澶存枃浠躲€?*/
#include <stdbool.h>
/* 绗?{number}琛岋細寮曞叆褰撳墠鏂囦欢闇€瑕佷娇鐢ㄧ殑澶存枃浠躲€?*/
#include <stdio.h>
/* 绗?{number}琛岋細寮曞叆褰撳墠鏂囦欢闇€瑕佷娇鐢ㄧ殑澶存枃浠躲€?*/
#include <stdlib.h>
/* 绗?{number}琛岋細寮曞叆褰撳墠鏂囦欢闇€瑕佷娇鐢ㄧ殑澶存枃浠躲€?*/
#include <string.h>
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細瀹氫箟鍚庨潰浠g爜浼氬弽澶嶄娇鐢ㄧ殑瀹忓父閲忋€?*/
#define MAX_BLOCKS 10
/* 绗?{number}琛岋細瀹氫箟鍚庨潰浠g爜浼氬弽澶嶄娇鐢ㄧ殑瀹忓父閲忋€?*/
#define MAX_HASH_SIZE 13
/* 绗?{number}琛岋細瀹氫箟鍚庨潰浠g爜浼氬弽澶嶄娇鐢ㄧ殑瀹忓父閲忋€?*/
#define EMPTY_SLOT (-1)
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細杩欐槸鍘熶唬鐮佷腑鑷甫鐨勮鏄庢€ф敞閲娿€?*/
/* 分块索引项:记录某一块的最大关键字,以及该块在原表中的起止下标。 */
/* 绗?{number}琛岋細寮€濮嬪畾涔変竴涓粨鏋勪綋绫诲瀷锛岀敤鏉ョ粍缁囩浉鍏虫暟鎹€?*/
typedef struct {
/* 绗?{number}琛岋細澹版槑褰撳墠璇彞鍚庨潰瑕佷娇鐢ㄧ殑鍙橀噺銆佹寚閽堟垨灞€閮ㄦ暟鎹€?*/
int max_key;
/* 绗?{number}琛岋細澹版槑褰撳墠璇彞鍚庨潰瑕佷娇鐢ㄧ殑鍙橀噺銆佹寚閽堟垨灞€閮ㄦ暟鎹€?*/
int start;
/* 绗?{number}琛岋細澹版槑褰撳墠璇彞鍚庨潰瑕佷娇鐢ㄧ殑鍙橀噺銆佹寚閽堟垨灞€閮ㄦ暟鎹€?*/
int end;
/* 绗?{number}琛岋細鎵ц杩欎竴琛屼唬鐮侊紝缁х画鎺ㄨ繘褰撳墠閫昏緫銆?*/
} BlockIndex;
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細杩欐槸鍘熶唬鐮佷腑鑷甫鐨勮鏄庢€ф敞閲娿€?*/
/* 二叉排序树结点:key 保存关键字,left/right 分别指向左右子树。 */
/* 绗?{number}琛岋細寮€濮嬪畾涔変竴涓粨鏋勪綋绫诲瀷锛岀敤鏉ョ粍缁囩浉鍏虫暟鎹€?*/
typedef struct BSTNode {
/* 绗?{number}琛岋細澹版槑褰撳墠璇彞鍚庨潰瑕佷娇鐢ㄧ殑鍙橀噺銆佹寚閽堟垨灞€閮ㄦ暟鎹€?*/
int key;
/* 绗?{number}琛岋細鎵ц杩欎竴琛屼唬鐮侊紝缁х画鎺ㄨ繘褰撳墠閫昏緫銆?*/
struct BSTNode *left;
/* 绗?{number}琛岋細鎵ц杩欎竴琛屼唬鐮侊紝缁х画鎺ㄨ繘褰撳墠閫昏緫銆?*/
struct BSTNode *right;
/* 绗?{number}琛岋細鎵ц杩欎竴琛屼唬鐮侊紝缁х画鎺ㄨ繘褰撳墠閫昏緫銆?*/
} BSTNode;
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細杩欐槸鍘熶唬鐮佷腑鑷甫鐨勮鏄庢€ф敞閲娿€?*/
/* AVL 结点:在 BST 结点基础上多维护一个高度字段。 */
/* 绗?{number}琛岋細寮€濮嬪畾涔変竴涓粨鏋勪綋绫诲瀷锛岀敤鏉ョ粍缁囩浉鍏虫暟鎹€?*/
typedef struct AVLNode {
/* 绗?{number}琛岋細澹版槑褰撳墠璇彞鍚庨潰瑕佷娇鐢ㄧ殑鍙橀噺銆佹寚閽堟垨灞€閮ㄦ暟鎹€?*/
int key;
/* 绗?{number}琛岋細澹版槑褰撳墠璇彞鍚庨潰瑕佷娇鐢ㄧ殑鍙橀噺銆佹寚閽堟垨灞€閮ㄦ暟鎹€?*/
int height;
/* 绗?{number}琛岋細鎵ц杩欎竴琛屼唬鐮侊紝缁х画鎺ㄨ繘褰撳墠閫昏緫銆?*/
struct AVLNode *left;
/* 绗?{number}琛岋細鎵ц杩欎竴琛屼唬鐮侊紝缁х画鎺ㄨ繘褰撳墠閫昏緫銆?*/
struct AVLNode *right;
/* 绗?{number}琛岋細鎵ц杩欎竴琛屼唬鐮侊紝缁х画鎺ㄨ繘褰撳墠閫昏緫銆?*/
} AVLNode;
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細鎵ц杩欎竴琛屼唬鐮侊紝缁х画鎺ㄨ繘褰撳墠閫昏緫銆?*/
typedef enum {
/* 绗?{number}琛岋細鎵ц杩欎竴琛屼唬鐮侊紝缁х画鎺ㄨ繘褰撳墠閫昏緫銆?*/
RB_RED,
/* 绗?{number}琛岋細鎵ц杩欎竴琛屼唬鐮侊紝缁х画鎺ㄨ繘褰撳墠閫昏緫銆?*/
RB_BLACK
/* 绗?{number}琛岋細鎵ц杩欎竴琛屼唬鐮侊紝缁х画鎺ㄨ繘褰撳墠閫昏緫銆?*/
} RBColor;
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細寮€濮嬪畾涔変竴涓粨鏋勪綋绫诲瀷锛岀敤鏉ョ粍缁囩浉鍏虫暟鎹€?*/
typedef struct RBNode {
/* 绗?{number}琛岋細澹版槑褰撳墠璇彞鍚庨潰瑕佷娇鐢ㄧ殑鍙橀噺銆佹寚閽堟垨灞€閮ㄦ暟鎹€?*/
int key;
/* 绗?{number}琛岋細鎵ц杩欎竴琛屼唬鐮侊紝缁х画鎺ㄨ繘褰撳墠閫昏緫銆?*/
RBColor color;
/* 绗?{number}琛岋細鎵ц杩欎竴琛屼唬鐮侊紝缁х画鎺ㄨ繘褰撳墠閫昏緫銆?*/
struct RBNode *left;
/* 绗?{number}琛岋細鎵ц杩欎竴琛屼唬鐮侊紝缁х画鎺ㄨ繘褰撳墠閫昏緫銆?*/
struct RBNode *right;
/* 绗?{number}琛岋細鎵ц杩欎竴琛屼唬鐮侊紝缁х画鎺ㄨ繘褰撳墠閫昏緫銆?*/
} RBNode;
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細瀹氫箟鍚庨潰浠g爜浼氬弽澶嶄娇鐢ㄧ殑瀹忓父閲忋€?*/
#define BTREE_MIN_DEGREE 2
/* 绗?{number}琛岋細瀹氫箟鍚庨潰浠g爜浼氬弽澶嶄娇鐢ㄧ殑瀹忓父閲忋€?*/
#define BTREE_MAX_KEYS (2 * BTREE_MIN_DEGREE - 1)
/* 绗?{number}琛岋細瀹氫箟鍚庨潰浠g爜浼氬弽澶嶄娇鐢ㄧ殑瀹忓父閲忋€?*/
#define BTREE_MAX_CHILDREN (2 * BTREE_MIN_DEGREE)
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細寮€濮嬪畾涔変竴涓粨鏋勪綋绫诲瀷锛岀敤鏉ョ粍缁囩浉鍏虫暟鎹€?*/
typedef struct BTreeNode {
/* 绗?{number}琛岋細澹版槑褰撳墠璇彞鍚庨潰瑕佷娇鐢ㄧ殑鍙橀噺銆佹寚閽堟垨灞€閮ㄦ暟鎹€?*/
int key_count;
/* 绗?{number}琛岋細澹版槑褰撳墠璇彞鍚庨潰瑕佷娇鐢ㄧ殑鍙橀噺銆佹寚閽堟垨灞€閮ㄦ暟鎹€?*/
int keys[BTREE_MAX_KEYS];
/* 绗?{number}琛岋細澹版槑褰撳墠璇彞鍚庨潰瑕佷娇鐢ㄧ殑鍙橀噺銆佹寚閽堟垨灞€閮ㄦ暟鎹€?*/
bool leaf;
/* 绗?{number}琛岋細鎵ц杩欎竴琛屼唬鐮侊紝缁х画鎺ㄨ繘褰撳墠閫昏緫銆?*/
struct BTreeNode *children[BTREE_MAX_CHILDREN];
/* 绗?{number}琛岋細鎵ц杩欎竴琛屼唬鐮侊紝缁х画鎺ㄨ繘褰撳墠閫昏緫銆?*/
} BTreeNode;
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細寮€濮嬪畾涔変竴涓粨鏋勪綋绫诲瀷锛岀敤鏉ョ粍缁囩浉鍏虫暟鎹€?*/
typedef struct BPlusNode {
/* 绗?{number}琛岋細澹版槑褰撳墠璇彞鍚庨潰瑕佷娇鐢ㄧ殑鍙橀噺銆佹寚閽堟垨灞€閮ㄦ暟鎹€?*/
bool leaf;
/* 绗?{number}琛岋細澹版槑褰撳墠璇彞鍚庨潰瑕佷娇鐢ㄧ殑鍙橀噺銆佹寚閽堟垨灞€閮ㄦ暟鎹€?*/
int key_count;
/* 绗?{number}琛岋細澹版槑褰撳墠璇彞鍚庨潰瑕佷娇鐢ㄧ殑鍙橀噺銆佹寚閽堟垨灞€閮ㄦ暟鎹€?*/
int keys[BTREE_MAX_KEYS + 1];
/* 绗?{number}琛岋細鎵ц杩欎竴琛屼唬鐮侊紝缁х画鎺ㄨ繘褰撳墠閫昏緫銆?*/
struct BPlusNode *children[BTREE_MAX_CHILDREN + 1];
/* 绗?{number}琛岋細鎵ц杩欎竴琛屼唬鐮侊紝缁х画鎺ㄨ繘褰撳墠閫昏緫銆?*/
struct BPlusNode *next;
/* 绗?{number}琛岋細鎵ц杩欎竴琛屼唬鐮侊紝缁х画鎺ㄨ繘褰撳墠閫昏緫銆?*/
} BPlusNode;
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細杩欐槸鍘熶唬鐮佷腑鑷甫鐨勮鏄庢€ф敞閲娿€?*/
/* 开放定址散列表:data 存关键字,occupied 表示是否曾经占用,deleted 表示逻辑删除。 */
/* 绗?{number}琛岋細寮€濮嬪畾涔変竴涓粨鏋勪綋绫诲瀷锛岀敤鏉ョ粍缁囩浉鍏虫暟鎹€?*/
typedef struct {
/* 绗?{number}琛岋細澹版槑褰撳墠璇彞鍚庨潰瑕佷娇鐢ㄧ殑鍙橀噺銆佹寚閽堟垨灞€閮ㄦ暟鎹€?*/
int data[MAX_HASH_SIZE];
/* 绗?{number}琛岋細澹版槑褰撳墠璇彞鍚庨潰瑕佷娇鐢ㄧ殑鍙橀噺銆佹寚閽堟垨灞€閮ㄦ暟鎹€?*/
bool occupied[MAX_HASH_SIZE];
/* 绗?{number}琛岋細澹版槑褰撳墠璇彞鍚庨潰瑕佷娇鐢ㄧ殑鍙橀噺銆佹寚閽堟垨灞€閮ㄦ暟鎹€?*/
bool deleted[MAX_HASH_SIZE];
/* 绗?{number}琛岋細鎵ц杩欎竴琛屼唬鐮侊紝缁х画鎺ㄨ繘褰撳墠閫昏緫銆?*/
} HashOpenTable;
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細杩欐槸鍘熶唬鐮佷腑鑷甫鐨勮鏄庢€ф敞閲娿€?*/
/* 拉链法结点:key 存关键字,next 指向同义词链上的下一个结点。 */
/* 绗?{number}琛岋細寮€濮嬪畾涔変竴涓粨鏋勪綋绫诲瀷锛岀敤鏉ョ粍缁囩浉鍏虫暟鎹€?*/
typedef struct ChainNode {
/* 绗?{number}琛岋細澹版槑褰撳墠璇彞鍚庨潰瑕佷娇鐢ㄧ殑鍙橀噺銆佹寚閽堟垨灞€閮ㄦ暟鎹€?*/
int key;
/* 绗?{number}琛岋細鎵ц杩欎竴琛屼唬鐮侊紝缁х画鎺ㄨ繘褰撳墠閫昏緫銆?*/
struct ChainNode *next;
/* 绗?{number}琛岋細鎵ц杩欎竴琛屼唬鐮侊紝缁х画鎺ㄨ繘褰撳墠閫昏緫銆?*/
} ChainNode;
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細杩欐槸鍘熶唬鐮佷腑鑷甫鐨勮鏄庢€ф敞閲娿€?*/
/* 拉链法散列表:buckets 中每个桶都是一个链表头指针。 */
/* 绗?{number}琛岋細寮€濮嬪畾涔変竴涓粨鏋勪綋绫诲瀷锛岀敤鏉ョ粍缁囩浉鍏虫暟鎹€?*/
typedef struct {
/* 绗?{number}琛岋細澹版槑褰撳墠璇彞鍚庨潰瑕佷娇鐢ㄧ殑鍙橀噺銆佹寚閽堟垨灞€閮ㄦ暟鎹€?*/
ChainNode *buckets[MAX_HASH_SIZE];
/* 绗?{number}琛岋細鎵ц杩欎竴琛屼唬鐮侊紝缁х画鎺ㄨ繘褰撳墠閫昏緫銆?*/
} ChainHashTable;
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細杩欐槸鍘熶唬鐮佷腑鑷甫鐨勮鏄庢€ф敞閲娿€?*/
/* 顺序查找:从头到尾逐个比较,找到目标就返回下标,否则返回 -1。 */
/* 绗?{number}琛岋細瀹氫箟鍑芥暟 ㈠紑濮嬪啓杩欎釜鍑芥暟鐨勫叿浣撳疄鐜般€?*/
int SeqSearch(const int *array, int length, int target) {
/* 绗?{number}琛岋細澹版槑褰撳墠璇彞鍚庨潰瑕佷娇鐢ㄧ殑鍙橀噺銆佹寚閽堟垨灞€閮ㄦ暟鎹€?*/
int i;
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭璧板摢涓垎鏀€?*/
if (array == NULL || length <= 0) {
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
return -1;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細寮€濮嬩竴娆?for 寰幆锛屾寜鍥哄畾娆℃暟鎴栧尯闂撮噸澶嶆墽琛屽悗缁鍙ャ€?*/
for (i = 0; i < length; i++) {
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭璧板摢涓垎鏀€?*/
if (array[i] == target) {
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
return i;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
return -1;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細杩欐槸鍘熶唬鐮佷腑鑷甫鐨勮鏄庢€ф敞閲娿€?*/
/* 折半查找非递归版:要求数组有序,通过不断缩小区间定位目标。 */
/* 绗?{number}琛岋細瀹氫箟鍑芥暟 ㈠紑濮嬪啓杩欎釜鍑芥暟鐨勫叿浣撳疄鐜般€?*/
int BinarySearchIter(const int *array, int length, int target) {
/* 绗?{number}琛岋細澹版槑褰撳墠璇彞鍚庨潰瑕佷娇鐢ㄧ殑鍙橀噺銆佹寚閽堟垨灞€閮ㄦ暟鎹€?*/
int low;
/* 绗?{number}琛岋細澹版槑褰撳墠璇彞鍚庨潰瑕佷娇鐢ㄧ殑鍙橀噺銆佹寚閽堟垨灞€閮ㄦ暟鎹€?*/
int high;
/* 绗?{number}琛岋細澹版槑褰撳墠璇彞鍚庨潰瑕佷娇鐢ㄧ殑鍙橀噺銆佹寚閽堟垨灞€閮ㄦ暟鎹€?*/
int mid;
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭璧板摢涓垎鏀€?*/
if (array == NULL || length <= 0) {
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
return -1;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
low = 0;
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
high = length - 1;
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細寮€濮嬩竴娆?while 寰幆锛屽彧瑕佹潯浠舵垚绔嬪氨缁х画鎵ц銆?*/
while (low <= high) {
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
mid = low + (high - low) / 2;
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭璧板摢涓垎鏀€?*/
if (array[mid] == target) {
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
return mid;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭璧板摢涓垎鏀€?*/
if (array[mid] < target) {
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
low = mid + 1;
/* 绗?{number}琛岋細鎵ц杩欎竴琛屼唬鐮侊紝缁х画鎺ㄨ繘褰撳墠閫昏緫銆?*/
} else {
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
high = mid - 1;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
return -1;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細杩欐槸鍘熶唬鐮佷腑鑷甫鐨勮鏄庢€ф敞閲娿€?*/
/* 折半查找递归版:逻辑和非递归版一致,只是把“缩区间”交给递归。 */
/* 绗?{number}琛岋細瀹氫箟鍑芥暟 ㈠紑濮嬪啓杩欎釜鍑芥暟鐨勫叿浣撳疄鐜般€?*/
int BinarySearchRecursive(const int *array, int low, int high, int target) {
/* 绗?{number}琛岋細澹版槑褰撳墠璇彞鍚庨潰瑕佷娇鐢ㄧ殑鍙橀噺銆佹寚閽堟垨灞€閮ㄦ暟鎹€?*/
int mid;
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭璧板摢涓垎鏀€?*/
if (array == NULL || low > high) {
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
return -1;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
mid = low + (high - low) / 2;
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭璧板摢涓垎鏀€?*/
if (array[mid] == target) {
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
return mid;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭璧板摢涓垎鏀€?*/
if (array[mid] < target) {
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
return BinarySearchRecursive(array, mid + 1, high, target);
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
return BinarySearchRecursive(array, low, mid - 1, target);
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細杩欐槸鍘熶唬鐮佷腑鑷甫鐨勮鏄庢€ф敞閲娿€?*/
/* 分块查找:先扫描索引块,再在目标块内部顺序查找。 */
/* 绗?{number}琛岋細瀹氫箟鍑芥暟 ㈠紑濮嬪啓杩欎釜鍑芥暟鐨勫叿浣撳疄鐜般€?*/
int BlockSearch(const int *array, int length, const BlockIndex *index, int block_count, int target) {
/* 绗?{number}琛岋細澹版槑褰撳墠璇彞鍚庨潰瑕佷娇鐢ㄧ殑鍙橀噺銆佹寚閽堟垨灞€閮ㄦ暟鎹€?*/
int i;
/* 绗?{number}琛岋細澹版槑褰撳墠璇彞鍚庨潰瑕佷娇鐢ㄧ殑鍙橀噺銆佹寚閽堟垨灞€閮ㄦ暟鎹€?*/
int start;
/* 绗?{number}琛岋細澹版槑褰撳墠璇彞鍚庨潰瑕佷娇鐢ㄧ殑鍙橀噺銆佹寚閽堟垨灞€閮ㄦ暟鎹€?*/
int end;
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭璧板摢涓垎鏀€?*/
if (array == NULL || index == NULL || length <= 0 || block_count <= 0) {
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
return -1;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細寮€濮嬩竴娆?for 寰幆锛屾寜鍥哄畾娆℃暟鎴栧尯闂撮噸澶嶆墽琛屽悗缁鍙ャ€?*/
for (i = 0; i < block_count; i++) {
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭璧板摢涓垎鏀€?*/
if (target <= index[i].max_key) {
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
start = index[i].start;
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
end = index[i].end;
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭璧板摢涓垎鏀€?*/
if (start < 0) {
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
start = 0;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭璧板摢涓垎鏀€?*/
if (end >= length) {
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
end = length - 1;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細寮€濮嬩竴娆?for 寰幆锛屾寜鍥哄畾娆℃暟鎴栧尯闂撮噸澶嶆墽琛屽悗缁鍙ャ€?*/
for (; start <= end; start++) {
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭璧板摢涓垎鏀€?*/
if (array[start] == target) {
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
return start;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
return -1;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
return -1;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細杩欐槸鍘熶唬鐮佷腑鑷甫鐨勮鏄庢€ф敞閲娿€?*/
/* 创建 BST 结点:后续插入、删除都基于这个基础构造函数。 */
/* 绗?{number}琛岋細澹版槑褰撳墠璇彞鍚庨潰瑕佷娇鐢ㄧ殑鍙橀噺銆佹寚閽堟垨灞€閮ㄦ暟鎹€?*/
BSTNode *CreateBSTNode(int key) {
/* 绗?{number}琛岋細澹版槑褰撳墠璇彞鍚庨潰瑕佷娇鐢ㄧ殑鍙橀噺銆佹寚閽堟垨灞€閮ㄦ暟鎹€?*/
BSTNode *node;
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
node = (BSTNode *)malloc(sizeof(BSTNode));
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭璧板摢涓垎鏀€?*/
if (node == NULL) {
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
return NULL;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
node->key = key;
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
node->left = NULL;
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
node->right = NULL;
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
return node;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細杩欐槸鍘熶唬鐮佷腑鑷甫鐨勮鏄庢€ф敞閲娿€?*/
/* BST 查找:小了往左,大了往右,相等就返回当前结点。 */
/* 绗?{number}琛岋細澹版槑褰撳墠璇彞鍚庨潰瑕佷娇鐢ㄧ殑鍙橀噺銆佹寚閽堟垨灞€閮ㄦ暟鎹€?*/
BSTNode *BSTSearch(BSTNode *root, int key) {
/* 绗?{number}琛岋細澹版槑褰撳墠璇彞鍚庨潰瑕佷娇鐢ㄧ殑鍙橀噺銆佹寚閽堟垨灞€閮ㄦ暟鎹€?*/
BSTNode *current;
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
current = root;
/* 绗?{number}琛岋細寮€濮嬩竴娆?while 寰幆锛屽彧瑕佹潯浠舵垚绔嬪氨缁х画鎵ц銆?*/
while (current != NULL) {
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭璧板摢涓垎鏀€?*/
if (key == current->key) {
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
return current;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭璧板摢涓垎鏀€?*/
if (key < current->key) {
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
current = current->left;
/* 绗?{number}琛岋細鎵ц杩欎竴琛屼唬鐮侊紝缁х画鎺ㄨ繘褰撳墠閫昏緫銆?*/
} else {
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
current = current->right;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
return NULL;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細杩欐槸鍘熶唬鐮佷腑鑷甫鐨勮鏄庢€ф敞閲娿€?*/
/* BST 插入:找到空位置后挂上新结点,重复关键字不再插入。 */
/* 绗?{number}琛岋細澹版槑褰撳墠璇彞鍚庨潰瑕佷娇鐢ㄧ殑鍙橀噺銆佹寚閽堟垨灞€閮ㄦ暟鎹€?*/
BSTNode *BSTInsert(BSTNode *root, int key) {
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭璧板摢涓垎鏀€?*/
if (root == NULL) {
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
return CreateBSTNode(key);
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭璧板摢涓垎鏀€?*/
if (key < root->key) {
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
root->left = BSTInsert(root->left, key);
/* 绗?{number}琛岋細鎵ц杩欎竴琛屼唬鐮侊紝缁х画鎺ㄨ繘褰撳墠閫昏緫銆?*/
} else if (key > root->key) {
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
root->right = BSTInsert(root->right, key);
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
return root;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細杩欐槸鍘熶唬鐮佷腑鑷甫鐨勮鏄庢€ф敞閲娿€?*/
/* 找 BST 中的最小结点:一路向左走到尽头。 */
/* 绗?{number}琛岋細澹版槑褰撳墠璇彞鍚庨潰瑕佷娇鐢ㄧ殑鍙橀噺銆佹寚閽堟垨灞€閮ㄦ暟鎹€?*/
BSTNode *BSTFindMin(BSTNode *root) {
/* 绗?{number}琛岋細澹版槑褰撳墠璇彞鍚庨潰瑕佷娇鐢ㄧ殑鍙橀噺銆佹寚閽堟垨灞€閮ㄦ暟鎹€?*/
BSTNode *current;
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
current = root;
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭璧板摢涓垎鏀€?*/
if (current == NULL) {
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
return NULL;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細寮€濮嬩竴娆?while 寰幆锛屽彧瑕佹潯浠舵垚绔嬪氨缁х画鎵ц銆?*/
while (current->left != NULL) {
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
current = current->left;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
return current;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細杩欐槸鍘熶唬鐮佷腑鑷甫鐨勮鏄庢€ф敞閲娿€?*/
/* BST 删除:分叶子、单孩子、双孩子三种情况处理。 */
/* 绗?{number}琛岋細澹版槑褰撳墠璇彞鍚庨潰瑕佷娇鐢ㄧ殑鍙橀噺銆佹寚閽堟垨灞€閮ㄦ暟鎹€?*/
BSTNode *BSTDelete(BSTNode *root, int key) {
/* 绗?{number}琛岋細澹版槑褰撳墠璇彞鍚庨潰瑕佷娇鐢ㄧ殑鍙橀噺銆佹寚閽堟垨灞€閮ㄦ暟鎹€?*/
BSTNode *successor;
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭璧板摢涓垎鏀€?*/
if (root == NULL) {
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
return NULL;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭璧板摢涓垎鏀€?*/
if (key < root->key) {
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
root->left = BSTDelete(root->left, key);
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
return root;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭璧板摢涓垎鏀€?*/
if (key > root->key) {
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
root->right = BSTDelete(root->right, key);
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
return root;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭璧板摢涓垎鏀€?*/
if (root->left == NULL && root->right == NULL) {
/* 绗?{number}琛岋細璋冪敤涓€涓嚱鏁帮紝璁╁畠甯垜浠畬鎴愬綋鍓嶈繖涓€姝ユ搷浣溿€?*/
free(root);
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
return NULL;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭璧板摢涓垎鏀€?*/
if (root->left == NULL) {
/* 绗?{number}琛岋細澹版槑褰撳墠璇彞鍚庨潰瑕佷娇鐢ㄧ殑鍙橀噺銆佹寚閽堟垨灞€閮ㄦ暟鎹€?*/
BSTNode *right_child;
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
right_child = root->right;
/* 绗?{number}琛岋細璋冪敤涓€涓嚱鏁帮紝璁╁畠甯垜浠畬鎴愬綋鍓嶈繖涓€姝ユ搷浣溿€?*/
free(root);
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
return right_child;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭璧板摢涓垎鏀€?*/
if (root->right == NULL) {
/* 绗?{number}琛岋細澹版槑褰撳墠璇彞鍚庨潰瑕佷娇鐢ㄧ殑鍙橀噺銆佹寚閽堟垨灞€閮ㄦ暟鎹€?*/
BSTNode *left_child;
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
left_child = root->left;
/* 绗?{number}琛岋細璋冪敤涓€涓嚱鏁帮紝璁╁畠甯垜浠畬鎴愬綋鍓嶈繖涓€姝ユ搷浣溿€?*/
free(root);
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
return left_child;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
successor = BSTFindMin(root->right);
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
root->key = successor->key;
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
root->right = BSTDelete(root->right, successor->key);
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
return root;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細杩欐槸鍘熶唬鐮佷腑鑷甫鐨勮鏄庢€ф敞閲娿€?*/
/* 中序遍历 BST:可以直接验证 BST 输出是否递增有序。 */
/* 绗?{number}琛岋細瀹氫箟鍑芥暟 ㈠紑濮嬪啓杩欎釜鍑芥暟鐨勫叿浣撳疄鐜般€?*/
void BSTInorder(const BSTNode *root) {
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭璧板摢涓垎鏀€?*/
if (root == NULL) {
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
return;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細璋冪敤涓€涓嚱鏁帮紝璁╁畠甯垜浠畬鎴愬綋鍓嶈繖涓€姝ユ搷浣溿€?*/
BSTInorder(root->left);
/* 绗?{number}琛岋細鎶婂綋鍓嶇粨鏋滄墦鍗板嚭鏉ワ紝鏂逛究瑙傚療绋嬪簭杩愯鎯呭喌銆?*/
printf("%d ", root->key);
/* 绗?{number}琛岋細璋冪敤涓€涓嚱鏁帮紝璁╁畠甯垜浠畬鎴愬綋鍓嶈繖涓€姝ユ搷浣溿€?*/
BSTInorder(root->right);
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細杩欐槸鍘熶唬鐮佷腑鑷甫鐨勮鏄庢€ф敞閲娿€?*/
/* 释放 BST:后序递归释放整棵树,避免内存泄漏。 */
/* 绗?{number}琛岋細瀹氫箟鍑芥暟 ㈠紑濮嬪啓杩欎釜鍑芥暟鐨勫叿浣撳疄鐜般€?*/
void DestroyBST(BSTNode *root) {
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭璧板摢涓垎鏀€?*/
if (root == NULL) {
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
return;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細璋冪敤涓€涓嚱鏁帮紝璁╁畠甯垜浠畬鎴愬綋鍓嶈繖涓€姝ユ搷浣溿€?*/
DestroyBST(root->left);
/* 绗?{number}琛岋細璋冪敤涓€涓嚱鏁帮紝璁╁畠甯垜浠畬鎴愬綋鍓嶈繖涓€姝ユ搷浣溿€?*/
DestroyBST(root->right);
/* 绗?{number}琛岋細璋冪敤涓€涓嚱鏁帮紝璁╁畠甯垜浠畬鎴愬綋鍓嶈繖涓€姝ユ搷浣溿€?*/
free(root);
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細杩欐槸鍘熶唬鐮佷腑鑷甫鐨勮鏄庢€ф敞閲娿€?*/
/* 取 AVL 结点高度:空树高度记为 0。 */
/* 绗?{number}琛岋細瀹氫箟鍑芥暟 ㈠紑濮嬪啓杩欎釜鍑芥暟鐨勫叿浣撳疄鐜般€?*/
int AVLHeight(const AVLNode *node) {
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭璧板摢涓垎鏀€?*/
if (node == NULL) {
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
return 0;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
return node->height;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細杩欐槸鍘熶唬鐮佷腑鑷甫鐨勮鏄庢€ф敞閲娿€?*/
/* 求两个整数的较大值:更新 AVL 高度时会用到。 */
/* 绗?{number}琛岋細瀹氫箟鍑芥暟 ㈠紑濮嬪啓杩欎釜鍑芥暟鐨勫叿浣撳疄鐜般€?*/
int MaxInt(int a, int b) {
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
return a > b ? a : b;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細杩欐槸鍘熶唬鐮佷腑鑷甫鐨勮鏄庢€ф敞閲娿€?*/
/* 创建 AVL 结点:默认作为叶子结点,高度初始化为 1。 */
/* 绗?{number}琛岋細澹版槑褰撳墠璇彞鍚庨潰瑕佷娇鐢ㄧ殑鍙橀噺銆佹寚閽堟垨灞€閮ㄦ暟鎹€?*/
AVLNode *CreateAVLNode(int key) {
/* 绗?{number}琛岋細澹版槑褰撳墠璇彞鍚庨潰瑕佷娇鐢ㄧ殑鍙橀噺銆佹寚閽堟垨灞€閮ㄦ暟鎹€?*/
AVLNode *node;
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
node = (AVLNode *)malloc(sizeof(AVLNode));
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭璧板摢涓垎鏀€?*/
if (node == NULL) {
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
return NULL;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
node->key = key;
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
node->height = 1;
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
node->left = NULL;
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
node->right = NULL;
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
return node;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細杩欐槸鍘熶唬鐮佷腑鑷甫鐨勮鏄庢€ф敞閲娿€?*/
/* 更新 AVL 结点高度:左右子树较高者加 1。 */
/* 绗?{number}琛岋細瀹氫箟鍑芥暟 ㈠紑濮嬪啓杩欎釜鍑芥暟鐨勫叿浣撳疄鐜般€?*/
void UpdateAVLHeight(AVLNode *node) {
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭璧板摢涓垎鏀€?*/
if (node == NULL) {
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
return;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
node->height = MaxInt(AVLHeight(node->left), AVLHeight(node->right)) + 1;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細杩欐槸鍘熶唬鐮佷腑鑷甫鐨勮鏄庢€ф敞閲娿€?*/
/* 计算 AVL 平衡因子:左高减右高。 */
/* 绗?{number}琛岋細瀹氫箟鍑芥暟 ㈠紑濮嬪啓杩欎釜鍑芥暟鐨勫叿浣撳疄鐜般€?*/
int GetBalanceFactor(const AVLNode *node) {
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭璧板摢涓垎鏀€?*/
if (node == NULL) {
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
return 0;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
return AVLHeight(node->left) - AVLHeight(node->right);
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細杩欐槸鍘熶唬鐮佷腑鑷甫鐨勮鏄庢€ф敞閲娿€?*/
/* 右旋:修复 LL 型失衡,也可作为 LR 调整中的第二步。 */
/* 绗?{number}琛岋細澹版槑褰撳墠璇彞鍚庨潰瑕佷娇鐢ㄧ殑鍙橀噺銆佹寚閽堟垨灞€閮ㄦ暟鎹€?*/
AVLNode *RotateRight(AVLNode *y) {
/* 绗?{number}琛岋細澹版槑褰撳墠璇彞鍚庨潰瑕佷娇鐢ㄧ殑鍙橀噺銆佹寚閽堟垨灞€閮ㄦ暟鎹€?*/
AVLNode *x;
/* 绗?{number}琛岋細澹版槑褰撳墠璇彞鍚庨潰瑕佷娇鐢ㄧ殑鍙橀噺銆佹寚閽堟垨灞€閮ㄦ暟鎹€?*/
AVLNode *t2;
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭璧板摢涓垎鏀€?*/
if (y == NULL || y->left == NULL) {
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
return y;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
x = y->left;
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
t2 = x->right;
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
x->right = y;
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
y->left = t2;
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細璋冪敤涓€涓嚱鏁帮紝璁╁畠甯垜浠畬鎴愬綋鍓嶈繖涓€姝ユ搷浣溿€?*/
UpdateAVLHeight(y);
/* 绗?{number}琛岋細璋冪敤涓€涓嚱鏁帮紝璁╁畠甯垜浠畬鎴愬綋鍓嶈繖涓€姝ユ搷浣溿€?*/
UpdateAVLHeight(x);
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
return x;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細杩欐槸鍘熶唬鐮佷腑鑷甫鐨勮鏄庢€ф敞閲娿€?*/
/* 左旋:修复 RR 型失衡,也可作为 RL 调整中的第二步。 */
/* 绗?{number}琛岋細澹版槑褰撳墠璇彞鍚庨潰瑕佷娇鐢ㄧ殑鍙橀噺銆佹寚閽堟垨灞€閮ㄦ暟鎹€?*/
AVLNode *RotateLeft(AVLNode *x) {
/* 绗?{number}琛岋細澹版槑褰撳墠璇彞鍚庨潰瑕佷娇鐢ㄧ殑鍙橀噺銆佹寚閽堟垨灞€閮ㄦ暟鎹€?*/
AVLNode *y;
/* 绗?{number}琛岋細澹版槑褰撳墠璇彞鍚庨潰瑕佷娇鐢ㄧ殑鍙橀噺銆佹寚閽堟垨灞€閮ㄦ暟鎹€?*/
AVLNode *t2;
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭璧板摢涓垎鏀€?*/
if (x == NULL || x->right == NULL) {
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
return x;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
y = x->right;
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
t2 = y->left;
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
y->left = x;
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
x->right = t2;
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細璋冪敤涓€涓嚱鏁帮紝璁╁畠甯垜浠畬鎴愬綋鍓嶈繖涓€姝ユ搷浣溿€?*/
UpdateAVLHeight(x);
/* 绗?{number}琛岋細璋冪敤涓€涓嚱鏁帮紝璁╁畠甯垜浠畬鎴愬綋鍓嶈繖涓€姝ユ搷浣溿€?*/
UpdateAVLHeight(y);
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
return y;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細杩欐槸鍘熶唬鐮佷腑鑷甫鐨勮鏄庢€ф敞閲娿€?*/
/* AVL 插入:先按 BST 插入,再根据失衡类型旋转恢复平衡。 */
/* 绗?{number}琛岋細澹版槑褰撳墠璇彞鍚庨潰瑕佷娇鐢ㄧ殑鍙橀噺銆佹寚閽堟垨灞€閮ㄦ暟鎹€?*/
AVLNode *AVLInsert(AVLNode *node, int key) {
/* 绗?{number}琛岋細澹版槑褰撳墠璇彞鍚庨潰瑕佷娇鐢ㄧ殑鍙橀噺銆佹寚閽堟垨灞€閮ㄦ暟鎹€?*/
int balance;
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭璧板摢涓垎鏀€?*/
if (node == NULL) {
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
return CreateAVLNode(key);
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭璧板摢涓垎鏀€?*/
if (key < node->key) {
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
node->left = AVLInsert(node->left, key);
/* 绗?{number}琛岋細鎵ц杩欎竴琛屼唬鐮侊紝缁х画鎺ㄨ繘褰撳墠閫昏緫銆?*/
} else if (key > node->key) {
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
node->right = AVLInsert(node->right, key);
/* 绗?{number}琛岋細鎵ц杩欎竴琛屼唬鐮侊紝缁х画鎺ㄨ繘褰撳墠閫昏緫銆?*/
} else {
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
return node;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細璋冪敤涓€涓嚱鏁帮紝璁╁畠甯垜浠畬鎴愬綋鍓嶈繖涓€姝ユ搷浣溿€?*/
UpdateAVLHeight(node);
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
balance = GetBalanceFactor(node);
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭璧板摢涓垎鏀€?*/
if (balance > 1 && key < node->left->key) {
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
return RotateRight(node);
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭璧板摢涓垎鏀€?*/
if (balance < -1 && key > node->right->key) {
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
return RotateLeft(node);
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭璧板摢涓垎鏀€?*/
if (balance > 1 && key > node->left->key) {
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
node->left = RotateLeft(node->left);
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
return RotateRight(node);
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭璧板摢涓垎鏀€?*/
if (balance < -1 && key < node->right->key) {
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
node->right = RotateRight(node->right);
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
return RotateLeft(node);
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
return node;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細杩欐槸鍘熶唬鐮佷腑鑷甫鐨勮鏄庢€ф敞閲娿€?*/
/* AVL 查找:查找路径和 BST 相同,只是树更不容易退化。 */
/* 绗?{number}琛岋細澹版槑褰撳墠璇彞鍚庨潰瑕佷娇鐢ㄧ殑鍙橀噺銆佹寚閽堟垨灞€閮ㄦ暟鎹€?*/
AVLNode *AVLSearch(AVLNode *root, int key) {
/* 绗?{number}琛岋細澹版槑褰撳墠璇彞鍚庨潰瑕佷娇鐢ㄧ殑鍙橀噺銆佹寚閽堟垨灞€閮ㄦ暟鎹€?*/
AVLNode *current;
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
current = root;
/* 绗?{number}琛岋細寮€濮嬩竴娆?while 寰幆锛屽彧瑕佹潯浠舵垚绔嬪氨缁х画鎵ц銆?*/
while (current != NULL) {
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭璧板摢涓垎鏀€?*/
if (key == current->key) {
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
return current;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭璧板摢涓垎鏀€?*/
if (key < current->key) {
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
current = current->left;
/* 绗?{number}琛岋細鎵ц杩欎竴琛屼唬鐮侊紝缁х画鎺ㄨ繘褰撳墠閫昏緫銆?*/
} else {
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
current = current->right;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
return NULL;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細杩欐槸鍘熶唬鐮佷腑鑷甫鐨勮鏄庢€ф敞閲娿€?*/
/* AVL 先序遍历:便于观察旋转后根和子树位置的变化。 */
/* 绗?{number}琛岋細瀹氫箟鍑芥暟 ㈠紑濮嬪啓杩欎釜鍑芥暟鐨勫叿浣撳疄鐜般€?*/
void AVLPreorder(const AVLNode *root) {
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭璧板摢涓垎鏀€?*/
if (root == NULL) {
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
return;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細鎶婂綋鍓嶇粨鏋滄墦鍗板嚭鏉ワ紝鏂逛究瑙傚療绋嬪簭杩愯鎯呭喌銆?*/
printf("%d ", root->key);
/* 绗?{number}琛岋細璋冪敤涓€涓嚱鏁帮紝璁╁畠甯垜浠畬鎴愬綋鍓嶈繖涓€姝ユ搷浣溿€?*/
AVLPreorder(root->left);
/* 绗?{number}琛岋細璋冪敤涓€涓嚱鏁帮紝璁╁畠甯垜浠畬鎴愬綋鍓嶈繖涓€姝ユ搷浣溿€?*/
AVLPreorder(root->right);
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細杩欐槸鍘熶唬鐮佷腑鑷甫鐨勮鏄庢€ф敞閲娿€?*/
/* 释放 AVL:和 BST 一样做后序释放。 */
/* 绗?{number}琛岋細瀹氫箟鍑芥暟 ㈠紑濮嬪啓杩欎釜鍑芥暟鐨勫叿浣撳疄鐜般€?*/
void DestroyAVL(AVLNode *root) {
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭璧板摢涓垎鏀€?*/
if (root == NULL) {
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
return;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細璋冪敤涓€涓嚱鏁帮紝璁╁畠甯垜浠畬鎴愬綋鍓嶈繖涓€姝ユ搷浣溿€?*/
DestroyAVL(root->left);
/* 绗?{number}琛岋細璋冪敤涓€涓嚱鏁帮紝璁╁畠甯垜浠畬鎴愬綋鍓嶈繖涓€姝ユ搷浣溿€?*/
DestroyAVL(root->right);
/* 绗?{number}琛岋細璋冪敤涓€涓嚱鏁帮紝璁╁畠甯垜浠畬鎴愬綋鍓嶈繖涓€姝ユ搷浣溿€?*/
free(root);
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細瀹氫箟鍑芥暟 ㈠紑濮嬪啓杩欎釜鍑芥暟鐨勫叿浣撳疄鐜般€?*/
bool IsRedRB(const RBNode *node) {
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
return node != NULL && node->color == RB_RED;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細鎵ц杩欎竴琛屼唬鐮侊紝缁х画鎺ㄨ繘褰撳墠閫昏緫銆?*/
RBNode *CreateRBNode(int key) {
/* 绗?{number}琛岋細鎵ц杩欎竴琛屼唬鐮侊紝缁х画鎺ㄨ繘褰撳墠閫昏緫銆?*/
RBNode *node;
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
node = (RBNode *)malloc(sizeof(RBNode));
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭璧板摢涓垎鏀€?*/
if (node == NULL) {
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
return NULL;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
node->key = key;
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
node->color = RB_RED;
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
node->left = NULL;
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
node->right = NULL;
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
return node;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細鎵ц杩欎竴琛屼唬鐮侊紝缁х画鎺ㄨ繘褰撳墠閫昏緫銆?*/
RBNode *RBRotateLeft(RBNode *node) {
/* 绗?{number}琛岋細鎵ц杩欎竴琛屼唬鐮侊紝缁х画鎺ㄨ繘褰撳墠閫昏緫銆?*/
RBNode *right_child;
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
right_child = node->right;
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
node->right = right_child->left;
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
right_child->left = node;
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
right_child->color = node->color;
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
node->color = RB_RED;
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
return right_child;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細鎵ц杩欎竴琛屼唬鐮侊紝缁х画鎺ㄨ繘褰撳墠閫昏緫銆?*/
RBNode *RBRotateRight(RBNode *node) {
/* 绗?{number}琛岋細鎵ц杩欎竴琛屼唬鐮侊紝缁х画鎺ㄨ繘褰撳墠閫昏緫銆?*/
RBNode *left_child;
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
left_child = node->left;
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
node->left = left_child->right;
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
left_child->right = node;
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
left_child->color = node->color;
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
node->color = RB_RED;
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
return left_child;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細瀹氫箟鍑芥暟 ㈠紑濮嬪啓杩欎釜鍑芥暟鐨勫叿浣撳疄鐜般€?*/
void RBFlipColors(RBNode *node) {
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭璧板摢涓垎鏀€?*/
if (node == NULL || node->left == NULL || node->right == NULL) {
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
return;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細鎵ц杩欎竴琛屼唬鐮侊紝缁х画鎺ㄨ繘褰撳墠閫昏緫銆?*/
node->color = node->color == RB_RED ? RB_BLACK : RB_RED;
/* 绗?{number}琛岋細鎵ц杩欎竴琛屼唬鐮侊紝缁х画鎺ㄨ繘褰撳墠閫昏緫銆?*/
node->left->color = node->left->color == RB_RED ? RB_BLACK : RB_RED;
/* 绗?{number}琛岋細鎵ц杩欎竴琛屼唬鐮侊紝缁х画鎺ㄨ繘褰撳墠閫昏緫銆?*/
node->right->color = node->right->color == RB_RED ? RB_BLACK : RB_RED;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細鎵ц杩欎竴琛屼唬鐮侊紝缁х画鎺ㄨ繘褰撳墠閫昏緫銆?*/
RBNode *RBInsert(RBNode *root, int key) {
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭璧板摢涓垎鏀€?*/
if (root == NULL) {
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
return CreateRBNode(key);
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭璧板摢涓垎鏀€?*/
if (key < root->key) {
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
root->left = RBInsert(root->left, key);
/* 绗?{number}琛岋細鎵ц杩欎竴琛屼唬鐮侊紝缁х画鎺ㄨ繘褰撳墠閫昏緫銆?*/
} else if (key > root->key) {
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
root->right = RBInsert(root->right, key);
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭璧板摢涓垎鏀€?*/
if (IsRedRB(root->right) && !IsRedRB(root->left)) {
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
root = RBRotateLeft(root);
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭璧板摢涓垎鏀€?*/
if (IsRedRB(root->left) && IsRedRB(root->left->left)) {
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
root = RBRotateRight(root);
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭璧板摢涓垎鏀€?*/
if (IsRedRB(root->left) && IsRedRB(root->right)) {
/* 绗?{number}琛岋細璋冪敤涓€涓嚱鏁帮紝璁╁畠甯垜浠畬鎴愬綋鍓嶈繖涓€姝ユ搷浣溿€?*/
RBFlipColors(root);
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
return root;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細鎵ц杩欎竴琛屼唬鐮侊紝缁х画鎺ㄨ繘褰撳墠閫昏緫銆?*/
RBNode *RBSearch(RBNode *root, int key) {
/* 绗?{number}琛岋細鎵ц杩欎竴琛屼唬鐮侊紝缁х画鎺ㄨ繘褰撳墠閫昏緫銆?*/
RBNode *current;
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
current = root;
/* 绗?{number}琛岋細寮€濮嬩竴娆?while 寰幆锛屽彧瑕佹潯浠舵垚绔嬪氨缁х画鎵ц銆?*/
while (current != NULL) {
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭璧板摢涓垎鏀€?*/
if (key == current->key) {
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
return current;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭璧板摢涓垎鏀€?*/
if (key < current->key) {
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
current = current->left;
/* 绗?{number}琛岋細鎵ц杩欎竴琛屼唬鐮侊紝缁х画鎺ㄨ繘褰撳墠閫昏緫銆?*/
} else {
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
current = current->right;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
return NULL;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細鎵ц杩欎竴琛屼唬鐮侊紝缁х画鎺ㄨ繘褰撳墠閫昏緫銆?*/
RBNode *RBMoveRedLeft(RBNode *node) {
/* 绗?{number}琛岋細璋冪敤涓€涓嚱鏁帮紝璁╁畠甯垜浠畬鎴愬綋鍓嶈繖涓€姝ユ搷浣溿€?*/
RBFlipColors(node);
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭璧板摢涓垎鏀€?*/
if (node->right != NULL && IsRedRB(node->right->left)) {
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
node->right = RBRotateRight(node->right);
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
node = RBRotateLeft(node);
/* 绗?{number}琛岋細璋冪敤涓€涓嚱鏁帮紝璁╁畠甯垜浠畬鎴愬綋鍓嶈繖涓€姝ユ搷浣溿€?*/
RBFlipColors(node);
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
return node;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細鎵ц杩欎竴琛屼唬鐮侊紝缁х画鎺ㄨ繘褰撳墠閫昏緫銆?*/
RBNode *RBMoveRedRight(RBNode *node) {
/* 绗?{number}琛岋細璋冪敤涓€涓嚱鏁帮紝璁╁畠甯垜浠畬鎴愬綋鍓嶈繖涓€姝ユ搷浣溿€?*/
RBFlipColors(node);
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭璧板摢涓垎鏀€?*/
if (node->left != NULL && IsRedRB(node->left->left)) {
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
node = RBRotateRight(node);
/* 绗?{number}琛岋細璋冪敤涓€涓嚱鏁帮紝璁╁畠甯垜浠畬鎴愬綋鍓嶈繖涓€姝ユ搷浣溿€?*/
RBFlipColors(node);
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
return node;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細鎵ц杩欎竴琛屼唬鐮侊紝缁х画鎺ㄨ繘褰撳墠閫昏緫銆?*/
RBNode *RBFixUp(RBNode *node) {
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭璧板摢涓垎鏀€?*/
if (node == NULL) {
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
return NULL;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭璧板摢涓垎鏀€?*/
if (IsRedRB(node->right)) {
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
node = RBRotateLeft(node);
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭璧板摢涓垎鏀€?*/
if (IsRedRB(node->left) && IsRedRB(node->left->left)) {
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
node = RBRotateRight(node);
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭璧板摢涓垎鏀€?*/
if (IsRedRB(node->left) && IsRedRB(node->right)) {
/* 绗?{number}琛岋細璋冪敤涓€涓嚱鏁帮紝璁╁畠甯垜浠畬鎴愬綋鍓嶈繖涓€姝ユ搷浣溿€?*/
RBFlipColors(node);
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
return node;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細鎵ц杩欎竴琛屼唬鐮侊紝缁х画鎺ㄨ繘褰撳墠閫昏緫銆?*/
RBNode *RBMin(RBNode *node) {
/* 绗?{number}琛岋細鎵ц杩欎竴琛屼唬鐮侊紝缁х画鎺ㄨ繘褰撳墠閫昏緫銆?*/
RBNode *current;
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
current = node;
/* 绗?{number}琛岋細寮€濮嬩竴娆?while 寰幆锛屽彧瑕佹潯浠舵垚绔嬪氨缁х画鎵ц銆?*/
while (current != NULL && current->left != NULL) {
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
current = current->left;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
return current;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細鎵ц杩欎竴琛屼唬鐮侊紝缁х画鎺ㄨ繘褰撳墠閫昏緫銆?*/
RBNode *RBDeleteMin(RBNode *node) {
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭璧板摢涓垎鏀€?*/
if (node == NULL) {
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
return NULL;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭璧板摢涓垎鏀€?*/
if (node->left == NULL) {
/* 绗?{number}琛岋細璋冪敤涓€涓嚱鏁帮紝璁╁畠甯垜浠畬鎴愬綋鍓嶈繖涓€姝ユ搷浣溿€?*/
free(node);
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
return NULL;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭璧板摢涓垎鏀€?*/
if (!IsRedRB(node->left) && !IsRedRB(node->left->left)) {
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
node = RBMoveRedLeft(node);
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
node->left = RBDeleteMin(node->left);
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
return RBFixUp(node);
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細鎵ц杩欎竴琛屼唬鐮侊紝缁х画鎺ㄨ繘褰撳墠閫昏緫銆?*/
RBNode *RBDelete(RBNode *node, int key) {
/* 绗?{number}琛岋細鎵ц杩欎竴琛屼唬鐮侊紝缁х画鎺ㄨ繘褰撳墠閫昏緫銆?*/
RBNode *min_node;
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭璧板摢涓垎鏀€?*/
if (node == NULL) {
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
return NULL;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭璧板摢涓垎鏀€?*/
if (key < node->key) {
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭璧板摢涓垎鏀€?*/
if (node->left != NULL) {
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭璧板摢涓垎鏀€?*/
if (!IsRedRB(node->left) && !IsRedRB(node->left->left)) {
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
node = RBMoveRedLeft(node);
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
node->left = RBDelete(node->left, key);
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細鎵ц杩欎竴琛屼唬鐮侊紝缁х画鎺ㄨ繘褰撳墠閫昏緫銆?*/
} else {
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭璧板摢涓垎鏀€?*/
if (IsRedRB(node->left)) {
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
node = RBRotateRight(node);
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭璧板摢涓垎鏀€?*/
if (key == node->key && node->right == NULL) {
/* 绗?{number}琛岋細璋冪敤涓€涓嚱鏁帮紝璁╁畠甯垜浠畬鎴愬綋鍓嶈繖涓€姝ユ搷浣溿€?*/
free(node);
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
return NULL;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭璧板摢涓垎鏀€?*/
if (node->right != NULL) {
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭璧板摢涓垎鏀€?*/
if (!IsRedRB(node->right) && !IsRedRB(node->right->left)) {
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
node = RBMoveRedRight(node);
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭璧板摢涓垎鏀€?*/
if (key == node->key) {
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
min_node = RBMin(node->right);
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭璧板摢涓垎鏀€?*/
if (min_node != NULL) {
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
node->key = min_node->key;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
node->right = RBDeleteMin(node->right);
/* 绗?{number}琛岋細鎵ц杩欎竴琛屼唬鐮侊紝缁х画鎺ㄨ繘褰撳墠閫昏緫銆?*/
} else {
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
node->right = RBDelete(node->right, key);
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
return RBFixUp(node);
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細瀹氫箟鍑芥暟 ㈠紑濮嬪啓杩欎釜鍑芥暟鐨勫叿浣撳疄鐜般€?*/
void RBInorder(const RBNode *root) {
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭璧板摢涓垎鏀€?*/
if (root == NULL) {
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
return;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細璋冪敤涓€涓嚱鏁帮紝璁╁畠甯垜浠畬鎴愬綋鍓嶈繖涓€姝ユ搷浣溿€?*/
RBInorder(root->left);
/* 绗?{number}琛岋細鎶婂綋鍓嶇粨鏋滄墦鍗板嚭鏉ワ紝鏂逛究瑙傚療绋嬪簭杩愯鎯呭喌銆?*/
printf("%d(%c) ", root->key, root->color == RB_RED ? 'R' : 'B');
/* 绗?{number}琛岋細璋冪敤涓€涓嚱鏁帮紝璁╁畠甯垜浠畬鎴愬綋鍓嶈繖涓€姝ユ搷浣溿€?*/
RBInorder(root->right);
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細瀹氫箟鍑芥暟 ㈠紑濮嬪啓杩欎釜鍑芥暟鐨勫叿浣撳疄鐜般€?*/
void DestroyRB(RBNode *root) {
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭璧板摢涓垎鏀€?*/
if (root == NULL) {
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
return;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細璋冪敤涓€涓嚱鏁帮紝璁╁畠甯垜浠畬鎴愬綋鍓嶈繖涓€姝ユ搷浣溿€?*/
DestroyRB(root->left);
/* 绗?{number}琛岋細璋冪敤涓€涓嚱鏁帮紝璁╁畠甯垜浠畬鎴愬綋鍓嶈繖涓€姝ユ搷浣溿€?*/
DestroyRB(root->right);
/* 绗?{number}琛岋細璋冪敤涓€涓嚱鏁帮紝璁╁畠甯垜浠畬鎴愬綋鍓嶈繖涓€姝ユ搷浣溿€?*/
free(root);
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細鎵ц杩欎竴琛屼唬鐮侊紝缁х画鎺ㄨ繘褰撳墠閫昏緫銆?*/
BTreeNode *CreateBTreeNode(bool leaf) {
/* 绗?{number}琛岋細鎵ц杩欎竴琛屼唬鐮侊紝缁х画鎺ㄨ繘褰撳墠閫昏緫銆?*/
BTreeNode *node;
/* 绗?{number}琛岋細澹版槑褰撳墠璇彞鍚庨潰瑕佷娇鐢ㄧ殑鍙橀噺銆佹寚閽堟垨灞€閮ㄦ暟鎹€?*/
int i;
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
node = (BTreeNode *)malloc(sizeof(BTreeNode));
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭璧板摢涓垎鏀€?*/
if (node == NULL) {
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
return NULL;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
node->key_count = 0;
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
node->leaf = leaf;
/* 绗?{number}琛岋細寮€濮嬩竴娆?for 寰幆锛屾寜鍥哄畾娆℃暟鎴栧尯闂撮噸澶嶆墽琛屽悗缁鍙ャ€?*/
for (i = 0; i < BTREE_MAX_CHILDREN; i++) {
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
node->children[i] = NULL;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
return node;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細鎵ц杩欎竴琛屼唬鐮侊紝缁х画鎺ㄨ繘褰撳墠閫昏緫銆?*/
BTreeNode *BTreeSearch(BTreeNode *root, int key, int *index) {
/* 绗?{number}琛岋細澹版槑褰撳墠璇彞鍚庨潰瑕佷娇鐢ㄧ殑鍙橀噺銆佹寚閽堟垨灞€閮ㄦ暟鎹€?*/
int i;
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭璧板摢涓垎鏀€?*/
if (root == NULL) {
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
return NULL;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
i = 0;
/* 绗?{number}琛岋細寮€濮嬩竴娆?while 寰幆锛屽彧瑕佹潯浠舵垚绔嬪氨缁х画鎵ц銆?*/
while (i < root->key_count && key > root->keys[i]) {
/* 绗?{number}琛岋細鎵ц杩欎竴琛屼唬鐮侊紝缁х画鎺ㄨ繘褰撳墠閫昏緫銆?*/
i++;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭璧板摢涓垎鏀€?*/
if (i < root->key_count && key == root->keys[i]) {
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭璧板摢涓垎鏀€?*/
if (index != NULL) {
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
*index = i;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
return root;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭璧板摢涓垎鏀€?*/
if (root->leaf) {
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
return NULL;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
return BTreeSearch(root->children[i], key, index);
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細瀹氫箟鍑芥暟 ㈠紑濮嬪啓杩欎釜鍑芥暟鐨勫叿浣撳疄鐜般€?*/
void BTreeSplitChild(BTreeNode *parent, int child_index) {
/* 绗?{number}琛岋細鎵ц杩欎竴琛屼唬鐮侊紝缁х画鎺ㄨ繘褰撳墠閫昏緫銆?*/
BTreeNode *full_child;
/* 绗?{number}琛岋細鎵ц杩欎竴琛屼唬鐮侊紝缁х画鎺ㄨ繘褰撳墠閫昏緫銆?*/
BTreeNode *new_child;
/* 绗?{number}琛岋細澹版槑褰撳墠璇彞鍚庨潰瑕佷娇鐢ㄧ殑鍙橀噺銆佹寚閽堟垨灞€閮ㄦ暟鎹€?*/
int i;
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
full_child = parent->children[child_index];
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
new_child = CreateBTreeNode(full_child->leaf);
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭璧板摢涓垎鏀€?*/
if (new_child == NULL) {
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
return;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
new_child->key_count = BTREE_MIN_DEGREE - 1;
/* 绗?{number}琛岋細寮€濮嬩竴娆?for 寰幆锛屾寜鍥哄畾娆℃暟鎴栧尯闂撮噸澶嶆墽琛屽悗缁鍙ャ€?*/
for (i = 0; i < BTREE_MIN_DEGREE - 1; i++) {
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
new_child->keys[i] = full_child->keys[i + BTREE_MIN_DEGREE];
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭璧板摢涓垎鏀€?*/
if (!full_child->leaf) {
/* 绗?{number}琛岋細寮€濮嬩竴娆?for 寰幆锛屾寜鍥哄畾娆℃暟鎴栧尯闂撮噸澶嶆墽琛屽悗缁鍙ャ€?*/
for (i = 0; i < BTREE_MIN_DEGREE; i++) {
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
new_child->children[i] = full_child->children[i + BTREE_MIN_DEGREE];
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
full_child->key_count = BTREE_MIN_DEGREE - 1;
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細寮€濮嬩竴娆?for 寰幆锛屾寜鍥哄畾娆℃暟鎴栧尯闂撮噸澶嶆墽琛屽悗缁鍙ャ€?*/
for (i = parent->key_count; i >= child_index + 1; i--) {
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
parent->children[i + 1] = parent->children[i];
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
parent->children[child_index + 1] = new_child;
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細寮€濮嬩竴娆?for 寰幆锛屾寜鍥哄畾娆℃暟鎴栧尯闂撮噸澶嶆墽琛屽悗缁鍙ャ€?*/
for (i = parent->key_count - 1; i >= child_index; i--) {
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
parent->keys[i + 1] = parent->keys[i];
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
parent->keys[child_index] = full_child->keys[BTREE_MIN_DEGREE - 1];
/* 绗?{number}琛岋細鎵ц杩欎竴琛屼唬鐮侊紝缁х画鎺ㄨ繘褰撳墠閫昏緫銆?*/
parent->key_count++;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細瀹氫箟鍑芥暟 ㈠紑濮嬪啓杩欎釜鍑芥暟鐨勫叿浣撳疄鐜般€?*/
void BTreeInsertNonFull(BTreeNode *node, int key) {
/* 绗?{number}琛岋細澹版槑褰撳墠璇彞鍚庨潰瑕佷娇鐢ㄧ殑鍙橀噺銆佹寚閽堟垨灞€閮ㄦ暟鎹€?*/
int i;
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
i = node->key_count - 1;
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭璧板摢涓垎鏀€?*/
if (node->leaf) {
/* 绗?{number}琛岋細寮€濮嬩竴娆?while 寰幆锛屽彧瑕佹潯浠舵垚绔嬪氨缁х画鎵ц銆?*/
while (i >= 0 && key < node->keys[i]) {
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
node->keys[i + 1] = node->keys[i];
/* 绗?{number}琛岋細鎵ц杩欎竴琛屼唬鐮侊紝缁х画鎺ㄨ繘褰撳墠閫昏緫銆?*/
i--;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
node->keys[i + 1] = key;
/* 绗?{number}琛岋細鎵ц杩欎竴琛屼唬鐮侊紝缁х画鎺ㄨ繘褰撳墠閫昏緫銆?*/
node->key_count++;
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
return;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細寮€濮嬩竴娆?while 寰幆锛屽彧瑕佹潯浠舵垚绔嬪氨缁х画鎵ц銆?*/
while (i >= 0 && key < node->keys[i]) {
/* 绗?{number}琛岋細鎵ц杩欎竴琛屼唬鐮侊紝缁х画鎺ㄨ繘褰撳墠閫昏緫銆?*/
i--;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細鎵ц杩欎竴琛屼唬鐮侊紝缁х画鎺ㄨ繘褰撳墠閫昏緫銆?*/
i++;
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭璧板摢涓垎鏀€?*/
if (node->children[i] != NULL && node->children[i]->key_count == BTREE_MAX_KEYS) {
/* 绗?{number}琛岋細璋冪敤涓€涓嚱鏁帮紝璁╁畠甯垜浠畬鎴愬綋鍓嶈繖涓€姝ユ搷浣溿€?*/
BTreeSplitChild(node, i);
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭璧板摢涓垎鏀€?*/
if (key > node->keys[i]) {
/* 绗?{number}琛岋細鎵ц杩欎竴琛屼唬鐮侊紝缁х画鎺ㄨ繘褰撳墠閫昏緫銆?*/
i++;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細璋冪敤涓€涓嚱鏁帮紝璁╁畠甯垜浠畬鎴愬綋鍓嶈繖涓€姝ユ搷浣溿€?*/
BTreeInsertNonFull(node->children[i], key);
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細鎵ц杩欎竴琛屼唬鐮侊紝缁х画鎺ㄨ繘褰撳墠閫昏緫銆?*/
BTreeNode *BTreeInsert(BTreeNode *root, int key) {
/* 绗?{number}琛岋細鎵ц杩欎竴琛屼唬鐮侊紝缁х画鎺ㄨ繘褰撳墠閫昏緫銆?*/
BTreeNode *new_root;
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭璧板摢涓垎鏀€?*/
if (root == NULL) {
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
root = CreateBTreeNode(true);
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭璧板摢涓垎鏀€?*/
if (root == NULL) {
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
return NULL;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
root->keys[0] = key;
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
root->key_count = 1;
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
return root;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭璧板摢涓垎鏀€?*/
if (root->key_count == BTREE_MAX_KEYS) {
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
new_root = CreateBTreeNode(false);
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭璧板摢涓垎鏀€?*/
if (new_root == NULL) {
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
return root;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
new_root->children[0] = root;
/* 绗?{number}琛岋細璋冪敤涓€涓嚱鏁帮紝璁╁畠甯垜浠畬鎴愬綋鍓嶈繖涓€姝ユ搷浣溿€?*/
BTreeSplitChild(new_root, 0);
/* 绗?{number}琛岋細璋冪敤涓€涓嚱鏁帮紝璁╁畠甯垜浠畬鎴愬綋鍓嶈繖涓€姝ユ搷浣溿€?*/
BTreeInsertNonFull(new_root, key);
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
return new_root;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細璋冪敤涓€涓嚱鏁帮紝璁╁畠甯垜浠畬鎴愬綋鍓嶈繖涓€姝ユ搷浣溿€?*/
BTreeInsertNonFull(root, key);
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
return root;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細瀹氫箟鍑芥暟 ㈠紑濮嬪啓杩欎釜鍑芥暟鐨勫叿浣撳疄鐜般€?*/
int BTreeFindKey(const BTreeNode *node, int key) {
/* 绗?{number}琛岋細澹版槑褰撳墠璇彞鍚庨潰瑕佷娇鐢ㄧ殑鍙橀噺銆佹寚閽堟垨灞€閮ㄦ暟鎹€?*/
int index;
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
index = 0;
/* 绗?{number}琛岋細寮€濮嬩竴娆?while 寰幆锛屽彧瑕佹潯浠舵垚绔嬪氨缁х画鎵ц銆?*/
while (index < node->key_count && node->keys[index] < key) {
/* 绗?{number}琛岋細鎵ц杩欎竴琛屼唬鐮侊紝缁х画鎺ㄨ繘褰撳墠閫昏緫銆?*/
index++;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
return index;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細瀹氫箟鍑芥暟 ㈠紑濮嬪啓杩欎釜鍑芥暟鐨勫叿浣撳疄鐜般€?*/
int BTreeGetPredecessor(BTreeNode *node) {
/* 绗?{number}琛岋細鎵ц杩欎竴琛屼唬鐮侊紝缁х画鎺ㄨ繘褰撳墠閫昏緫銆?*/
BTreeNode *current;
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
current = node;
/* 绗?{number}琛岋細寮€濮嬩竴娆?while 寰幆锛屽彧瑕佹潯浠舵垚绔嬪氨缁х画鎵ц銆?*/
while (!current->leaf) {
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
current = current->children[current->key_count];
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
return current->keys[current->key_count - 1];
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細瀹氫箟鍑芥暟 ㈠紑濮嬪啓杩欎釜鍑芥暟鐨勫叿浣撳疄鐜般€?*/
int BTreeGetSuccessor(BTreeNode *node) {
/* 绗?{number}琛岋細鎵ц杩欎竴琛屼唬鐮侊紝缁х画鎺ㄨ繘褰撳墠閫昏緫銆?*/
BTreeNode *current;
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
current = node;
/* 绗?{number}琛岋細寮€濮嬩竴娆?while 寰幆锛屽彧瑕佹潯浠舵垚绔嬪氨缁х画鎵ц銆?*/
while (!current->leaf) {
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
current = current->children[0];
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
return current->keys[0];
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細瀹氫箟鍑芥暟 ㈠紑濮嬪啓杩欎釜鍑芥暟鐨勫叿浣撳疄鐜般€?*/
void BTreeMergeChildren(BTreeNode *node, int index) {
/* 绗?{number}琛岋細鎵ц杩欎竴琛屼唬鐮侊紝缁х画鎺ㄨ繘褰撳墠閫昏緫銆?*/
BTreeNode *left_child;
/* 绗?{number}琛岋細鎵ц杩欎竴琛屼唬鐮侊紝缁х画鎺ㄨ繘褰撳墠閫昏緫銆?*/
BTreeNode *right_child;
/* 绗?{number}琛岋細澹版槑褰撳墠璇彞鍚庨潰瑕佷娇鐢ㄧ殑鍙橀噺銆佹寚閽堟垨灞€閮ㄦ暟鎹€?*/
int i;
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
left_child = node->children[index];
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
right_child = node->children[index + 1];
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭璧板摢涓垎鏀€?*/
if (left_child == NULL || right_child == NULL) {
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
return;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
left_child->keys[BTREE_MIN_DEGREE - 1] = node->keys[index];
/* 绗?{number}琛岋細寮€濮嬩竴娆?for 寰幆锛屾寜鍥哄畾娆℃暟鎴栧尯闂撮噸澶嶆墽琛屽悗缁鍙ャ€?*/
for (i = 0; i < right_child->key_count; i++) {
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
left_child->keys[i + BTREE_MIN_DEGREE] = right_child->keys[i];
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭璧板摢涓垎鏀€?*/
if (!left_child->leaf) {
/* 绗?{number}琛岋細寮€濮嬩竴娆?for 寰幆锛屾寜鍥哄畾娆℃暟鎴栧尯闂撮噸澶嶆墽琛屽悗缁鍙ャ€?*/
for (i = 0; i <= right_child->key_count; i++) {
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
left_child->children[i + BTREE_MIN_DEGREE] = right_child->children[i];
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
left_child->key_count += right_child->key_count + 1;
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細寮€濮嬩竴娆?for 寰幆锛屾寜鍥哄畾娆℃暟鎴栧尯闂撮噸澶嶆墽琛屽悗缁鍙ャ€?*/
for (i = index + 1; i < node->key_count; i++) {
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
node->keys[i - 1] = node->keys[i];
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細寮€濮嬩竴娆?for 寰幆锛屾寜鍥哄畾娆℃暟鎴栧尯闂撮噸澶嶆墽琛屽悗缁鍙ャ€?*/
for (i = index + 2; i <= node->key_count; i++) {
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
node->children[i - 1] = node->children[i];
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細鎵ц杩欎竴琛屼唬鐮侊紝缁х画鎺ㄨ繘褰撳墠閫昏緫銆?*/
node->key_count--;
/* 绗?{number}琛岋細璋冪敤涓€涓嚱鏁帮紝璁╁畠甯垜浠畬鎴愬綋鍓嶈繖涓€姝ユ搷浣溿€?*/
free(right_child);
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細瀹氫箟鍑芥暟 ㈠紑濮嬪啓杩欎釜鍑芥暟鐨勫叿浣撳疄鐜般€?*/
void BTreeBorrowFromPrev(BTreeNode *node, int index) {
/* 绗?{number}琛岋細鎵ц杩欎竴琛屼唬鐮侊紝缁х画鎺ㄨ繘褰撳墠閫昏緫銆?*/
BTreeNode *child;
/* 绗?{number}琛岋細鎵ц杩欎竴琛屼唬鐮侊紝缁х画鎺ㄨ繘褰撳墠閫昏緫銆?*/
BTreeNode *sibling;
/* 绗?{number}琛岋細澹版槑褰撳墠璇彞鍚庨潰瑕佷娇鐢ㄧ殑鍙橀噺銆佹寚閽堟垨灞€閮ㄦ暟鎹€?*/
int i;
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
child = node->children[index];
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
sibling = node->children[index - 1];
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭璧板摢涓垎鏀€?*/
if (child == NULL || sibling == NULL) {
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
return;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細寮€濮嬩竴娆?for 寰幆锛屾寜鍥哄畾娆℃暟鎴栧尯闂撮噸澶嶆墽琛屽悗缁鍙ャ€?*/
for (i = child->key_count - 1; i >= 0; i--) {
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
child->keys[i + 1] = child->keys[i];
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭璧板摢涓垎鏀€?*/
if (!child->leaf) {
/* 绗?{number}琛岋細寮€濮嬩竴娆?for 寰幆锛屾寜鍥哄畾娆℃暟鎴栧尯闂撮噸澶嶆墽琛屽悗缁鍙ャ€?*/
for (i = child->key_count; i >= 0; i--) {
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
child->children[i + 1] = child->children[i];
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
child->keys[0] = node->keys[index - 1];
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭璧板摢涓垎鏀€?*/
if (!child->leaf) {
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
child->children[0] = sibling->children[sibling->key_count];
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
node->keys[index - 1] = sibling->keys[sibling->key_count - 1];
/* 绗?{number}琛岋細鎵ц杩欎竴琛屼唬鐮侊紝缁х画鎺ㄨ繘褰撳墠閫昏緫銆?*/
child->key_count++;
/* 绗?{number}琛岋細鎵ц杩欎竴琛屼唬鐮侊紝缁х画鎺ㄨ繘褰撳墠閫昏緫銆?*/
sibling->key_count--;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細瀹氫箟鍑芥暟 ㈠紑濮嬪啓杩欎釜鍑芥暟鐨勫叿浣撳疄鐜般€?*/
void BTreeBorrowFromNext(BTreeNode *node, int index) {
/* 绗?{number}琛岋細鎵ц杩欎竴琛屼唬鐮侊紝缁х画鎺ㄨ繘褰撳墠閫昏緫銆?*/
BTreeNode *child;
/* 绗?{number}琛岋細鎵ц杩欎竴琛屼唬鐮侊紝缁х画鎺ㄨ繘褰撳墠閫昏緫銆?*/
BTreeNode *sibling;
/* 绗?{number}琛岋細澹版槑褰撳墠璇彞鍚庨潰瑕佷娇鐢ㄧ殑鍙橀噺銆佹寚閽堟垨灞€閮ㄦ暟鎹€?*/
int i;
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
child = node->children[index];
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
sibling = node->children[index + 1];
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭璧板摢涓垎鏀€?*/
if (child == NULL || sibling == NULL) {
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
return;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
child->keys[child->key_count] = node->keys[index];
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭璧板摢涓垎鏀€?*/
if (!child->leaf) {
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
child->children[child->key_count + 1] = sibling->children[0];
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
node->keys[index] = sibling->keys[0];
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細寮€濮嬩竴娆?for 寰幆锛屾寜鍥哄畾娆℃暟鎴栧尯闂撮噸澶嶆墽琛屽悗缁鍙ャ€?*/
for (i = 1; i < sibling->key_count; i++) {
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
sibling->keys[i - 1] = sibling->keys[i];
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭璧板摢涓垎鏀€?*/
if (!sibling->leaf) {
/* 绗?{number}琛岋細寮€濮嬩竴娆?for 寰幆锛屾寜鍥哄畾娆℃暟鎴栧尯闂撮噸澶嶆墽琛屽悗缁鍙ャ€?*/
for (i = 1; i <= sibling->key_count; i++) {
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
sibling->children[i - 1] = sibling->children[i];
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細鎵ц杩欎竴琛屼唬鐮侊紝缁х画鎺ㄨ繘褰撳墠閫昏緫銆?*/
child->key_count++;
/* 绗?{number}琛岋細鎵ц杩欎竴琛屼唬鐮侊紝缁х画鎺ㄨ繘褰撳墠閫昏緫銆?*/
sibling->key_count--;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細瀹氫箟鍑芥暟 ㈠紑濮嬪啓杩欎釜鍑芥暟鐨勫叿浣撳疄鐜般€?*/
void BTreeFillChild(BTreeNode *node, int index) {
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭璧板摢涓垎鏀€?*/
if (index > 0 && node->children[index - 1] != NULL &&
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
node->children[index - 1]->key_count >= BTREE_MIN_DEGREE) {
/* 绗?{number}琛岋細璋冪敤涓€涓嚱鏁帮紝璁╁畠甯垜浠畬鎴愬綋鍓嶈繖涓€姝ユ搷浣溿€?*/
BTreeBorrowFromPrev(node, index);
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
} else if (index < node->key_count && node->children[index + 1] != NULL &&
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
node->children[index + 1]->key_count >= BTREE_MIN_DEGREE) {
/* 绗?{number}琛岋細璋冪敤涓€涓嚱鏁帮紝璁╁畠甯垜浠畬鎴愬綋鍓嶈繖涓€姝ユ搷浣溿€?*/
BTreeBorrowFromNext(node, index);
/* 绗?{number}琛岋細鎵ц杩欎竴琛屼唬鐮侊紝缁х画鎺ㄨ繘褰撳墠閫昏緫銆?*/
} else if (index < node->key_count) {
/* 绗?{number}琛岋細璋冪敤涓€涓嚱鏁帮紝璁╁畠甯垜浠畬鎴愬綋鍓嶈繖涓€姝ユ搷浣溿€?*/
BTreeMergeChildren(node, index);
/* 绗?{number}琛岋細鎵ц杩欎竴琛屼唬鐮侊紝缁х画鎺ㄨ繘褰撳墠閫昏緫銆?*/
} else {
/* 绗?{number}琛岋細璋冪敤涓€涓嚱鏁帮紝璁╁畠甯垜浠畬鎴愬綋鍓嶈繖涓€姝ユ搷浣溿€?*/
BTreeMergeChildren(node, index - 1);
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細瀹氫箟鍑芥暟 ㈠紑濮嬪啓杩欎釜鍑芥暟鐨勫叿浣撳疄鐜般€?*/
void BTreeDeleteFromNode(BTreeNode *node, int key) {
/* 绗?{number}琛岋細澹版槑褰撳墠璇彞鍚庨潰瑕佷娇鐢ㄧ殑鍙橀噺銆佹寚閽堟垨灞€閮ㄦ暟鎹€?*/
int index;
/* 绗?{number}琛岋細澹版槑褰撳墠璇彞鍚庨潰瑕佷娇鐢ㄧ殑鍙橀噺銆佹寚閽堟垨灞€閮ㄦ暟鎹€?*/
int predecessor;
/* 绗?{number}琛岋細澹版槑褰撳墠璇彞鍚庨潰瑕佷娇鐢ㄧ殑鍙橀噺銆佹寚閽堟垨灞€閮ㄦ暟鎹€?*/
int successor;
/* 绗?{number}琛岋細澹版槑褰撳墠璇彞鍚庨潰瑕佷娇鐢ㄧ殑鍙橀噺銆佹寚閽堟垨灞€閮ㄦ暟鎹€?*/
bool at_end;
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭璧板摢涓垎鏀€?*/
if (node == NULL) {
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
return;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
index = BTreeFindKey(node, key);
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭璧板摢涓垎鏀€?*/
if (index < node->key_count && node->keys[index] == key) {
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭璧板摢涓垎鏀€?*/
if (node->leaf) {
/* 绗?{number}琛岋細寮€濮嬩竴娆?for 寰幆锛屾寜鍥哄畾娆℃暟鎴栧尯闂撮噸澶嶆墽琛屽悗缁鍙ャ€?*/
for (; index + 1 < node->key_count; index++) {
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
node->keys[index] = node->keys[index + 1];
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細鎵ц杩欎竴琛屼唬鐮侊紝缁х画鎺ㄨ繘褰撳墠閫昏緫銆?*/
node->key_count--;
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
return;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭璧板摢涓垎鏀€?*/
if (node->children[index] != NULL &&
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
node->children[index]->key_count >= BTREE_MIN_DEGREE) {
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
predecessor = BTreeGetPredecessor(node->children[index]);
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
node->keys[index] = predecessor;
/* 绗?{number}琛岋細璋冪敤涓€涓嚱鏁帮紝璁╁畠甯垜浠畬鎴愬綋鍓嶈繖涓€姝ユ搷浣溿€?*/
BTreeDeleteFromNode(node->children[index], predecessor);
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
} else if (node->children[index + 1] != NULL &&
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
node->children[index + 1]->key_count >= BTREE_MIN_DEGREE) {
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
successor = BTreeGetSuccessor(node->children[index + 1]);
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
node->keys[index] = successor;
/* 绗?{number}琛岋細璋冪敤涓€涓嚱鏁帮紝璁╁畠甯垜浠畬鎴愬綋鍓嶈繖涓€姝ユ搷浣溿€?*/
BTreeDeleteFromNode(node->children[index + 1], successor);
/* 绗?{number}琛岋細鎵ц杩欎竴琛屼唬鐮侊紝缁х画鎺ㄨ繘褰撳墠閫昏緫銆?*/
} else {
/* 绗?{number}琛岋細璋冪敤涓€涓嚱鏁帮紝璁╁畠甯垜浠畬鎴愬綋鍓嶈繖涓€姝ユ搷浣溿€?*/
BTreeMergeChildren(node, index);
/* 绗?{number}琛岋細璋冪敤涓€涓嚱鏁帮紝璁╁畠甯垜浠畬鎴愬綋鍓嶈繖涓€姝ユ搷浣溿€?*/
BTreeDeleteFromNode(node->children[index], key);
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
return;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭璧板摢涓垎鏀€?*/
if (node->leaf) {
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
return;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細鎵ц杩欎竴琛屼唬鐮侊紝缁х画鎺ㄨ繘褰撳墠閫昏緫銆?*/
at_end = index == node->key_count;
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭璧板摢涓垎鏀€?*/
if (node->children[index] != NULL &&
/* 绗?{number}琛岋細鎵ц杩欎竴琛屼唬鐮侊紝缁х画鎺ㄨ繘褰撳墠閫昏緫銆?*/
node->children[index]->key_count < BTREE_MIN_DEGREE) {
/* 绗?{number}琛岋細璋冪敤涓€涓嚱鏁帮紝璁╁畠甯垜浠畬鎴愬綋鍓嶈繖涓€姝ユ搷浣溿€?*/
BTreeFillChild(node, index);
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭璧板摢涓垎鏀€?*/
if (at_end && index > node->key_count) {
/* 绗?{number}琛岋細璋冪敤涓€涓嚱鏁帮紝璁╁畠甯垜浠畬鎴愬綋鍓嶈繖涓€姝ユ搷浣溿€?*/
BTreeDeleteFromNode(node->children[index - 1], key);
/* 绗?{number}琛岋細鎵ц杩欎竴琛屼唬鐮侊紝缁х画鎺ㄨ繘褰撳墠閫昏緫銆?*/
} else {
/* 绗?{number}琛岋細璋冪敤涓€涓嚱鏁帮紝璁╁畠甯垜浠畬鎴愬綋鍓嶈繖涓€姝ユ搷浣溿€?*/
BTreeDeleteFromNode(node->children[index], key);
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細鎵ц杩欎竴琛屼唬鐮侊紝缁х画鎺ㄨ繘褰撳墠閫昏緫銆?*/
BTreeNode *BTreeDelete(BTreeNode *root, int key) {
/* 绗?{number}琛岋細鎵ц杩欎竴琛屼唬鐮侊紝缁х画鎺ㄨ繘褰撳墠閫昏緫銆?*/
BTreeNode *new_root;
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭璧板摢涓垎鏀€?*/
if (root == NULL) {
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
return NULL;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細璋冪敤涓€涓嚱鏁帮紝璁╁畠甯垜浠畬鎴愬綋鍓嶈繖涓€姝ユ搷浣溿€?*/
BTreeDeleteFromNode(root, key);
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭璧板摢涓垎鏀€?*/
if (root->key_count > 0) {
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
return root;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭璧板摢涓垎鏀€?*/
if (root->leaf) {
/* 绗?{number}琛岋細璋冪敤涓€涓嚱鏁帮紝璁╁畠甯垜浠畬鎴愬綋鍓嶈繖涓€姝ユ搷浣溿€?*/
free(root);
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
return NULL;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
new_root = root->children[0];
/* 绗?{number}琛岋細璋冪敤涓€涓嚱鏁帮紝璁╁畠甯垜浠畬鎴愬綋鍓嶈繖涓€姝ユ搷浣溿€?*/
free(root);
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
return new_root;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細瀹氫箟鍑芥暟 ㈠紑濮嬪啓杩欎釜鍑芥暟鐨勫叿浣撳疄鐜般€?*/
void BTreePrint(const BTreeNode *root, int depth) {
/* 绗?{number}琛岋細澹版槑褰撳墠璇彞鍚庨潰瑕佷娇鐢ㄧ殑鍙橀噺銆佹寚閽堟垨灞€閮ㄦ暟鎹€?*/
int i;
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭璧板摢涓垎鏀€?*/
if (root == NULL) {
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
return;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細寮€濮嬩竴娆?for 寰幆锛屾寜鍥哄畾娆℃暟鎴栧尯闂撮噸澶嶆墽琛屽悗缁鍙ャ€?*/
for (i = 0; i < depth; i++) {
/* 绗?{number}琛岋細鎶婂綋鍓嶇粨鏋滄墦鍗板嚭鏉ワ紝鏂逛究瑙傚療绋嬪簭杩愯鎯呭喌銆?*/
printf(" ");
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細鎶婂綋鍓嶇粨鏋滄墦鍗板嚭鏉ワ紝鏂逛究瑙傚療绋嬪簭杩愯鎯呭喌銆?*/
printf("[");
/* 绗?{number}琛岋細寮€濮嬩竴娆?for 寰幆锛屾寜鍥哄畾娆℃暟鎴栧尯闂撮噸澶嶆墽琛屽悗缁鍙ャ€?*/
for (i = 0; i < root->key_count; i++) {
/* 绗?{number}琛岋細鎶婂綋鍓嶇粨鏋滄墦鍗板嚭鏉ワ紝鏂逛究瑙傚療绋嬪簭杩愯鎯呭喌銆?*/
printf("%d", root->keys[i]);
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭璧板摢涓垎鏀€?*/
if (i + 1 < root->key_count) {
/* 绗?{number}琛岋細鎶婂綋鍓嶇粨鏋滄墦鍗板嚭鏉ワ紝鏂逛究瑙傚療绋嬪簭杩愯鎯呭喌銆?*/
printf(" ");
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細鎶婂綋鍓嶇粨鏋滄墦鍗板嚭鏉ワ紝鏂逛究瑙傚療绋嬪簭杩愯鎯呭喌銆?*/
printf("]\n");
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭璧板摢涓垎鏀€?*/
if (!root->leaf) {
/* 绗?{number}琛岋細寮€濮嬩竴娆?for 寰幆锛屾寜鍥哄畾娆℃暟鎴栧尯闂撮噸澶嶆墽琛屽悗缁鍙ャ€?*/
for (i = 0; i <= root->key_count; i++) {
/* 绗?{number}琛岋細璋冪敤涓€涓嚱鏁帮紝璁╁畠甯垜浠畬鎴愬綋鍓嶈繖涓€姝ユ搷浣溿€?*/
BTreePrint(root->children[i], depth + 1);
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細瀹氫箟鍑芥暟 ㈠紑濮嬪啓杩欎釜鍑芥暟鐨勫叿浣撳疄鐜般€?*/
void DestroyBTree(BTreeNode *root) {
/* 绗?{number}琛岋細澹版槑褰撳墠璇彞鍚庨潰瑕佷娇鐢ㄧ殑鍙橀噺銆佹寚閽堟垨灞€閮ㄦ暟鎹€?*/
int i;
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭璧板摢涓垎鏀€?*/
if (root == NULL) {
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
return;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭璧板摢涓垎鏀€?*/
if (!root->leaf) {
/* 绗?{number}琛岋細寮€濮嬩竴娆?for 寰幆锛屾寜鍥哄畾娆℃暟鎴栧尯闂撮噸澶嶆墽琛屽悗缁鍙ャ€?*/
for (i = 0; i <= root->key_count; i++) {
/* 绗?{number}琛岋細璋冪敤涓€涓嚱鏁帮紝璁╁畠甯垜浠畬鎴愬綋鍓嶈繖涓€姝ユ搷浣溿€?*/
DestroyBTree(root->children[i]);
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細璋冪敤涓€涓嚱鏁帮紝璁╁畠甯垜浠畬鎴愬綋鍓嶈繖涓€姝ユ搷浣溿€?*/
free(root);
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細鎵ц杩欎竴琛屼唬鐮侊紝缁х画鎺ㄨ繘褰撳墠閫昏緫銆?*/
BPlusNode *CreateBPlusNode(bool leaf) {
/* 绗?{number}琛岋細鎵ц杩欎竴琛屼唬鐮侊紝缁х画鎺ㄨ繘褰撳墠閫昏緫銆?*/
BPlusNode *node;
/* 绗?{number}琛岋細澹版槑褰撳墠璇彞鍚庨潰瑕佷娇鐢ㄧ殑鍙橀噺銆佹寚閽堟垨灞€閮ㄦ暟鎹€?*/
int i;
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
node = (BPlusNode *)malloc(sizeof(BPlusNode));
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭璧板摢涓垎鏀€?*/
if (node == NULL) {
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
return NULL;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
node->leaf = leaf;
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
node->key_count = 0;
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
node->next = NULL;
/* 绗?{number}琛岋細寮€濮嬩竴娆?for 寰幆锛屾寜鍥哄畾娆℃暟鎴栧尯闂撮噸澶嶆墽琛屽悗缁鍙ャ€?*/
for (i = 0; i < BTREE_MAX_CHILDREN + 1; i++) {
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
node->children[i] = NULL;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
return node;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細鎵ц杩欎竴琛屼唬鐮侊紝缁х画鎺ㄨ繘褰撳墠閫昏緫銆?*/
BPlusNode *BPlusFindLeaf(BPlusNode *root, int key);
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細瀹氫箟鍑芥暟 ㈠紑濮嬪啓杩欎釜鍑芥暟鐨勫叿浣撳疄鐜般€?*/
int BPlusFirstKey(BPlusNode *node) {
/* 绗?{number}琛岋細鎵ц杩欎竴琛屼唬鐮侊紝缁х画鎺ㄨ繘褰撳墠閫昏緫銆?*/
BPlusNode *current;
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
current = node;
/* 绗?{number}琛岋細寮€濮嬩竴娆?while 寰幆锛屽彧瑕佹潯浠舵垚绔嬪氨缁х画鎵ц銆?*/
while (current != NULL && !current->leaf) {
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
current = current->children[0];
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭璧板摢涓垎鏀€?*/
if (current == NULL || current->key_count == 0) {
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
return 0;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
return current->keys[0];
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細瀹氫箟鍑芥暟 ㈠紑濮嬪啓杩欎釜鍑芥暟鐨勫叿浣撳疄鐜般€?*/
void BPlusRefreshKeys(BPlusNode *node) {
/* 绗?{number}琛岋細澹版槑褰撳墠璇彞鍚庨潰瑕佷娇鐢ㄧ殑鍙橀噺銆佹寚閽堟垨灞€閮ㄦ暟鎹€?*/
int i;
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭璧板摢涓垎鏀€?*/
if (node == NULL || node->leaf) {
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
return;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細寮€濮嬩竴娆?for 寰幆锛屾寜鍥哄畾娆℃暟鎴栧尯闂撮噸澶嶆墽琛屽悗缁鍙ャ€?*/
for (i = 1; i <= node->key_count; i++) {
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
node->keys[i - 1] = BPlusFirstKey(node->children[i]);
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細瀹氫箟鍑芥暟 ㈠紑濮嬪啓杩欎釜鍑芥暟鐨勫叿浣撳疄鐜般€?*/
void BPlusInsertIntoLeaf(BPlusNode *leaf, int key) {
/* 绗?{number}琛岋細澹版槑褰撳墠璇彞鍚庨潰瑕佷娇鐢ㄧ殑鍙橀噺銆佹寚閽堟垨灞€閮ㄦ暟鎹€?*/
int i;
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
i = leaf->key_count - 1;
/* 绗?{number}琛岋細寮€濮嬩竴娆?while 寰幆锛屽彧瑕佹潯浠舵垚绔嬪氨缁х画鎵ц銆?*/
while (i >= 0 && key < leaf->keys[i]) {
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
leaf->keys[i + 1] = leaf->keys[i];
/* 绗?{number}琛岋細鎵ц杩欎竴琛屼唬鐮侊紝缁х画鎺ㄨ繘褰撳墠閫昏緫銆?*/
i--;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
leaf->keys[i + 1] = key;
/* 绗?{number}琛岋細鎵ц杩欎竴琛屼唬鐮侊紝缁х画鎺ㄨ繘褰撳墠閫昏緫銆?*/
leaf->key_count++;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細瀹氫箟鍑芥暟 ㈠紑濮嬪啓杩欎釜鍑芥暟鐨勫叿浣撳疄鐜般€?*/
bool BPlusInsertRecursive(BPlusNode *node, int key, int *promoted_key, BPlusNode **new_child) {
/* 绗?{number}琛岋細澹版槑褰撳墠璇彞鍚庨潰瑕佷娇鐢ㄧ殑鍙橀噺銆佹寚閽堟垨灞€閮ㄦ暟鎹€?*/
int i;
/* 绗?{number}琛岋細澹版槑褰撳墠璇彞鍚庨潰瑕佷娇鐢ㄧ殑鍙橀噺銆佹寚閽堟垨灞€閮ㄦ暟鎹€?*/
int child_count;
/* 绗?{number}琛岋細澹版槑褰撳墠璇彞鍚庨潰瑕佷娇鐢ㄧ殑鍙橀噺銆佹寚閽堟垨灞€閮ㄦ暟鎹€?*/
int split_index;
/* 绗?{number}琛岋細澹版槑褰撳墠璇彞鍚庨潰瑕佷娇鐢ㄧ殑鍙橀噺銆佹寚閽堟垨灞€閮ㄦ暟鎹€?*/
int right_child_count;
/* 绗?{number}琛岋細鎵ц杩欎竴琛屼唬鐮侊紝缁х画鎺ㄨ繘褰撳墠閫昏緫銆?*/
BPlusNode *right_node;
/* 绗?{number}琛岋細澹版槑褰撳墠璇彞鍚庨潰瑕佷娇鐢ㄧ殑鍙橀噺銆佹寚閽堟垨灞€閮ㄦ暟鎹€?*/
int child_promoted_key;
/* 绗?{number}琛岋細鎵ц杩欎竴琛屼唬鐮侊紝缁х画鎺ㄨ繘褰撳墠閫昏緫銆?*/
BPlusNode *child_new_node;
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭璧板摢涓垎鏀€?*/
if (node == NULL) {
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
return false;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭璧板摢涓垎鏀€?*/
if (node->leaf) {
/* 绗?{number}琛岋細寮€濮嬩竴娆?for 寰幆锛屾寜鍥哄畾娆℃暟鎴栧尯闂撮噸澶嶆墽琛屽悗缁鍙ャ€?*/
for (i = 0; i < node->key_count; i++) {
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭璧板摢涓垎鏀€?*/
if (node->keys[i] == key) {
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
return false;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細璋冪敤涓€涓嚱鏁帮紝璁╁畠甯垜浠畬鎴愬綋鍓嶈繖涓€姝ユ搷浣溿€?*/
BPlusInsertIntoLeaf(node, key);
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭璧板摢涓垎鏀€?*/
if (node->key_count <= BTREE_MAX_KEYS) {
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
return false;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
right_node = CreateBPlusNode(true);
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭璧板摢涓垎鏀€?*/
if (right_node == NULL) {
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
return false;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
split_index = (node->key_count + 1) / 2;
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
right_node->key_count = node->key_count - split_index;
/* 绗?{number}琛岋細寮€濮嬩竴娆?for 寰幆锛屾寜鍥哄畾娆℃暟鎴栧尯闂撮噸澶嶆墽琛屽悗缁鍙ャ€?*/
for (i = 0; i < right_node->key_count; i++) {
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
right_node->keys[i] = node->keys[split_index + i];
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
node->key_count = split_index;
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
right_node->next = node->next;
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
node->next = right_node;
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
*promoted_key = right_node->keys[0];
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
*new_child = right_node;
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
return true;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
i = 0;
/* 绗?{number}琛岋細寮€濮嬩竴娆?while 寰幆锛屽彧瑕佹潯浠舵垚绔嬪氨缁х画鎵ц銆?*/
while (i < node->key_count && key >= node->keys[i]) {
/* 绗?{number}琛岋細鎵ц杩欎竴琛屼唬鐮侊紝缁х画鎺ㄨ繘褰撳墠閫昏緫銆?*/
i++;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
child_new_node = NULL;
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
child_promoted_key = 0;
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭璧板摢涓垎鏀€?*/
if (BPlusInsertRecursive(node->children[i], key, &child_promoted_key, &child_new_node)) {
/* 绗?{number}琛岋細寮€濮嬩竴娆?for 寰幆锛屾寜鍥哄畾娆℃暟鎴栧尯闂撮噸澶嶆墽琛屽悗缁鍙ャ€?*/
for (child_count = node->key_count; child_count >= i; child_count--) {
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
node->keys[child_count] = node->keys[child_count - 1];
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細寮€濮嬩竴娆?for 寰幆锛屾寜鍥哄畾娆℃暟鎴栧尯闂撮噸澶嶆墽琛屽悗缁鍙ャ€?*/
for (child_count = node->key_count + 1; child_count >= i + 1; child_count--) {
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
node->children[child_count + 1] = node->children[child_count];
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
node->children[i + 1] = child_new_node;
/* 绗?{number}琛岋細鎵ц杩欎竴琛屼唬鐮侊紝缁х画鎺ㄨ繘褰撳墠閫昏緫銆?*/
node->key_count++;
/* 绗?{number}琛岋細璋冪敤涓€涓嚱鏁帮紝璁╁畠甯垜浠畬鎴愬綋鍓嶈繖涓€姝ユ搷浣溿€?*/
BPlusRefreshKeys(node);
/* 绗?{number}琛岋細鎵ц杩欎竴琛屼唬鐮侊紝缁х画鎺ㄨ繘褰撳墠閫昏緫銆?*/
} else {
/* 绗?{number}琛岋細璋冪敤涓€涓嚱鏁帮紝璁╁畠甯垜浠畬鎴愬綋鍓嶈繖涓€姝ユ搷浣溿€?*/
BPlusRefreshKeys(node);
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
return false;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭璧板摢涓垎鏀€?*/
if (node->key_count <= BTREE_MAX_KEYS) {
/* 绗?{number}琛岋細璋冪敤涓€涓嚱鏁帮紝璁╁畠甯垜浠畬鎴愬綋鍓嶈繖涓€姝ユ搷浣溿€?*/
BPlusRefreshKeys(node);
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
return false;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
right_node = CreateBPlusNode(false);
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭璧板摢涓垎鏀€?*/
if (right_node == NULL) {
/* 绗?{number}琛岋細璋冪敤涓€涓嚱鏁帮紝璁╁畠甯垜浠畬鎴愬綋鍓嶈繖涓€姝ユ搷浣溿€?*/
BPlusRefreshKeys(node);
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
return false;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
child_count = node->key_count + 1;
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
split_index = 3;
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
right_child_count = child_count - split_index;
/* 绗?{number}琛岋細寮€濮嬩竴娆?for 寰幆锛屾寜鍥哄畾娆℃暟鎴栧尯闂撮噸澶嶆墽琛屽悗缁鍙ャ€?*/
for (i = 0; i < right_child_count; i++) {
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
right_node->children[i] = node->children[split_index + i];
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
node->children[split_index + i] = NULL;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
node->key_count = split_index - 1;
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
right_node->key_count = right_child_count - 1;
/* 绗?{number}琛岋細璋冪敤涓€涓嚱鏁帮紝璁╁畠甯垜浠畬鎴愬綋鍓嶈繖涓€姝ユ搷浣溿€?*/
BPlusRefreshKeys(node);
/* 绗?{number}琛岋細璋冪敤涓€涓嚱鏁帮紝璁╁畠甯垜浠畬鎴愬綋鍓嶈繖涓€姝ユ搷浣溿€?*/
BPlusRefreshKeys(right_node);
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
*promoted_key = BPlusFirstKey(right_node);
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
*new_child = right_node;
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
return true;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細鎵ц杩欎竴琛屼唬鐮侊紝缁х画鎺ㄨ繘褰撳墠閫昏緫銆?*/
BPlusNode *BPlusInsert(BPlusNode *root, int key) {
/* 绗?{number}琛岋細澹版槑褰撳墠璇彞鍚庨潰瑕佷娇鐢ㄧ殑鍙橀噺銆佹寚閽堟垨灞€閮ㄦ暟鎹€?*/
int promoted_key;
/* 绗?{number}琛岋細鎵ц杩欎竴琛屼唬鐮侊紝缁х画鎺ㄨ繘褰撳墠閫昏緫銆?*/
BPlusNode *new_child;
/* 绗?{number}琛岋細鎵ц杩欎竴琛屼唬鐮侊紝缁х画鎺ㄨ繘褰撳墠閫昏緫銆?*/
BPlusNode *new_root;
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭璧板摢涓垎鏀€?*/
if (root == NULL) {
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
root = CreateBPlusNode(true);
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭璧板摢涓垎鏀€?*/
if (root == NULL) {
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
return NULL;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
root->keys[0] = key;
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
root->key_count = 1;
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
return root;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
new_child = NULL;
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
promoted_key = 0;
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭璧板摢涓垎鏀€?*/
if (!BPlusInsertRecursive(root, key, &promoted_key, &new_child)) {
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
return root;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
new_root = CreateBPlusNode(false);
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭璧板摢涓垎鏀€?*/
if (new_root == NULL) {
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
return root;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
new_root->children[0] = root;
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
new_root->children[1] = new_child;
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
new_root->key_count = 1;
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
new_root->keys[0] = promoted_key;
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
return new_root;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細瀹氫箟鍑芥暟 ㈠紑濮嬪啓杩欎釜鍑芥暟鐨勫叿浣撳疄鐜般€?*/
void BPlusBorrowFromPrev(BPlusNode *parent, int index) {
/* 绗?{number}琛岋細鎵ц杩欎竴琛屼唬鐮侊紝缁х画鎺ㄨ繘褰撳墠閫昏緫銆?*/
BPlusNode *child;
/* 绗?{number}琛岋細鎵ц杩欎竴琛屼唬鐮侊紝缁х画鎺ㄨ繘褰撳墠閫昏緫銆?*/
BPlusNode *sibling;
/* 绗?{number}琛岋細澹版槑褰撳墠璇彞鍚庨潰瑕佷娇鐢ㄧ殑鍙橀噺銆佹寚閽堟垨灞€閮ㄦ暟鎹€?*/
int i;
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
child = parent->children[index];
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
sibling = parent->children[index - 1];
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭璧板摢涓垎鏀€?*/
if (child == NULL || sibling == NULL) {
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
return;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭璧板摢涓垎鏀€?*/
if (child->leaf) {
/* 绗?{number}琛岋細寮€濮嬩竴娆?for 寰幆锛屾寜鍥哄畾娆℃暟鎴栧尯闂撮噸澶嶆墽琛屽悗缁鍙ャ€?*/
for (i = child->key_count; i > 0; i--) {
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
child->keys[i] = child->keys[i - 1];
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
child->keys[0] = sibling->keys[sibling->key_count - 1];
/* 绗?{number}琛岋細鎵ц杩欎竴琛屼唬鐮侊紝缁х画鎺ㄨ繘褰撳墠閫昏緫銆?*/
child->key_count++;
/* 绗?{number}琛岋細鎵ц杩欎竴琛屼唬鐮侊紝缁х画鎺ㄨ繘褰撳墠閫昏緫銆?*/
sibling->key_count--;
/* 绗?{number}琛岋細鎵ц杩欎竴琛屼唬鐮侊紝缁х画鎺ㄨ繘褰撳墠閫昏緫銆?*/
} else {
/* 绗?{number}琛岋細寮€濮嬩竴娆?for 寰幆锛屾寜鍥哄畾娆℃暟鎴栧尯闂撮噸澶嶆墽琛屽悗缁鍙ャ€?*/
for (i = child->key_count; i >= 0; i--) {
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
child->children[i + 1] = child->children[i];
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
child->children[0] = sibling->children[sibling->key_count];
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
sibling->children[sibling->key_count] = NULL;
/* 绗?{number}琛岋細鎵ц杩欎竴琛屼唬鐮侊紝缁х画鎺ㄨ繘褰撳墠閫昏緫銆?*/
child->key_count++;
/* 绗?{number}琛岋細鎵ц杩欎竴琛屼唬鐮侊紝缁х画鎺ㄨ繘褰撳墠閫昏緫銆?*/
sibling->key_count--;
/* 绗?{number}琛岋細璋冪敤涓€涓嚱鏁帮紝璁╁畠甯垜浠畬鎴愬綋鍓嶈繖涓€姝ユ搷浣溿€?*/
BPlusRefreshKeys(sibling);
/* 绗?{number}琛岋細璋冪敤涓€涓嚱鏁帮紝璁╁畠甯垜浠畬鎴愬綋鍓嶈繖涓€姝ユ搷浣溿€?*/
BPlusRefreshKeys(child);
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細璋冪敤涓€涓嚱鏁帮紝璁╁畠甯垜浠畬鎴愬綋鍓嶈繖涓€姝ユ搷浣溿€?*/
BPlusRefreshKeys(parent);
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細瀹氫箟鍑芥暟 ㈠紑濮嬪啓杩欎釜鍑芥暟鐨勫叿浣撳疄鐜般€?*/
void BPlusBorrowFromNext(BPlusNode *parent, int index) {
/* 绗?{number}琛岋細鎵ц杩欎竴琛屼唬鐮侊紝缁х画鎺ㄨ繘褰撳墠閫昏緫銆?*/
BPlusNode *child;
/* 绗?{number}琛岋細鎵ц杩欎竴琛屼唬鐮侊紝缁х画鎺ㄨ繘褰撳墠閫昏緫銆?*/
BPlusNode *sibling;
/* 绗?{number}琛岋細澹版槑褰撳墠璇彞鍚庨潰瑕佷娇鐢ㄧ殑鍙橀噺銆佹寚閽堟垨灞€閮ㄦ暟鎹€?*/
int i;
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
child = parent->children[index];
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
sibling = parent->children[index + 1];
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭璧板摢涓垎鏀€?*/
if (child == NULL || sibling == NULL) {
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
return;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭璧板摢涓垎鏀€?*/
if (child->leaf) {
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
child->keys[child->key_count] = sibling->keys[0];
/* 绗?{number}琛岋細鎵ц杩欎竴琛屼唬鐮侊紝缁х画鎺ㄨ繘褰撳墠閫昏緫銆?*/
child->key_count++;
/* 绗?{number}琛岋細寮€濮嬩竴娆?for 寰幆锛屾寜鍥哄畾娆℃暟鎴栧尯闂撮噸澶嶆墽琛屽悗缁鍙ャ€?*/
for (i = 1; i < sibling->key_count; i++) {
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
sibling->keys[i - 1] = sibling->keys[i];
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細鎵ц杩欎竴琛屼唬鐮侊紝缁х画鎺ㄨ繘褰撳墠閫昏緫銆?*/
sibling->key_count--;
/* 绗?{number}琛岋細鎵ц杩欎竴琛屼唬鐮侊紝缁х画鎺ㄨ繘褰撳墠閫昏緫銆?*/
} else {
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
child->children[child->key_count + 1] = sibling->children[0];
/* 绗?{number}琛岋細鎵ц杩欎竴琛屼唬鐮侊紝缁х画鎺ㄨ繘褰撳墠閫昏緫銆?*/
child->key_count++;
/* 绗?{number}琛岋細寮€濮嬩竴娆?for 寰幆锛屾寜鍥哄畾娆℃暟鎴栧尯闂撮噸澶嶆墽琛屽悗缁鍙ャ€?*/
for (i = 1; i <= sibling->key_count; i++) {
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
sibling->children[i - 1] = sibling->children[i];
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
sibling->children[sibling->key_count] = NULL;
/* 绗?{number}琛岋細鎵ц杩欎竴琛屼唬鐮侊紝缁х画鎺ㄨ繘褰撳墠閫昏緫銆?*/
sibling->key_count--;
/* 绗?{number}琛岋細璋冪敤涓€涓嚱鏁帮紝璁╁畠甯垜浠畬鎴愬綋鍓嶈繖涓€姝ユ搷浣溿€?*/
BPlusRefreshKeys(child);
/* 绗?{number}琛岋細璋冪敤涓€涓嚱鏁帮紝璁╁畠甯垜浠畬鎴愬綋鍓嶈繖涓€姝ユ搷浣溿€?*/
BPlusRefreshKeys(sibling);
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細璋冪敤涓€涓嚱鏁帮紝璁╁畠甯垜浠畬鎴愬綋鍓嶈繖涓€姝ユ搷浣溿€?*/
BPlusRefreshKeys(parent);
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細瀹氫箟鍑芥暟 ㈠紑濮嬪啓杩欎釜鍑芥暟鐨勫叿浣撳疄鐜般€?*/
void BPlusMergeChildren(BPlusNode *parent, int index) {
/* 绗?{number}琛岋細鎵ц杩欎竴琛屼唬鐮侊紝缁х画鎺ㄨ繘褰撳墠閫昏緫銆?*/
BPlusNode *left_child;
/* 绗?{number}琛岋細鎵ц杩欎竴琛屼唬鐮侊紝缁х画鎺ㄨ繘褰撳墠閫昏緫銆?*/
BPlusNode *right_child;
/* 绗?{number}琛岋細澹版槑褰撳墠璇彞鍚庨潰瑕佷娇鐢ㄧ殑鍙橀噺銆佹寚閽堟垨灞€閮ㄦ暟鎹€?*/
int left_child_count;
/* 绗?{number}琛岋細澹版槑褰撳墠璇彞鍚庨潰瑕佷娇鐢ㄧ殑鍙橀噺銆佹寚閽堟垨灞€閮ㄦ暟鎹€?*/
int right_child_count;
/* 绗?{number}琛岋細澹版槑褰撳墠璇彞鍚庨潰瑕佷娇鐢ㄧ殑鍙橀噺銆佹寚閽堟垨灞€閮ㄦ暟鎹€?*/
int i;
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
left_child = parent->children[index];
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
right_child = parent->children[index + 1];
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭璧板摢涓垎鏀€?*/
if (left_child == NULL || right_child == NULL) {
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
return;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭璧板摢涓垎鏀€?*/
if (left_child->leaf) {
/* 绗?{number}琛岋細寮€濮嬩竴娆?for 寰幆锛屾寜鍥哄畾娆℃暟鎴栧尯闂撮噸澶嶆墽琛屽悗缁鍙ャ€?*/
for (i = 0; i < right_child->key_count; i++) {
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
left_child->keys[left_child->key_count + i] = right_child->keys[i];
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
left_child->key_count += right_child->key_count;
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
left_child->next = right_child->next;
/* 绗?{number}琛岋細鎵ц杩欎竴琛屼唬鐮侊紝缁х画鎺ㄨ繘褰撳墠閫昏緫銆?*/
} else {
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
left_child_count = left_child->key_count + 1;
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
right_child_count = right_child->key_count + 1;
/* 绗?{number}琛岋細寮€濮嬩竴娆?for 寰幆锛屾寜鍥哄畾娆℃暟鎴栧尯闂撮噸澶嶆墽琛屽悗缁鍙ャ€?*/
for (i = 0; i < right_child_count; i++) {
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
left_child->children[left_child_count + i] = right_child->children[i];
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
left_child->key_count = left_child_count + right_child_count - 1;
/* 绗?{number}琛岋細璋冪敤涓€涓嚱鏁帮紝璁╁畠甯垜浠畬鎴愬綋鍓嶈繖涓€姝ユ搷浣溿€?*/
BPlusRefreshKeys(left_child);
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細寮€濮嬩竴娆?for 寰幆锛屾寜鍥哄畾娆℃暟鎴栧尯闂撮噸澶嶆墽琛屽悗缁鍙ャ€?*/
for (i = index + 1; i < parent->key_count; i++) {
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
parent->children[i] = parent->children[i + 1];
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
parent->children[parent->key_count] = NULL;
/* 绗?{number}琛岋細鎵ц杩欎竴琛屼唬鐮侊紝缁х画鎺ㄨ繘褰撳墠閫昏緫銆?*/
parent->key_count--;
/* 绗?{number}琛岋細璋冪敤涓€涓嚱鏁帮紝璁╁畠甯垜浠畬鎴愬綋鍓嶈繖涓€姝ユ搷浣溿€?*/
BPlusRefreshKeys(parent);
/* 绗?{number}琛岋細璋冪敤涓€涓嚱鏁帮紝璁╁畠甯垜浠畬鎴愬綋鍓嶈繖涓€姝ユ搷浣溿€?*/
free(right_child);
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細瀹氫箟鍑芥暟 ㈠紑濮嬪啓杩欎釜鍑芥暟鐨勫叿浣撳疄鐜般€?*/
bool BPlusDeleteRecursive(BPlusNode *node, int key) {
/* 绗?{number}琛岋細澹版槑褰撳墠璇彞鍚庨潰瑕佷娇鐢ㄧ殑鍙橀噺銆佹寚閽堟垨灞€閮ㄦ暟鎹€?*/
int index;
/* 绗?{number}琛岋細澹版槑褰撳墠璇彞鍚庨潰瑕佷娇鐢ㄧ殑鍙橀噺銆佹寚閽堟垨灞€閮ㄦ暟鎹€?*/
int i;
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭璧板摢涓垎鏀€?*/
if (node == NULL) {
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
return false;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭璧板摢涓垎鏀€?*/
if (node->leaf) {
/* 绗?{number}琛岋細寮€濮嬩竴娆?for 寰幆锛屾寜鍥哄畾娆℃暟鎴栧尯闂撮噸澶嶆墽琛屽悗缁鍙ャ€?*/
for (index = 0; index < node->key_count; index++) {
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭璧板摢涓垎鏀€?*/
if (node->keys[index] == key) {
/* 绗?{number}琛岋細寮€濮嬩竴娆?for 寰幆锛屾寜鍥哄畾娆℃暟鎴栧尯闂撮噸澶嶆墽琛屽悗缁鍙ャ€?*/
for (i = index + 1; i < node->key_count; i++) {
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
node->keys[i - 1] = node->keys[i];
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細鎵ц杩欎竴琛屼唬鐮侊紝缁х画鎺ㄨ繘褰撳墠閫昏緫銆?*/
node->key_count--;
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
return true;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
return false;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
index = 0;
/* 绗?{number}琛岋細寮€濮嬩竴娆?while 寰幆锛屽彧瑕佹潯浠舵垚绔嬪氨缁х画鎵ц銆?*/
while (index < node->key_count && key >= node->keys[index]) {
/* 绗?{number}琛岋細鎵ц杩欎竴琛屼唬鐮侊紝缁х画鎺ㄨ繘褰撳墠閫昏緫銆?*/
index++;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭璧板摢涓垎鏀€?*/
if (!BPlusDeleteRecursive(node->children[index], key)) {
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
return false;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭璧板摢涓垎鏀€?*/
if (node->children[index] != NULL && node->children[index]->key_count == 0) {
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭璧板摢涓垎鏀€?*/
if (index > 0 && node->children[index - 1] != NULL &&
/* 绗?{number}琛岋細鎵ц杩欎竴琛屼唬鐮侊紝缁х画鎺ㄨ繘褰撳墠閫昏緫銆?*/
node->children[index - 1]->key_count > 1) {
/* 绗?{number}琛岋細璋冪敤涓€涓嚱鏁帮紝璁╁畠甯垜浠畬鎴愬綋鍓嶈繖涓€姝ユ搷浣溿€?*/
BPlusBorrowFromPrev(node, index);
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
} else if (index < node->key_count && node->children[index + 1] != NULL &&
/* 绗?{number}琛岋細鎵ц杩欎竴琛屼唬鐮侊紝缁х画鎺ㄨ繘褰撳墠閫昏緫銆?*/
node->children[index + 1]->key_count > 1) {
/* 绗?{number}琛岋細璋冪敤涓€涓嚱鏁帮紝璁╁畠甯垜浠畬鎴愬綋鍓嶈繖涓€姝ユ搷浣溿€?*/
BPlusBorrowFromNext(node, index);
/* 绗?{number}琛岋細鎵ц杩欎竴琛屼唬鐮侊紝缁х画鎺ㄨ繘褰撳墠閫昏緫銆?*/
} else if (index > 0) {
/* 绗?{number}琛岋細璋冪敤涓€涓嚱鏁帮紝璁╁畠甯垜浠畬鎴愬綋鍓嶈繖涓€姝ユ搷浣溿€?*/
BPlusMergeChildren(node, index - 1);
/* 绗?{number}琛岋細鎵ц杩欎竴琛屼唬鐮侊紝缁х画鎺ㄨ繘褰撳墠閫昏緫銆?*/
} else {
/* 绗?{number}琛岋細璋冪敤涓€涓嚱鏁帮紝璁╁畠甯垜浠畬鎴愬綋鍓嶈繖涓€姝ユ搷浣溿€?*/
BPlusMergeChildren(node, index);
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細鎵ц杩欎竴琛屼唬鐮侊紝缁х画鎺ㄨ繘褰撳墠閫昏緫銆?*/
} else {
/* 绗?{number}琛岋細璋冪敤涓€涓嚱鏁帮紝璁╁畠甯垜浠畬鎴愬綋鍓嶈繖涓€姝ユ搷浣溿€?*/
BPlusRefreshKeys(node);
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
return true;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細鎵ц杩欎竴琛屼唬鐮侊紝缁х画鎺ㄨ繘褰撳墠閫昏緫銆?*/
BPlusNode *BPlusDelete(BPlusNode *root, int key) {
/* 绗?{number}琛岋細鎵ц杩欎竴琛屼唬鐮侊紝缁х画鎺ㄨ繘褰撳墠閫昏緫銆?*/
BPlusNode *new_root;
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭璧板摢涓垎鏀€?*/
if (root == NULL) {
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
return NULL;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭璧板摢涓垎鏀€?*/
if (!BPlusDeleteRecursive(root, key)) {
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
return root;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭璧板摢涓垎鏀€?*/
if (root->leaf) {
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭璧板摢涓垎鏀€?*/
if (root->key_count == 0) {
/* 绗?{number}琛岋細璋冪敤涓€涓嚱鏁帮紝璁╁畠甯垜浠畬鎴愬綋鍓嶈繖涓€姝ユ搷浣溿€?*/
free(root);
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
return NULL;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
return root;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭璧板摢涓垎鏀€?*/
if (root->key_count > 0) {
/* 绗?{number}琛岋細璋冪敤涓€涓嚱鏁帮紝璁╁畠甯垜浠畬鎴愬綋鍓嶈繖涓€姝ユ搷浣溿€?*/
BPlusRefreshKeys(root);
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
return root;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
new_root = root->children[0];
/* 绗?{number}琛岋細璋冪敤涓€涓嚱鏁帮紝璁╁畠甯垜浠畬鎴愬綋鍓嶈繖涓€姝ユ搷浣溿€?*/
free(root);
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
return new_root;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細鎵ц杩欎竴琛屼唬鐮侊紝缁х画鎺ㄨ繘褰撳墠閫昏緫銆?*/
BPlusNode *BuildSampleBPlusTree(void) {
/* 绗?{number}琛岋細澹版槑褰撳墠璇彞鍚庨潰瑕佷娇鐢ㄧ殑鍙橀噺銆佹寚閽堟垨灞€閮ㄦ暟鎹€?*/
int keys[] = {5, 12, 18, 24, 30, 37, 42, 50};
/* 绗?{number}琛岋細澹版槑褰撳墠璇彞鍚庨潰瑕佷娇鐢ㄧ殑鍙橀噺銆佹寚閽堟垨灞€閮ㄦ暟鎹€?*/
int i;
/* 绗?{number}琛岋細鎵ц杩欎竴琛屼唬鐮侊紝缁х画鎺ㄨ繘褰撳墠閫昏緫銆?*/
BPlusNode *root;
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
root = NULL;
/* 绗?{number}琛岋細寮€濮嬩竴娆?for 寰幆锛屾寜鍥哄畾娆℃暟鎴栧尯闂撮噸澶嶆墽琛屽悗缁鍙ャ€?*/
for (i = 0; i < (int)(sizeof(keys) / sizeof(keys[0])); i++) {
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
root = BPlusInsert(root, keys[i]);
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
return root;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細鎵ц杩欎竴琛屼唬鐮侊紝缁х画鎺ㄨ繘褰撳墠閫昏緫銆?*/
BPlusNode *BPlusFindLeaf(BPlusNode *root, int key) {
/* 绗?{number}琛岋細澹版槑褰撳墠璇彞鍚庨潰瑕佷娇鐢ㄧ殑鍙橀噺銆佹寚閽堟垨灞€閮ㄦ暟鎹€?*/
int i;
/* 绗?{number}琛岋細鎵ц杩欎竴琛屼唬鐮侊紝缁х画鎺ㄨ繘褰撳墠閫昏緫銆?*/
BPlusNode *current;
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
current = root;
/* 绗?{number}琛岋細寮€濮嬩竴娆?while 寰幆锛屽彧瑕佹潯浠舵垚绔嬪氨缁х画鎵ц銆?*/
while (current != NULL && !current->leaf) {
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
i = 0;
/* 绗?{number}琛岋細寮€濮嬩竴娆?while 寰幆锛屽彧瑕佹潯浠舵垚绔嬪氨缁х画鎵ц銆?*/
while (i < current->key_count && key >= current->keys[i]) {
/* 绗?{number}琛岋細鎵ц杩欎竴琛屼唬鐮侊紝缁х画鎺ㄨ繘褰撳墠閫昏緫銆?*/
i++;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
current = current->children[i];
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
return current;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細瀹氫箟鍑芥暟 ㈠紑濮嬪啓杩欎釜鍑芥暟鐨勫叿浣撳疄鐜般€?*/
bool BPlusSearch(BPlusNode *root, int key) {
/* 绗?{number}琛岋細鎵ц杩欎竴琛屼唬鐮侊紝缁х画鎺ㄨ繘褰撳墠閫昏緫銆?*/
BPlusNode *leaf;
/* 绗?{number}琛岋細澹版槑褰撳墠璇彞鍚庨潰瑕佷娇鐢ㄧ殑鍙橀噺銆佹寚閽堟垨灞€閮ㄦ暟鎹€?*/
int i;
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
leaf = BPlusFindLeaf(root, key);
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭璧板摢涓垎鏀€?*/
if (leaf == NULL) {
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
return false;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細寮€濮嬩竴娆?for 寰幆锛屾寜鍥哄畾娆℃暟鎴栧尯闂撮噸澶嶆墽琛屽悗缁鍙ャ€?*/
for (i = 0; i < leaf->key_count; i++) {
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭璧板摢涓垎鏀€?*/
if (leaf->keys[i] == key) {
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
return true;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
return false;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細瀹氫箟鍑芥暟 ㈠紑濮嬪啓杩欎釜鍑芥暟鐨勫叿浣撳疄鐜般€?*/
void BPlusPrintRange(BPlusNode *root, int low, int high) {
/* 绗?{number}琛岋細鎵ц杩欎竴琛屼唬鐮侊紝缁х画鎺ㄨ繘褰撳墠閫昏緫銆?*/
BPlusNode *leaf;
/* 绗?{number}琛岋細澹版槑褰撳墠璇彞鍚庨潰瑕佷娇鐢ㄧ殑鍙橀噺銆佹寚閽堟垨灞€閮ㄦ暟鎹€?*/
int i;
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
leaf = BPlusFindLeaf(root, low);
/* 绗?{number}琛岋細鎶婂綋鍓嶇粨鏋滄墦鍗板嚭鏉ワ紝鏂逛究瑙傚療绋嬪簭杩愯鎯呭喌銆?*/
printf("B+ range [%d, %d]: ", low, high);
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細寮€濮嬩竴娆?while 寰幆锛屽彧瑕佹潯浠舵垚绔嬪氨缁х画鎵ц銆?*/
while (leaf != NULL) {
/* 绗?{number}琛岋細寮€濮嬩竴娆?for 寰幆锛屾寜鍥哄畾娆℃暟鎴栧尯闂撮噸澶嶆墽琛屽悗缁鍙ャ€?*/
for (i = 0; i < leaf->key_count; i++) {
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭璧板摢涓垎鏀€?*/
if (leaf->keys[i] >= low && leaf->keys[i] <= high) {
/* 绗?{number}琛岋細鎶婂綋鍓嶇粨鏋滄墦鍗板嚭鏉ワ紝鏂逛究瑙傚療绋嬪簭杩愯鎯呭喌銆?*/
printf("%d ", leaf->keys[i]);
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭璧板摢涓垎鏀€?*/
if (leaf->keys[i] > high) {
/* 绗?{number}琛岋細鎶婂綋鍓嶇粨鏋滄墦鍗板嚭鏉ワ紝鏂逛究瑙傚療绋嬪簭杩愯鎯呭喌銆?*/
printf("\n");
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
return;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
leaf = leaf->next;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細鎶婂綋鍓嶇粨鏋滄墦鍗板嚭鏉ワ紝鏂逛究瑙傚療绋嬪簭杩愯鎯呭喌銆?*/
printf("\n");
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細瀹氫箟鍑芥暟 ㈠紑濮嬪啓杩欎釜鍑芥暟鐨勫叿浣撳疄鐜般€?*/
void BPlusPrintLeaves(BPlusNode *root) {
/* 绗?{number}琛岋細鎵ц杩欎竴琛屼唬鐮侊紝缁х画鎺ㄨ繘褰撳墠閫昏緫銆?*/
BPlusNode *current;
/* 绗?{number}琛岋細澹版槑褰撳墠璇彞鍚庨潰瑕佷娇鐢ㄧ殑鍙橀噺銆佹寚閽堟垨灞€閮ㄦ暟鎹€?*/
int i;
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
current = root;
/* 绗?{number}琛岋細寮€濮嬩竴娆?while 寰幆锛屽彧瑕佹潯浠舵垚绔嬪氨缁х画鎵ц銆?*/
while (current != NULL && !current->leaf) {
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
current = current->children[0];
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細鎶婂綋鍓嶇粨鏋滄墦鍗板嚭鏉ワ紝鏂逛究瑙傚療绋嬪簭杩愯鎯呭喌銆?*/
printf("B+ leaves: ");
/* 绗?{number}琛岋細寮€濮嬩竴娆?while 寰幆锛屽彧瑕佹潯浠舵垚绔嬪氨缁х画鎵ц銆?*/
while (current != NULL) {
/* 绗?{number}琛岋細鎶婂綋鍓嶇粨鏋滄墦鍗板嚭鏉ワ紝鏂逛究瑙傚療绋嬪簭杩愯鎯呭喌銆?*/
printf("[");
/* 绗?{number}琛岋細寮€濮嬩竴娆?for 寰幆锛屾寜鍥哄畾娆℃暟鎴栧尯闂撮噸澶嶆墽琛屽悗缁鍙ャ€?*/
for (i = 0; i < current->key_count; i++) {
/* 绗?{number}琛岋細鎶婂綋鍓嶇粨鏋滄墦鍗板嚭鏉ワ紝鏂逛究瑙傚療绋嬪簭杩愯鎯呭喌銆?*/
printf("%d", current->keys[i]);
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭璧板摢涓垎鏀€?*/
if (i + 1 < current->key_count) {
/* 绗?{number}琛岋細鎶婂綋鍓嶇粨鏋滄墦鍗板嚭鏉ワ紝鏂逛究瑙傚療绋嬪簭杩愯鎯呭喌銆?*/
printf(" ");
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細鎶婂綋鍓嶇粨鏋滄墦鍗板嚭鏉ワ紝鏂逛究瑙傚療绋嬪簭杩愯鎯呭喌銆?*/
printf("] ");
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
current = current->next;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細鎶婂綋鍓嶇粨鏋滄墦鍗板嚭鏉ワ紝鏂逛究瑙傚療绋嬪簭杩愯鎯呭喌銆?*/
printf("\n");
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細瀹氫箟鍑芥暟 ㈠紑濮嬪啓杩欎釜鍑芥暟鐨勫叿浣撳疄鐜般€?*/
void DestroyBPlusTree(BPlusNode *root) {
/* 绗?{number}琛岋細澹版槑褰撳墠璇彞鍚庨潰瑕佷娇鐢ㄧ殑鍙橀噺銆佹寚閽堟垨灞€閮ㄦ暟鎹€?*/
int i;
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭璧板摢涓垎鏀€?*/
if (root == NULL) {
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
return;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭璧板摢涓垎鏀€?*/
if (!root->leaf) {
/* 绗?{number}琛岋細寮€濮嬩竴娆?for 寰幆锛屾寜鍥哄畾娆℃暟鎴栧尯闂撮噸澶嶆墽琛屽悗缁鍙ャ€?*/
for (i = 0; i <= root->key_count; i++) {
/* 绗?{number}琛岋細璋冪敤涓€涓嚱鏁帮紝璁╁畠甯垜浠畬鎴愬綋鍓嶈繖涓€姝ユ搷浣溿€?*/
DestroyBPlusTree(root->children[i]);
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細璋冪敤涓€涓嚱鏁帮紝璁╁畠甯垜浠畬鎴愬綋鍓嶈繖涓€姝ユ搷浣溿€?*/
free(root);
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細杩欐槸鍘熶唬鐮佷腑鑷甫鐨勮鏄庢€ф敞閲娿€?*/
/* 散列函数:这里用简单取模,便于演示冲突与探测。 */
/* 绗?{number}琛岋細瀹氫箟鍑芥暟 ㈠紑濮嬪啓杩欎釜鍑芥暟鐨勫叿浣撳疄鐜般€?*/
int HashFunc(int key) {
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭璧板摢涓垎鏀€?*/
if (key < 0) {
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
key = -key;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
return key % MAX_HASH_SIZE;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細杩欐槸鍘熶唬鐮佷腑鑷甫鐨勮鏄庢€ф敞閲娿€?*/
/* 初始化开放定址表:所有位置先视为空槽。 */
/* 绗?{number}琛岋細瀹氫箟鍑芥暟 ㈠紑濮嬪啓杩欎釜鍑芥暟鐨勫叿浣撳疄鐜般€?*/
void InitHashOpenTable(HashOpenTable *table) {
/* 绗?{number}琛岋細澹版槑褰撳墠璇彞鍚庨潰瑕佷娇鐢ㄧ殑鍙橀噺銆佹寚閽堟垨灞€閮ㄦ暟鎹€?*/
int i;
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭璧板摢涓垎鏀€?*/
if (table == NULL) {
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
return;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細寮€濮嬩竴娆?for 寰幆锛屾寜鍥哄畾娆℃暟鎴栧尯闂撮噸澶嶆墽琛屽悗缁鍙ャ€?*/
for (i = 0; i < MAX_HASH_SIZE; i++) {
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
table->data[i] = EMPTY_SLOT;
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
table->occupied[i] = false;
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
table->deleted[i] = false;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細杩欐槸鍘熶唬鐮佷腑鑷甫鐨勮鏄庢€ф敞閲娿€?*/
/* 线性探测插入:发生冲突时顺着往后找空位。 */
/* 绗?{number}琛岋細瀹氫箟鍑芥暟 ㈠紑濮嬪啓杩欎釜鍑芥暟鐨勫叿浣撳疄鐜般€?*/
bool HashOpenInsert(HashOpenTable *table, int key) {
/* 绗?{number}琛岋細澹版槑褰撳墠璇彞鍚庨潰瑕佷娇鐢ㄧ殑鍙橀噺銆佹寚閽堟垨灞€閮ㄦ暟鎹€?*/
int start;
/* 绗?{number}琛岋細澹版槑褰撳墠璇彞鍚庨潰瑕佷娇鐢ㄧ殑鍙橀噺銆佹寚閽堟垨灞€閮ㄦ暟鎹€?*/
int step;
/* 绗?{number}琛岋細澹版槑褰撳墠璇彞鍚庨潰瑕佷娇鐢ㄧ殑鍙橀噺銆佹寚閽堟垨灞€閮ㄦ暟鎹€?*/
int pos;
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭璧板摢涓垎鏀€?*/
if (table == NULL) {
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
return false;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
start = HashFunc(key);
/* 绗?{number}琛岋細寮€濮嬩竴娆?for 寰幆锛屾寜鍥哄畾娆℃暟鎴栧尯闂撮噸澶嶆墽琛屽悗缁鍙ャ€?*/
for (step = 0; step < MAX_HASH_SIZE; step++) {
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
pos = (start + step) % MAX_HASH_SIZE;
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭璧板摢涓垎鏀€?*/
if (!table->occupied[pos] || table->deleted[pos]) {
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
table->data[pos] = key;
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
table->occupied[pos] = true;
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
table->deleted[pos] = false;
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
return true;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭璧板摢涓垎鏀€?*/
if (table->data[pos] == key) {
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
return true;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
return false;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細杩欐槸鍘熶唬鐮佷腑鑷甫鐨勮鏄庢€ф敞閲娿€?*/
/* 线性探测查找:遇到真正的空槽就可断定查找失败。 */
/* 绗?{number}琛岋細瀹氫箟鍑芥暟 ㈠紑濮嬪啓杩欎釜鍑芥暟鐨勫叿浣撳疄鐜般€?*/
int HashOpenSearch(const HashOpenTable *table, int key) {
/* 绗?{number}琛岋細澹版槑褰撳墠璇彞鍚庨潰瑕佷娇鐢ㄧ殑鍙橀噺銆佹寚閽堟垨灞€閮ㄦ暟鎹€?*/
int start;
/* 绗?{number}琛岋細澹版槑褰撳墠璇彞鍚庨潰瑕佷娇鐢ㄧ殑鍙橀噺銆佹寚閽堟垨灞€閮ㄦ暟鎹€?*/
int step;
/* 绗?{number}琛岋細澹版槑褰撳墠璇彞鍚庨潰瑕佷娇鐢ㄧ殑鍙橀噺銆佹寚閽堟垨灞€閮ㄦ暟鎹€?*/
int pos;
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭璧板摢涓垎鏀€?*/
if (table == NULL) {
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
return -1;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
start = HashFunc(key);
/* 绗?{number}琛岋細寮€濮嬩竴娆?for 寰幆锛屾寜鍥哄畾娆℃暟鎴栧尯闂撮噸澶嶆墽琛屽悗缁鍙ャ€?*/
for (step = 0; step < MAX_HASH_SIZE; step++) {
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
pos = (start + step) % MAX_HASH_SIZE;
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭璧板摢涓垎鏀€?*/
if (!table->occupied[pos] && !table->deleted[pos]) {
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
return -1;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭璧板摢涓垎鏀€?*/
if (table->occupied[pos] && !table->deleted[pos] && table->data[pos] == key) {
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
return pos;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
return -1;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細杩欐槸鍘熶唬鐮佷腑鑷甫鐨勮鏄庢€ф敞閲娿€?*/
/* 打印开放定址表:便于观察哪些关键字因为冲突被探测到后面。 */
/* 绗?{number}琛岋細瀹氫箟鍑芥暟 ㈠紑濮嬪啓杩欎釜鍑芥暟鐨勫叿浣撳疄鐜般€?*/
void PrintHashOpenTable(const HashOpenTable *table) {
/* 绗?{number}琛岋細澹版槑褰撳墠璇彞鍚庨潰瑕佷娇鐢ㄧ殑鍙橀噺銆佹寚閽堟垨灞€閮ㄦ暟鎹€?*/
int i;
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭璧板摢涓垎鏀€?*/
if (table == NULL) {
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
return;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細鎶婂綋鍓嶇粨鏋滄墦鍗板嚭鏉ワ紝鏂逛究瑙傚療绋嬪簭杩愯鎯呭喌銆?*/
printf("Open addressing hash table:\n");
/* 绗?{number}琛岋細寮€濮嬩竴娆?for 寰幆锛屾寜鍥哄畾娆℃暟鎴栧尯闂撮噸澶嶆墽琛屽悗缁鍙ャ€?*/
for (i = 0; i < MAX_HASH_SIZE; i++) {
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭璧板摢涓垎鏀€?*/
if (table->occupied[i] && !table->deleted[i]) {
/* 绗?{number}琛岋細鎶婂綋鍓嶇粨鏋滄墦鍗板嚭鏉ワ紝鏂逛究瑙傚療绋嬪簭杩愯鎯呭喌銆?*/
printf("[%d]=%d ", i, table->data[i]);
/* 绗?{number}琛岋細鎵ц杩欎竴琛屼唬鐮侊紝缁х画鎺ㄨ繘褰撳墠閫昏緫銆?*/
} else {
/* 绗?{number}琛岋細鎶婂綋鍓嶇粨鏋滄墦鍗板嚭鏉ワ紝鏂逛究瑙傚療绋嬪簭杩愯鎯呭喌銆?*/
printf("[%d]=- ", i);
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細鎶婂綋鍓嶇粨鏋滄墦鍗板嚭鏉ワ紝鏂逛究瑙傚療绋嬪簭杩愯鎯呭喌銆?*/
printf("\n");
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細杩欐槸鍘熶唬鐮佷腑鑷甫鐨勮鏄庢€ф敞閲娿€?*/
/* 创建拉链法结点:把新关键字挂到同义词链中。 */
/* 绗?{number}琛岋細澹版槑褰撳墠璇彞鍚庨潰瑕佷娇鐢ㄧ殑鍙橀噺銆佹寚閽堟垨灞€閮ㄦ暟鎹€?*/
ChainNode *CreateChainNode(int key) {
/* 绗?{number}琛岋細澹版槑褰撳墠璇彞鍚庨潰瑕佷娇鐢ㄧ殑鍙橀噺銆佹寚閽堟垨灞€閮ㄦ暟鎹€?*/
ChainNode *node;
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
node = (ChainNode *)malloc(sizeof(ChainNode));
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭璧板摢涓垎鏀€?*/
if (node == NULL) {
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
return NULL;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
node->key = key;
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
node->next = NULL;
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
return node;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細杩欐槸鍘熶唬鐮佷腑鑷甫鐨勮鏄庢€ф敞閲娿€?*/
/* 初始化拉链法散列表:所有桶头指针先置空。 */
/* 绗?{number}琛岋細瀹氫箟鍑芥暟 ㈠紑濮嬪啓杩欎釜鍑芥暟鐨勫叿浣撳疄鐜般€?*/
void InitChainHashTable(ChainHashTable *table) {
/* 绗?{number}琛岋細澹版槑褰撳墠璇彞鍚庨潰瑕佷娇鐢ㄧ殑鍙橀噺銆佹寚閽堟垨灞€閮ㄦ暟鎹€?*/
int i;
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭璧板摢涓垎鏀€?*/
if (table == NULL) {
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
return;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細寮€濮嬩竴娆?for 寰幆锛屾寜鍥哄畾娆℃暟鎴栧尯闂撮噸澶嶆墽琛屽悗缁鍙ャ€?*/
for (i = 0; i < MAX_HASH_SIZE; i++) {
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
table->buckets[i] = NULL;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細杩欐槸鍘熶唬鐮佷腑鑷甫鐨勮鏄庢€ф敞閲娿€?*/
/* 拉链法插入:直接头插到对应桶的链表里。 */
/* 绗?{number}琛岋細瀹氫箟鍑芥暟 ㈠紑濮嬪啓杩欎釜鍑芥暟鐨勫叿浣撳疄鐜般€?*/
bool ChainHashInsert(ChainHashTable *table, int key) {
/* 绗?{number}琛岋細澹版槑褰撳墠璇彞鍚庨潰瑕佷娇鐢ㄧ殑鍙橀噺銆佹寚閽堟垨灞€閮ㄦ暟鎹€?*/
int index;
/* 绗?{number}琛岋細澹版槑褰撳墠璇彞鍚庨潰瑕佷娇鐢ㄧ殑鍙橀噺銆佹寚閽堟垨灞€閮ㄦ暟鎹€?*/
ChainNode *node;
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭璧板摢涓垎鏀€?*/
if (table == NULL) {
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
return false;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
index = HashFunc(key);
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
node = CreateChainNode(key);
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭璧板摢涓垎鏀€?*/
if (node == NULL) {
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
return false;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
node->next = table->buckets[index];
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
table->buckets[index] = node;
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
return true;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細杩欐槸鍘熶唬鐮佷腑鑷甫鐨勮鏄庢€ф敞閲娿€?*/
/* 拉链法查找:只在对应桶的链表中顺着找。 */
/* 绗?{number}琛岋細澹版槑褰撳墠璇彞鍚庨潰瑕佷娇鐢ㄧ殑鍙橀噺銆佹寚閽堟垨灞€閮ㄦ暟鎹€?*/
ChainNode *ChainHashSearch(const ChainHashTable *table, int key) {
/* 绗?{number}琛岋細澹版槑褰撳墠璇彞鍚庨潰瑕佷娇鐢ㄧ殑鍙橀噺銆佹寚閽堟垨灞€閮ㄦ暟鎹€?*/
int index;
/* 绗?{number}琛岋細澹版槑褰撳墠璇彞鍚庨潰瑕佷娇鐢ㄧ殑鍙橀噺銆佹寚閽堟垨灞€閮ㄦ暟鎹€?*/
ChainNode *current;
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭璧板摢涓垎鏀€?*/
if (table == NULL) {
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
return NULL;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
index = HashFunc(key);
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
current = table->buckets[index];
/* 绗?{number}琛岋細寮€濮嬩竴娆?while 寰幆锛屽彧瑕佹潯浠舵垚绔嬪氨缁х画鎵ц銆?*/
while (current != NULL) {
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭璧板摢涓垎鏀€?*/
if (current->key == key) {
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
return current;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
current = current->next;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
return NULL;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細杩欐槸鍘熶唬鐮佷腑鑷甫鐨勮鏄庢€ф敞閲娿€?*/
/* 打印拉链法散列表:直观看每个桶上的同义词链。 */
/* 绗?{number}琛岋細瀹氫箟鍑芥暟 ㈠紑濮嬪啓杩欎釜鍑芥暟鐨勫叿浣撳疄鐜般€?*/
void PrintChainHashTable(const ChainHashTable *table) {
/* 绗?{number}琛岋細澹版槑褰撳墠璇彞鍚庨潰瑕佷娇鐢ㄧ殑鍙橀噺銆佹寚閽堟垨灞€閮ㄦ暟鎹€?*/
int i;
/* 绗?{number}琛岋細澹版槑褰撳墠璇彞鍚庨潰瑕佷娇鐢ㄧ殑鍙橀噺銆佹寚閽堟垨灞€閮ㄦ暟鎹€?*/
ChainNode *current;
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭璧板摢涓垎鏀€?*/
if (table == NULL) {
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
return;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細鎶婂綋鍓嶇粨鏋滄墦鍗板嚭鏉ワ紝鏂逛究瑙傚療绋嬪簭杩愯鎯呭喌銆?*/
printf("Chaining hash table:\n");
/* 绗?{number}琛岋細寮€濮嬩竴娆?for 寰幆锛屾寜鍥哄畾娆℃暟鎴栧尯闂撮噸澶嶆墽琛屽悗缁鍙ャ€?*/
for (i = 0; i < MAX_HASH_SIZE; i++) {
/* 绗?{number}琛岋細鎶婂綋鍓嶇粨鏋滄墦鍗板嚭鏉ワ紝鏂逛究瑙傚療绋嬪簭杩愯鎯呭喌銆?*/
printf("[%d] -> ", i);
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
current = table->buckets[i];
/* 绗?{number}琛岋細寮€濮嬩竴娆?while 寰幆锛屽彧瑕佹潯浠舵垚绔嬪氨缁х画鎵ц銆?*/
while (current != NULL) {
/* 绗?{number}琛岋細鎶婂綋鍓嶇粨鏋滄墦鍗板嚭鏉ワ紝鏂逛究瑙傚療绋嬪簭杩愯鎯呭喌銆?*/
printf("%d ", current->key);
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
current = current->next;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細鎶婂綋鍓嶇粨鏋滄墦鍗板嚭鏉ワ紝鏂逛究瑙傚療绋嬪簭杩愯鎯呭喌銆?*/
printf("^\n");
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細杩欐槸鍘熶唬鐮佷腑鑷甫鐨勮鏄庢€ф敞閲娿€?*/
/* 释放拉链法散列表:逐桶逐链释放动态结点。 */
/* 绗?{number}琛岋細瀹氫箟鍑芥暟 ㈠紑濮嬪啓杩欎釜鍑芥暟鐨勫叿浣撳疄鐜般€?*/
void DestroyChainHashTable(ChainHashTable *table) {
/* 绗?{number}琛岋細澹版槑褰撳墠璇彞鍚庨潰瑕佷娇鐢ㄧ殑鍙橀噺銆佹寚閽堟垨灞€閮ㄦ暟鎹€?*/
int i;
/* 绗?{number}琛岋細澹版槑褰撳墠璇彞鍚庨潰瑕佷娇鐢ㄧ殑鍙橀噺銆佹寚閽堟垨灞€閮ㄦ暟鎹€?*/
ChainNode *current;
/* 绗?{number}琛岋細澹版槑褰撳墠璇彞鍚庨潰瑕佷娇鐢ㄧ殑鍙橀噺銆佹寚閽堟垨灞€閮ㄦ暟鎹€?*/
ChainNode *next;
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭璧板摢涓垎鏀€?*/
if (table == NULL) {
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
return;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細寮€濮嬩竴娆?for 寰幆锛屾寜鍥哄畾娆℃暟鎴栧尯闂撮噸澶嶆墽琛屽悗缁鍙ャ€?*/
for (i = 0; i < MAX_HASH_SIZE; i++) {
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
current = table->buckets[i];
/* 绗?{number}琛岋細寮€濮嬩竴娆?while 寰幆锛屽彧瑕佹潯浠舵垚绔嬪氨缁х画鎵ц銆?*/
while (current != NULL) {
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
next = current->next;
/* 绗?{number}琛岋細璋冪敤涓€涓嚱鏁帮紝璁╁畠甯垜浠畬鎴愬綋鍓嶈繖涓€姝ユ搷浣溿€?*/
free(current);
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
current = next;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
table->buckets[i] = NULL;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細杩欐槸鍘熶唬鐮佷腑鑷甫鐨勮鏄庢€ф敞閲娿€?*/
/* 主函数:集中演示第 7 章启动版已经落地的查找结构和算法。 */
/* 绗?{number}琛岋細瀹氫箟鍑芥暟 ㈠紑濮嬪啓杩欎釜鍑芥暟鐨勫叿浣撳疄鐜般€?*/
int main(void) {
/* 绗?{number}琛岋細澹版槑褰撳墠璇彞鍚庨潰瑕佷娇鐢ㄧ殑鍙橀噺銆佹寚閽堟垨灞€閮ㄦ暟鎹€?*/
int ordered_array[] = {5, 8, 12, 19, 23, 31, 45, 57, 68, 72};
/* 绗?{number}琛岋細澹版槑褰撳墠璇彞鍚庨潰瑕佷娇鐢ㄧ殑鍙橀噺銆佹寚閽堟垨灞€閮ㄦ暟鎹€?*/
int unordered_array[] = {19, 14, 23, 1, 68, 20, 84, 27, 55, 11, 10, 79};
/* 绗?{number}琛岋細澹版槑褰撳墠璇彞鍚庨潰瑕佷娇鐢ㄧ殑鍙橀噺銆佹寚閽堟垨灞€閮ㄦ暟鎹€?*/
BlockIndex blocks[MAX_BLOCKS] = {
/* 绗?{number}琛岋細鎵ц杩欎竴琛屼唬鐮侊紝缁х画鎺ㄨ繘褰撳墠閫昏緫銆?*/
{19, 0, 3},
/* 绗?{number}琛岋細鎵ц杩欎竴琛屼唬鐮侊紝缁х画鎺ㄨ繘褰撳墠閫昏緫銆?*/
{45, 4, 6},
/* 绗?{number}琛岋細鎵ц杩欎竴琛屼唬鐮侊紝缁х画鎺ㄨ繘褰撳墠閫昏緫銆?*/
{72, 7, 9}
/* 绗?{number}琛岋細鎵ц杩欎竴琛屼唬鐮侊紝缁х画鎺ㄨ繘褰撳墠閫昏緫銆?*/
};
/* 绗?{number}琛岋細澹版槑褰撳墠璇彞鍚庨潰瑕佷娇鐢ㄧ殑鍙橀噺銆佹寚閽堟垨灞€閮ㄦ暟鎹€?*/
int bst_keys[] = {45, 24, 53, 12, 37, 50, 61, 30, 40};
/* 绗?{number}琛岋細澹版槑褰撳墠璇彞鍚庨潰瑕佷娇鐢ㄧ殑鍙橀噺銆佹寚閽堟垨灞€閮ㄦ暟鎹€?*/
int avl_keys[] = {30, 20, 40, 10, 25, 35, 50, 5, 15, 27};
/* 绗?{number}琛岋細澹版槑褰撳墠璇彞鍚庨潰瑕佷娇鐢ㄧ殑鍙橀噺銆佹寚閽堟垨灞€閮ㄦ暟鎹€?*/
int rb_keys[] = {30, 20, 40, 10, 25, 35, 50, 5, 15, 27, 45};
/* 绗?{number}琛岋細澹版槑褰撳墠璇彞鍚庨潰瑕佷娇鐢ㄧ殑鍙橀噺銆佹寚閽堟垨灞€閮ㄦ暟鎹€?*/
int btree_keys[] = {20, 10, 30, 5, 15, 25, 35, 40, 50, 60, 70};
/* 绗?{number}琛岋細澹版槑褰撳墠璇彞鍚庨潰瑕佷娇鐢ㄧ殑鍙橀噺銆佹寚閽堟垨灞€閮ㄦ暟鎹€?*/
int bplus_extra_keys[] = {44, 46};
/* 绗?{number}琛岋細澹版槑褰撳墠璇彞鍚庨潰瑕佷娇鐢ㄧ殑鍙橀噺銆佹寚閽堟垨灞€閮ㄦ暟鎹€?*/
int hash_keys[] = {19, 14, 23, 1, 68, 20, 84, 27, 55, 11, 10, 79};
/* 绗?{number}琛岋細澹版槑褰撳墠璇彞鍚庨潰瑕佷娇鐢ㄧ殑鍙橀噺銆佹寚閽堟垨灞€閮ㄦ暟鎹€?*/
int i;
/* 绗?{number}琛岋細澹版槑褰撳墠璇彞鍚庨潰瑕佷娇鐢ㄧ殑鍙橀噺銆佹寚閽堟垨灞€閮ㄦ暟鎹€?*/
int seq_pos;
/* 绗?{number}琛岋細澹版槑褰撳墠璇彞鍚庨潰瑕佷娇鐢ㄧ殑鍙橀噺銆佹寚閽堟垨灞€閮ㄦ暟鎹€?*/
int binary_pos;
/* 绗?{number}琛岋細澹版槑褰撳墠璇彞鍚庨潰瑕佷娇鐢ㄧ殑鍙橀噺銆佹寚閽堟垨灞€閮ㄦ暟鎹€?*/
int binary_recursive_pos;
/* 绗?{number}琛岋細澹版槑褰撳墠璇彞鍚庨潰瑕佷娇鐢ㄧ殑鍙橀噺銆佹寚閽堟垨灞€閮ㄦ暟鎹€?*/
int block_pos;
/* 绗?{number}琛岋細澹版槑褰撳墠璇彞鍚庨潰瑕佷娇鐢ㄧ殑鍙橀噺銆佹寚閽堟垨灞€閮ㄦ暟鎹€?*/
int btree_index;
/* 绗?{number}琛岋細澹版槑褰撳墠璇彞鍚庨潰瑕佷娇鐢ㄧ殑鍙橀噺銆佹寚閽堟垨灞€閮ㄦ暟鎹€?*/
BSTNode *bst_root;
/* 绗?{number}琛岋細澹版槑褰撳墠璇彞鍚庨潰瑕佷娇鐢ㄧ殑鍙橀噺銆佹寚閽堟垨灞€閮ㄦ暟鎹€?*/
AVLNode *avl_root;
/* 绗?{number}琛岋細鎵ц杩欎竴琛屼唬鐮侊紝缁х画鎺ㄨ繘褰撳墠閫昏緫銆?*/
RBNode *rb_root;
/* 绗?{number}琛岋細鎵ц杩欎竴琛屼唬鐮侊紝缁х画鎺ㄨ繘褰撳墠閫昏緫銆?*/
BTreeNode *btree_root;
/* 绗?{number}琛岋細鎵ц杩欎竴琛屼唬鐮侊紝缁х画鎺ㄨ繘褰撳墠閫昏緫銆?*/
BTreeNode *btree_found;
/* 绗?{number}琛岋細鎵ц杩欎竴琛屼唬鐮侊紝缁х画鎺ㄨ繘褰撳墠閫昏緫銆?*/
BPlusNode *bplus_root;
/* 绗?{number}琛岋細澹版槑褰撳墠璇彞鍚庨潰瑕佷娇鐢ㄧ殑鍙橀噺銆佹寚閽堟垨灞€閮ㄦ暟鎹€?*/
HashOpenTable open_table;
/* 绗?{number}琛岋細澹版槑褰撳墠璇彞鍚庨潰瑕佷娇鐢ㄧ殑鍙橀噺銆佹寚閽堟垨灞€閮ㄦ暟鎹€?*/
ChainHashTable chain_table;
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
seq_pos = SeqSearch(unordered_array, (int)(sizeof(unordered_array) / sizeof(unordered_array[0])), 84);
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
binary_pos = BinarySearchIter(ordered_array, (int)(sizeof(ordered_array) / sizeof(ordered_array[0])), 31);
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
binary_recursive_pos = BinarySearchRecursive(
/* 绗?{number}琛岋細鎵ц杩欎竴琛屼唬鐮侊紝缁х画鎺ㄨ繘褰撳墠閫昏緫銆?*/
ordered_array,
/* 绗?{number}琛岋細鎵ц杩欎竴琛屼唬鐮侊紝缁х画鎺ㄨ繘褰撳墠閫昏緫銆?*/
0,
/* 绗?{number}琛岋細鎵ц杩欎竴琛屼唬鐮侊紝缁х画鎺ㄨ繘褰撳墠閫昏緫銆?*/
(int)(sizeof(ordered_array) / sizeof(ordered_array[0])) - 1,
/* 绗?{number}琛岋細鎵ц杩欎竴琛屼唬鐮侊紝缁х画鎺ㄨ繘褰撳墠閫昏緫銆?*/
68
/* 绗?{number}琛岋細鎵ц杩欎竴琛屼唬鐮侊紝缁х画鎺ㄨ繘褰撳墠閫昏緫銆?*/
);
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
block_pos = BlockSearch(ordered_array, (int)(sizeof(ordered_array) / sizeof(ordered_array[0])), blocks, 3, 57);
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細鎶婂綋鍓嶇粨鏋滄墦鍗板嚭鏉ワ紝鏂逛究瑙傚療绋嬪簭杩愯鎯呭喌銆?*/
printf("Sequential search position of 84: %d\n", seq_pos);
/* 绗?{number}琛岋細鎶婂綋鍓嶇粨鏋滄墦鍗板嚭鏉ワ紝鏂逛究瑙傚療绋嬪簭杩愯鎯呭喌銆?*/
printf("Binary search position of 31: %d\n", binary_pos);
/* 绗?{number}琛岋細鎶婂綋鍓嶇粨鏋滄墦鍗板嚭鏉ワ紝鏂逛究瑙傚療绋嬪簭杩愯鎯呭喌銆?*/
printf("Recursive binary search position of 68: %d\n", binary_recursive_pos);
/* 绗?{number}琛岋細鎶婂綋鍓嶇粨鏋滄墦鍗板嚭鏉ワ紝鏂逛究瑙傚療绋嬪簭杩愯鎯呭喌銆?*/
printf("Block search position of 57: %d\n", block_pos);
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
bst_root = NULL;
/* 绗?{number}琛岋細寮€濮嬩竴娆?for 寰幆锛屾寜鍥哄畾娆℃暟鎴栧尯闂撮噸澶嶆墽琛屽悗缁鍙ャ€?*/
for (i = 0; i < (int)(sizeof(bst_keys) / sizeof(bst_keys[0])); i++) {
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
bst_root = BSTInsert(bst_root, bst_keys[i]);
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細鎶婂綋鍓嶇粨鏋滄墦鍗板嚭鏉ワ紝鏂逛究瑙傚療绋嬪簭杩愯鎯呭喌銆?*/
printf("BST inorder before deletion: ");
/* 绗?{number}琛岋細璋冪敤涓€涓嚱鏁帮紝璁╁畠甯垜浠畬鎴愬綋鍓嶈繖涓€姝ユ搷浣溿€?*/
BSTInorder(bst_root);
/* 绗?{number}琛岋細鎶婂綋鍓嶇粨鏋滄墦鍗板嚭鏉ワ紝鏂逛究瑙傚療绋嬪簭杩愯鎯呭喌銆?*/
printf("\n");
/* 绗?{number}琛岋細鎶婂綋鍓嶇粨鏋滄墦鍗板嚭鏉ワ紝鏂逛究瑙傚療绋嬪簭杩愯鎯呭喌銆?*/
printf("BST search 37: %s\n", BSTSearch(bst_root, 37) != NULL ? "found" : "not found");
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
bst_root = BSTDelete(bst_root, 24);
/* 绗?{number}琛岋細鎶婂綋鍓嶇粨鏋滄墦鍗板嚭鏉ワ紝鏂逛究瑙傚療绋嬪簭杩愯鎯呭喌銆?*/
printf("BST inorder after deleting 24: ");
/* 绗?{number}琛岋細璋冪敤涓€涓嚱鏁帮紝璁╁畠甯垜浠畬鎴愬綋鍓嶈繖涓€姝ユ搷浣溿€?*/
BSTInorder(bst_root);
/* 绗?{number}琛岋細鎶婂綋鍓嶇粨鏋滄墦鍗板嚭鏉ワ紝鏂逛究瑙傚療绋嬪簭杩愯鎯呭喌銆?*/
printf("\n");
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
avl_root = NULL;
/* 绗?{number}琛岋細寮€濮嬩竴娆?for 寰幆锛屾寜鍥哄畾娆℃暟鎴栧尯闂撮噸澶嶆墽琛屽悗缁鍙ャ€?*/
for (i = 0; i < (int)(sizeof(avl_keys) / sizeof(avl_keys[0])); i++) {
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
avl_root = AVLInsert(avl_root, avl_keys[i]);
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細鎶婂綋鍓嶇粨鏋滄墦鍗板嚭鏉ワ紝鏂逛究瑙傚療绋嬪簭杩愯鎯呭喌銆?*/
printf("AVL preorder: ");
/* 绗?{number}琛岋細璋冪敤涓€涓嚱鏁帮紝璁╁畠甯垜浠畬鎴愬綋鍓嶈繖涓€姝ユ搷浣溿€?*/
AVLPreorder(avl_root);
/* 绗?{number}琛岋細鎶婂綋鍓嶇粨鏋滄墦鍗板嚭鏉ワ紝鏂逛究瑙傚療绋嬪簭杩愯鎯呭喌銆?*/
printf("\n");
/* 绗?{number}琛岋細鎶婂綋鍓嶇粨鏋滄墦鍗板嚭鏉ワ紝鏂逛究瑙傚療绋嬪簭杩愯鎯呭喌銆?*/
printf("AVL search 27: %s\n", AVLSearch(avl_root, 27) != NULL ? "found" : "not found");
/* 绗?{number}琛岋細鎶婂綋鍓嶇粨鏋滄墦鍗板嚭鏉ワ紝鏂逛究瑙傚療绋嬪簭杩愯鎯呭喌銆?*/
printf("AVL root = %d, height = %d\n", avl_root != NULL ? avl_root->key : -1, AVLHeight(avl_root));
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
rb_root = NULL;
/* 绗?{number}琛岋細寮€濮嬩竴娆?for 寰幆锛屾寜鍥哄畾娆℃暟鎴栧尯闂撮噸澶嶆墽琛屽悗缁鍙ャ€?*/
for (i = 0; i < (int)(sizeof(rb_keys) / sizeof(rb_keys[0])); i++) {
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
rb_root = RBInsert(rb_root, rb_keys[i]);
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭璧板摢涓垎鏀€?*/
if (rb_root != NULL) {
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
rb_root->color = RB_BLACK;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細鎶婂綋鍓嶇粨鏋滄墦鍗板嚭鏉ワ紝鏂逛究瑙傚療绋嬪簭杩愯鎯呭喌銆?*/
printf("Red-black inorder: ");
/* 绗?{number}琛岋細璋冪敤涓€涓嚱鏁帮紝璁╁畠甯垜浠畬鎴愬綋鍓嶈繖涓€姝ユ搷浣溿€?*/
RBInorder(rb_root);
/* 绗?{number}琛岋細鎶婂綋鍓嶇粨鏋滄墦鍗板嚭鏉ワ紝鏂逛究瑙傚療绋嬪簭杩愯鎯呭喌銆?*/
printf("\n");
/* 绗?{number}琛岋細鎶婂綋鍓嶇粨鏋滄墦鍗板嚭鏉ワ紝鏂逛究瑙傚療绋嬪簭杩愯鎯呭喌銆?*/
printf("Red-black search 45: %s\n", RBSearch(rb_root, 45) != NULL ? "found" : "not found");
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
rb_root = RBDelete(rb_root, 20);
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭璧板摢涓垎鏀€?*/
if (rb_root != NULL) {
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
rb_root->color = RB_BLACK;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細鎶婂綋鍓嶇粨鏋滄墦鍗板嚭鏉ワ紝鏂逛究瑙傚療绋嬪簭杩愯鎯呭喌銆?*/
printf("Red-black inorder after deleting 20: ");
/* 绗?{number}琛岋細璋冪敤涓€涓嚱鏁帮紝璁╁畠甯垜浠畬鎴愬綋鍓嶈繖涓€姝ユ搷浣溿€?*/
RBInorder(rb_root);
/* 绗?{number}琛岋細鎶婂綋鍓嶇粨鏋滄墦鍗板嚭鏉ワ紝鏂逛究瑙傚療绋嬪簭杩愯鎯呭喌銆?*/
printf("\n");
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
btree_root = NULL;
/* 绗?{number}琛岋細寮€濮嬩竴娆?for 寰幆锛屾寜鍥哄畾娆℃暟鎴栧尯闂撮噸澶嶆墽琛屽悗缁鍙ャ€?*/
for (i = 0; i < (int)(sizeof(btree_keys) / sizeof(btree_keys[0])); i++) {
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
btree_root = BTreeInsert(btree_root, btree_keys[i]);
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細鎶婂綋鍓嶇粨鏋滄墦鍗板嚭鏉ワ紝鏂逛究瑙傚療绋嬪簭杩愯鎯呭喌銆?*/
printf("B-tree structure:\n");
/* 绗?{number}琛岋細璋冪敤涓€涓嚱鏁帮紝璁╁畠甯垜浠畬鎴愬綋鍓嶈繖涓€姝ユ搷浣溿€?*/
BTreePrint(btree_root, 0);
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
btree_index = -1;
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
btree_found = BTreeSearch(btree_root, 35, &btree_index);
/* 绗?{number}琛岋細鎶婂綋鍓嶇粨鏋滄墦鍗板嚭鏉ワ紝鏂逛究瑙傚療绋嬪簭杩愯鎯呭喌銆?*/
printf("B-tree search 35: %s", btree_found != NULL ? "found" : "not found");
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭璧板摢涓垎鏀€?*/
if (btree_found != NULL) {
/* 绗?{number}琛岋細鎶婂綋鍓嶇粨鏋滄墦鍗板嚭鏉ワ紝鏂逛究瑙傚療绋嬪簭杩愯鎯呭喌銆?*/
printf(" in node slot %d", btree_index);
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細鎶婂綋鍓嶇粨鏋滄墦鍗板嚭鏉ワ紝鏂逛究瑙傚療绋嬪簭杩愯鎯呭喌銆?*/
printf("\n");
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
btree_root = BTreeDelete(btree_root, 30);
/* 绗?{number}琛岋細鎶婂綋鍓嶇粨鏋滄墦鍗板嚭鏉ワ紝鏂逛究瑙傚療绋嬪簭杩愯鎯呭喌銆?*/
printf("B-tree after deleting 30:\n");
/* 绗?{number}琛岋細璋冪敤涓€涓嚱鏁帮紝璁╁畠甯垜浠畬鎴愬綋鍓嶈繖涓€姝ユ搷浣溿€?*/
BTreePrint(btree_root, 0);
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
bplus_root = BuildSampleBPlusTree();
/* 绗?{number}琛岋細璋冪敤涓€涓嚱鏁帮紝璁╁畠甯垜浠畬鎴愬綋鍓嶈繖涓€姝ユ搷浣溿€?*/
BPlusPrintLeaves(bplus_root);
/* 绗?{number}琛岋細鎶婂綋鍓嶇粨鏋滄墦鍗板嚭鏉ワ紝鏂逛究瑙傚療绋嬪簭杩愯鎯呭喌銆?*/
printf("B+ search 24: %s\n", BPlusSearch(bplus_root, 24) ? "found" : "not found");
/* 绗?{number}琛岋細璋冪敤涓€涓嚱鏁帮紝璁╁畠甯垜浠畬鎴愬綋鍓嶈繖涓€姝ユ搷浣溿€?*/
BPlusPrintRange(bplus_root, 18, 42);
/* 绗?{number}琛岋細寮€濮嬩竴娆?for 寰幆锛屾寜鍥哄畾娆℃暟鎴栧尯闂撮噸澶嶆墽琛屽悗缁鍙ャ€?*/
for (i = 0; i < (int)(sizeof(bplus_extra_keys) / sizeof(bplus_extra_keys[0])); i++) {
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
bplus_root = BPlusInsert(bplus_root, bplus_extra_keys[i]);
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細鎶婂綋鍓嶇粨鏋滄墦鍗板嚭鏉ワ紝鏂逛究瑙傚療绋嬪簭杩愯鎯呭喌銆?*/
printf("After inserting 44 and 46:\n");
/* 绗?{number}琛岋細璋冪敤涓€涓嚱鏁帮紝璁╁畠甯垜浠畬鎴愬綋鍓嶈繖涓€姝ユ搷浣溿€?*/
BPlusPrintLeaves(bplus_root);
/* 绗?{number}琛岋細缁欏彉閲忋€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
bplus_root = BPlusDelete(bplus_root, 24);
/* 绗?{number}琛岋細鎶婂綋鍓嶇粨鏋滄墦鍗板嚭鏉ワ紝鏂逛究瑙傚療绋嬪簭杩愯鎯呭喌銆?*/
printf("After deleting 24:\n");
/* 绗?{number}琛岋細璋冪敤涓€涓嚱鏁帮紝璁╁畠甯垜浠畬鎴愬綋鍓嶈繖涓€姝ユ搷浣溿€?*/
BPlusPrintLeaves(bplus_root);
/* 绗?{number}琛岋細璋冪敤涓€涓嚱鏁帮紝璁╁畠甯垜浠畬鎴愬綋鍓嶈繖涓€姝ユ搷浣溿€?*/
BPlusPrintRange(bplus_root, 18, 46);
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細璋冪敤涓€涓嚱鏁帮紝璁╁畠甯垜浠畬鎴愬綋鍓嶈繖涓€姝ユ搷浣溿€?*/
InitHashOpenTable(&open_table);
/* 绗?{number}琛岋細璋冪敤涓€涓嚱鏁帮紝璁╁畠甯垜浠畬鎴愬綋鍓嶈繖涓€姝ユ搷浣溿€?*/
InitChainHashTable(&chain_table);
/* 绗?{number}琛岋細寮€濮嬩竴娆?for 寰幆锛屾寜鍥哄畾娆℃暟鎴栧尯闂撮噸澶嶆墽琛屽悗缁鍙ャ€?*/
for (i = 0; i < (int)(sizeof(hash_keys) / sizeof(hash_keys[0])); i++) {
/* 绗?{number}琛岋細璋冪敤涓€涓嚱鏁帮紝璁╁畠甯垜浠畬鎴愬綋鍓嶈繖涓€姝ユ搷浣溿€?*/
HashOpenInsert(&open_table, hash_keys[i]);
/* 绗?{number}琛岋細璋冪敤涓€涓嚱鏁帮紝璁╁畠甯垜浠畬鎴愬綋鍓嶈繖涓€姝ユ搷浣溿€?*/
ChainHashInsert(&chain_table, hash_keys[i]);
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細璋冪敤涓€涓嚱鏁帮紝璁╁畠甯垜浠畬鎴愬綋鍓嶈繖涓€姝ユ搷浣溿€?*/
PrintHashOpenTable(&open_table);
/* 绗?{number}琛岋細鎶婂綋鍓嶇粨鏋滄墦鍗板嚭鏉ワ紝鏂逛究瑙傚療绋嬪簭杩愯鎯呭喌銆?*/
printf("Open addressing search 84 -> slot %d\n", HashOpenSearch(&open_table, 84));
/* 绗?{number}琛岋細璋冪敤涓€涓嚱鏁帮紝璁╁畠甯垜浠畬鎴愬綋鍓嶈繖涓€姝ユ搷浣溿€?*/
PrintChainHashTable(&chain_table);
/* 绗?{number}琛岋細鎶婂綋鍓嶇粨鏋滄墦鍗板嚭鏉ワ紝鏂逛究瑙傚療绋嬪簭杩愯鎯呭喌銆?*/
printf("Chaining search 55: %s\n", ChainHashSearch(&chain_table, 55) != NULL ? "found" : "not found");
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑浠g爜閫昏緫娈点€?*/
/* 绗?{number}琛岋細璋冪敤涓€涓嚱鏁帮紝璁╁畠甯垜浠畬鎴愬綋鍓嶈繖涓€姝ユ搷浣溿€?*/
DestroyBST(bst_root);
/* 绗?{number}琛岋細璋冪敤涓€涓嚱鏁帮紝璁╁畠甯垜浠畬鎴愬綋鍓嶈繖涓€姝ユ搷浣溿€?*/
DestroyAVL(avl_root);
/* 绗?{number}琛岋細璋冪敤涓€涓嚱鏁帮紝璁╁畠甯垜浠畬鎴愬綋鍓嶈繖涓€姝ユ搷浣溿€?*/
DestroyRB(rb_root);
/* 绗?{number}琛岋細璋冪敤涓€涓嚱鏁帮紝璁╁畠甯垜浠畬鎴愬綋鍓嶈繖涓€姝ユ搷浣溿€?*/
DestroyBTree(btree_root);
/* 绗?{number}琛岋細璋冪敤涓€涓嚱鏁帮紝璁╁畠甯垜浠畬鎴愬綋鍓嶈繖涓€姝ユ搷浣溿€?*/
DestroyBPlusTree(bplus_root);
/* 绗?{number}琛岋細璋冪敤涓€涓嚱鏁帮紝璁╁畠甯垜浠畬鎴愬綋鍓嶈繖涓€姝ユ搷浣溿€?*/
DestroyChainHashTable(&chain_table);
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
return 0;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠缁撴瀯鎴栧嚱鏁板湪杩欓噷鏀跺彛銆?*/
}
继续阅读