init commit
This commit is contained in:
186
archive/algorithm/struct/tree/b-tree.c
Normal file
186
archive/algorithm/struct/tree/b-tree.c
Normal file
@ -0,0 +1,186 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <memory.h>
|
||||
#include <math.h>
|
||||
#define M 3
|
||||
|
||||
typedef struct tree *prt_tree;
|
||||
|
||||
struct tree
|
||||
{
|
||||
int data; //存储的数据
|
||||
prt_tree left; //左子节点
|
||||
prt_tree right; //右子节点
|
||||
prt_tree brother; //兄弟节点
|
||||
};
|
||||
prt_tree create_node(int data)
|
||||
{
|
||||
prt_tree tree = malloc(sizeof(struct tree));
|
||||
memset(tree, 0, sizeof(struct tree));
|
||||
tree->data = data;
|
||||
return tree;
|
||||
}
|
||||
|
||||
prt_tree insert(int data, prt_tree root, prt_tree father)
|
||||
{
|
||||
if (root == NULL)
|
||||
{
|
||||
root = create_node(data);
|
||||
return root;
|
||||
}
|
||||
//在兄弟节点进行搜索,直到data夹在两个兄弟节点之中,或者相等,或者为空
|
||||
//如果相等不进行处理,直接返回
|
||||
//如果比最小的还小,插入节点后,与第一个交换返回
|
||||
//如果是夹在兄弟中,就进入第一个的右,或者第二个左节点
|
||||
//如果等于NULL的话,证明这是叶子节点,就直接在中间插入,否则进行插入操作,回到第一行
|
||||
//如果是空就插入在最后一个兄弟节点
|
||||
//插入之后继续进行循环,得到n来判断这个节点数量有没有大于m
|
||||
prt_tree tmp = root;
|
||||
int n = 0;
|
||||
while (tmp != NULL)
|
||||
{
|
||||
n += 1;
|
||||
if (data == tmp->data)
|
||||
{
|
||||
//相等的情况
|
||||
break;
|
||||
}
|
||||
else if (data < tmp->data)
|
||||
{
|
||||
//比最小还小的情况(也就是最小),往左边插入,先判断left节点是不是NULL
|
||||
//为NULL则认为是叶子节点,数量+1,然后跳出循环,新节点变为老节点
|
||||
//否则递归调用insert,往left节点继续搜索
|
||||
if (tmp->left == NULL)
|
||||
{
|
||||
prt_tree new_tree = create_node(data);
|
||||
new_tree->brother = tmp;
|
||||
n += 1;
|
||||
root = new_tree;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
//往左节点继续搜索
|
||||
insert(data, tmp->left, tmp);
|
||||
}
|
||||
}
|
||||
else if (tmp->brother == NULL)
|
||||
{
|
||||
//等于空的情况(也就是最大的情况),往右插入,先判断right节点是不是NULL
|
||||
//为NULL则认为是叶子节点,新节点加入兄弟节点后,tmp指向兄弟节点,跳出循环
|
||||
//否则递归调用insert,往right节点继续搜索
|
||||
if (tmp->right == NULL)
|
||||
{
|
||||
prt_tree new_tree = create_node(data);
|
||||
tmp->brother = new_tree;
|
||||
tmp = tmp->brother;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
insert(data, tmp->right, tmp);
|
||||
}
|
||||
}
|
||||
else if (data > tmp->data && data < tmp->brother->data)
|
||||
{
|
||||
//夹在中间的情况,如果right为空的就认为是叶子节点,插入在中间
|
||||
if (tmp->right == NULL)
|
||||
{
|
||||
//插入在中间,新建立一个新的节点,然后将节点插入到中间
|
||||
prt_tree new_tree = create_node(data);
|
||||
prt_tree tmpPrtTree = tmp->brother;
|
||||
tmp->brother = new_tree;
|
||||
new_tree->brother = tmpPrtTree;
|
||||
tmp = tmp->brother;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
//往父的right插入
|
||||
insert(data, tmp->right, tmp);
|
||||
}
|
||||
}
|
||||
tmp = tmp->brother;
|
||||
}
|
||||
//接着tmp继续循环,遍历这个节点有没有超过m
|
||||
while (tmp != NULL)
|
||||
{
|
||||
tmp = tmp->brother;
|
||||
n += 1;
|
||||
}
|
||||
//判断是否超过M
|
||||
if (n > M)
|
||||
{
|
||||
//超过m,取出中间的前一个节点
|
||||
prt_tree mid_before_tree = root;
|
||||
prt_tree mid_tree = NULL;
|
||||
int sub = ceil(M / 2);
|
||||
for (int i = 0; i < sub; i++)
|
||||
{
|
||||
mid_before_tree = mid_before_tree->brother;
|
||||
}
|
||||
mid_tree = mid_before_tree->brother;
|
||||
//取出中间的后,判断父节点,是不是等于当前,如果是等于当前root节点
|
||||
//将这一整个块从mid_tree分开,中间节点提取到上一节点
|
||||
mid_before_tree->brother = NULL;
|
||||
mid_tree->left = root;
|
||||
mid_tree->right = mid_tree->brother;
|
||||
mid_tree->brother = NULL;
|
||||
//则认为这是在操作根节点,操作的是根节点的话
|
||||
//就要将现在的这个节点变为根节点
|
||||
if (root == father)
|
||||
{
|
||||
root = mid_tree;
|
||||
}
|
||||
else
|
||||
{
|
||||
//然后判断比父节点大还是小
|
||||
//比父大就是直接插入到父的兄弟节点
|
||||
//然后父的兄弟的left为空
|
||||
//比父小就进行交换,插入
|
||||
//父right为空
|
||||
if (father->data > data)
|
||||
{
|
||||
prt_tree tmp_node = father->brother;
|
||||
father->brother = mid_tree;
|
||||
mid_tree->brother = tmp_node;
|
||||
}
|
||||
else
|
||||
{
|
||||
//连接兄弟节点
|
||||
mid_tree->brother = father->brother;
|
||||
father->brother = mid_tree;
|
||||
}
|
||||
}
|
||||
}
|
||||
printf("data:%d\tn:%d\n", data, n);
|
||||
return root;
|
||||
}
|
||||
|
||||
//排序输出
|
||||
void print_tree(prt_tree root)
|
||||
{
|
||||
if (root == NULL)
|
||||
return;
|
||||
print_tree(root->left);
|
||||
printf("%d\t", root->data);
|
||||
print_tree(root->brother);
|
||||
if (root->brother == NULL)
|
||||
{
|
||||
print_tree(root->right);
|
||||
}
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
prt_tree root = NULL;
|
||||
root = insert(1, root, root);
|
||||
root = insert(6, root, root);
|
||||
root = insert(8, root, root);
|
||||
root = insert(11, root, root);
|
||||
root = insert(15, root, root);
|
||||
root = insert(16, root, root);
|
||||
root = insert(18, root, root);
|
||||
print_tree(root);
|
||||
return 0;
|
||||
}
|
Reference in New Issue
Block a user