简述
1、本文没有画图,想看的话可以在书上找。也不对方法做过多解释,如果是通过搜索找到的这篇博客,看不懂的话,可以多跟着代码走几遍。
2、删除和插入,基本都是先做检查,使删除和插入数据后能继续满足B树性质。
3、本实现虽经过测试,但也不保证完全不存在问题,若发现错误,请留言或私信。
4、个人认为,删除时做的旋转可能太多,参考的博客是另外一种实现,但进行了回溯。
代码实现
btree.h
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
//#include "log4c.h"
#define T 3
typedef int keyType;
enum bool{
FALSE,
TRUE
};
struct B_TREE_NODE
{
// size
int size;
/*
删除时暂没做到正确赋值。
替代方式:判断是否有孩子节点
*/
enum bool leaf;
// 存放数据的数组
// t - 1 ~ 2t - 1(t >= 2)
keyType *keys;
// 数组形式 存放孩子节点的指针
// t ~ 2t
struct B_TREE_NODE **childs;
};
typedef struct B_TREE_NODE *nodep;
struct B_TREE
{
nodep root;
};
typedef struct B_TREE *treep;
nodep allocate_node(void);
treep btree_create(void);
int btree_search(nodep x , keyType k);
int btree_bin_find_idx(nodep x, keyType k);
void btree_insert(treep tp , keyType k);
void btree_split_child(nodep x , keyType i);
void btree_insert_nonfull(nodep x , keyType k);
int btree_delete(treep btree, keyType k);
int btree_delete_do(nodep x, keyType k);
int btree_delete_merge(nodep x, int i);
void btree_rotate_right(nodep x, int i, nodep l, nodep r);
void btree_rotate_left(nodep x, int i, nodep l, nodep r);
void btree_print(treep tp);
void btree_print_recursive(nodep x , keyType level);
void btree_free_tree(treep tp);
void btree_free_node(nodep x , keyType level);
void random_test(treep tp, int size);
void error_case(treep tp);
btree.c
#include "btree.h"
/**
* @brief 使用log4c需要在root 运行
* gcc -o b-tree-v3 b-tree-v3.c -llog4c -I /usr/local/log4c/include -L /usr/local/log4c/lib
* @return int
*/
int main(int argc, char **argv)
{
/*
log4c_category_t* mycat = NULL;
if (log4c_init()){
printf("log4c_init() failed");
}
*/
treep tp = btree_create();
//printf("%d,%d\n" , sizeof(int) , sizeof(nodep));
//printf("%d\n", (T << 1) - 1);
int t_size = 1000;
if(argc > 1)
{
t_size = atoi(argv[1]);
}
for(int i = 1 ; i < t_size ; ++ i)
{
btree_insert(tp , i);
//btree_print(tp);
}
for(int i = 0 ; i < t_size ; ++ i)
{
keyType r = btree_search(tp->root , i);
if(r != i)
{
printf("error r = %d," , r);
}
}
printf("\n\n");
btree_print(tp);
for(int i = 1 ; i < t_size ; ++ i)
{
btree_delete(tp , i);
//btree_print(tp);
}
for(int i = 1 ; i < t_size ; ++ i)
{
btree_insert(tp , i);
//btree_print(tp);
}
random_test(tp , t_size);
//error_case(tp);
btree_free_tree(tp);
return EXIT_SUCCESS;
}
void error_case(treep tp)
{
/*int test[] = {6,12,4,23,6,1,0,0,17,1,8,20,4,0,22,24,21,11,9,18,9,17,7,18,8,};
int test[] = {
958,974,238,536,175,734,61,691,564,979,973,281,986,587,283,163,587,739,73,907, 989,374,942,607,897,368,560,120,633,173,
638,944,147,876,480,675,962,893,718,526,224,691,159,210,630,443,374,218,182,799,125,171,173,419,130,422,787,43,895,420,
216,533,364,715,762,196,390,724,441,460,603,666,151,114,876,782,557,602,352,92,401,829,615,926,248,746,349,35,789,244,
807,357,129,524,72,243,72,815,320,514,275,923,180,427,37,408,561,947,11,265,39,764,94,654,691,694,752,392,81,893,988,240,250,
469,116,675,713,189,490,33,55,765,308,587,192,345,995,105,644,358,722,35,123,168,690,814,862,794,558,295,40,546,536,642,15,4,
317,728,193,807,113,600,573,421,187,117,119,535,575,763,893,297,799,16,466,841,182,328,987,92,976,379,638,512,22,654,868,339,734,
62,147,200,14,720,621,554,189,92,89,764,208,334,62,359,703,528,552,885,208,891,978,184,271,968,48,293,974,91};
*/
/*
int test[] = {
771,448,204,240,271,469,68,597,27,885,226,490,109,284,960,459,91,6,765,807,413,985,516,406,154,924,178,829,75,219,
617,846,19,821,439,642,643,859,239,670,744,817,160,205,101,472,665,545,479,782,704,892,119,572,650,274,497,828,455,572,
399,73,770,770,894,209,412,889,421,651,560,165,469,72,723,922,545,388,819,376,170,523,268,290,448,270,916,945,99,371,
869,850,796,639,621,691,201,33,580,622,37,492,139,858,565,862,132,110,602,952,486,773,827,106,415,275,376,331,572,827,
54,441,678,851,81,651,894,634,684,826,608,73,319,747,931,236,962,416,698,564,368,536,689,547,642,104,175,370,787,99,
550,194,541,228,45,974,231,291,608,267,117,568,341,788,667,624,24,629,40,722,546,760,610,235,660,252,692,187,975,831,
286,877,377,827,457,422,153,688,65,113,955,183,681,296,971,349,273,348,330,313,422,876,426,33,464,438,637,508,625,964,
691,911,841,69,91,298,843,244,986,909,358,942,92,39,238,415,740,863,115,71,529,538,299,955,923,115,393,560,975,370,
525,667,281,366,736,724,665,931,969,651,840,327,945,284,718,536,52,459,399,167,882,928,57,533,235,980,649,628,541,624,
350,418,643,632,136,731,356,801,663,677,805,855,356,102,140,75,638,192,886,38,711,120,318,121,653,554,101,654,534,994,
631,885,412,274,869,549,358,577,702,21,255,859,228,963,962,368,38,952,912,276,990,976,396,661,97,402,215,550,56,101,
545,687,338,309,314,207,210,672,785,265,45,392,124,273,355,438,994,746,391,258,22,733,234,771,394,683,173,961,234,581,
63,131,269,401,792,583,961,3,607,98,268,652,490,744,277,197,535,271,295,926,530,670,11,116,441,406,152,966,719,738,
547,134,869,168,888,661,751,849,16,358,947,284,362,789,381,640,338,916,911,634,194,793,304,205,262,97,963,414,415,683,
152,962,817,373,131,705,34,234,906,51,945,205,687,307,994,420,947,685,336,211,671,882,356,327,88,618,424,51,384,191,
86,888,505,904,261,988,961,648,223,220,51,520,425,90,827,772,511,127,457,847,338,128,82,694,455,170,665,231,573,401,
422,660,290,279,916,903,268,229,551,491,449,954,363,875,45,190,647,556,317,456,755,7,936,837,54,391,359,719,974,933,
120,748,945,762,27,861,666,295,90,569,138,540,524};
*/
/*
int test[] = {
424,849,205,11,915,839,790,559,854,849,46,632,43,864,763,933,801,218,379,605,48,485,18,395,101,195,53,197,643,520,506,67,
370,63,78,285,255,220,196,109,421,243,93,817,459,857,750,612,427,481,217,827,966,588,222,68,135,275,617,779,796,475,198,
166,539,629,803,794,201,351,255,623,594,700,792,405,909,542,18,337,375,587,164,342,175,387,762,311,14,731,442,162,207,640,
680,746,621,835,892,823,187,499,798,781,199,590,539,109,484,557,446,859,144,962,201,672,349,315,983,716,47,425,878,254,417,
559,352,39,394,596,862,933,95,660,67,646,250,606,755,734,163,553,945,659,516,499,331,217,814,666,933,213,443,812,819,861,723,
523,900,469,119,762,403,566,774,822,213,376,428,320,462,943,874,407,954,742,906,638,959,721,304,893,286,748,57,106,961,132,
629,861,953,101,975,708,19,101,530,584,477,958,905,939,253,131,346,208,873,253,846,832,326,502,77,964,602,486,70,563,970,52,
424,924,505,751,632,876,852,515,461,329,825,366,268,79,849,967,287,722,572,485,906,250,987,336,214,590,822,637,505,793,41,930,
69,898,681,53,774,534,568,235,215,394,953,836,825,154,155,464,876,727,949,135,329,288,471,543,230,645,532,736,790,925,18,859,
823,699,265,950,585,833,185,153,579,491,989,404,997,144,868,874,223,169,361,552,458,184,447,688,829,980,776,972,257,794,183,81,
846,448,31,431,634,568,936,213,411,925,970,409,421,838,635,644,8,996,548,818,180,996,858,361,328,635,333,585,429,517,18,275,317,
49,59,951,970,995,165,381,273,135,790,694,325,777,691,685,773,239,503,305,587,362,19,915,997,704,853,778,221,871,54,539,921,113,
490,243,108,7,624,381,494,767,428,820,544,119,857,670,710,361,327,298,75,698,213,424,403,66,202,624,290,608,515,563,721,358,806,
182,717,782,915,212,549,343,384,446,814,241,468,525,954,147,823,29,846,388,805,249,807,360,225,97,968,93,660,690,451,818,224,168,
600,139,732,502,483,116,300,297,358,120,174,312,267,997,694,465,738,499,714,545,859,292,994,828,385,6,870,188,824,94,356,776,233,
89,278,68,557,930,718,915,50,892,228,670,242,274,135,332,773,202,229,985,494,575,165,231,581,387,419,757,833,775,533,66,216,164,
487,774,446,557,41,497,801,62};
*/
/*
int test[] = {
546,742,591,32,508,588,45,561,35,643,3,597,978,345,917,224,308,580,769,955,498,791,832,794,927,419,597,159,167,848,341,65,590,284,449,
450,873,846,11,260,489,367,857,819,64,126,44,725,58,165,680,908,956,864,702,883,283,299,394,802,499,87,219,441,371,668,244,596,514,607,
856,355,974,66,175,391,544,571,116,603,736,796,511,692,12,566,927,647,217,321,450,717,408,669,510,131,690,754,728,556,362,936,912,688,
2,439,79,547,10,195,502,746,343,365,790,355,931,717,3,149,38,805,218,798,826,728,281,516,483,9,425,197,946,337,885,300,776,965,199,138,
160,53,884,856,771,674,211,54,743,566,555,133,371,773,283,198,854,564,66,337,926,491,534,224,180,771,524,308,736,76,446,249,129,682,105,
900,708,668,955,451,235,510,584,606,636,867,156,490,784,223,179,710,66,65,934,247,836,810,555,573,886,354,174,16,36,279,268,745,947,575,
196,182,86,133,141,74,0,649,564,784,224,95,846,291,160,132,890,348,943,445,273,181,151,447,549,188,726,818,933,674,393,129,208,831,262,
701,905,615,351,821,751,927,916,598,218,428,730,108,777,25,906,50
};
*/
/*
int test[] = {
402,212,198,486,188,141,55,363,66,368,260,144,397,331,245,99,46,156,94,485,71,485,294,300,297,22,305,248,189,79,232,91,144,431,77,184,
424,484,47,490,352,308,134,102,491,232,201,389,240,147,374,311,484,20,112,281,42,269,29,231,349,262,174,345,45,104,29,469,88,428,311,
293,88,297,395,79,29,448,468,270,95,194,433,431,215,45,213,109,167,94,193,368,208,367,213,253,323,242,222,264,170,385,57,259,183,452,
190,64,400,11,334,347,205,120,278,272,165,491,382,184,438,75,52,146,294,265,400,470,359,474,234,382,360,291,493,395,95,183,459,495,46,
146,194,252,266,472,24,283,316,258,468,254,185,372,400,480,490,152,302,349,127,36,83,339,179,76,234,274,112,193,121,158,339,315,262,105,
139,139,389,455,397,209,61,83,81,314,415,71,466,217,273,93,105,356,432,136,285,18,410,249,212,383,407,403,50,22,9,41,161,250,349,410,459,
410,345,392,224,112,464,191,181,89,136,138,445,421,274,82,439,184,331,3,419,91,407,321,465,416,363,478,18,212,388,329,122,86,221,199,198,
185,242,232,126,378,370,424,299,145,6,91,181,190,94,101,281,1,274,2};
*/
int del_arr[] = {745,980,893,713,523,58,358,326,694,500,362,903,611,827,232,65,197,130,618,688,443,579,18,654,447,643,585,169,534,920,835,279,
900,728,992,775,786,350,101,480,202,463,383,813,643,615,231,840,746,201,880,541,781,250,547,228,893,484,397,779,405,584,58,657,312,402,433,
450,104,534,931,306,350,666,472,993,634,703,185,732,256,65,625,37,668,172,617,561,657,367,341,414,951,751,71,616,154,504,66,610,39,349,269,
389,16,741,734,2,796,919,734,52,336,711,442,4,883,411,918,892,778,611,306,730,362,378,698,868,882,764,479,273,114,100,14,130,841,748,484,989,
19,570,393,356,281,187,360,164,599,630,409,377,241,715,459,956,445,157,824,680,922,655,953,388,755,320,870,948,68,354,289,88,924,35,796,205,
222,508,721,821,139,130,551,380,198,362,336,995,520,513,675,794,520,981,182,628,653,52,576,73,758,218,513,682,253,309,887,475,818,960,649,
957,443,552,689,993,914,26,988,786,891,16,932,411,349,466,39,2,870,968,75,628,538,589,310,791,898,549,618,68,862,619,25,305,171,67,298,438,
93,638,224,336,654,157,747,3,623,139,357,494,459,433,122,997,374,785,140,272,686,110,693,548,82,70,853,605,137,503,43,582,142,268,918,796,
777,18,152,752,157,509,246,968,294,721,317,668,858,809,293,544,271,986,445,353,408,298,959,546,802,2,128,296,622,47,444,751,65,596,504,574,
458,102,894,104,175,563,773,33,372,418,930,643,756,375,997,164,25,308,710,179,662,191,475,285,590,920,388,655,868,892,581,678,995,827,783,
522,390,908,556,762,678,838,757,434,565,754,950,942,414,13,122,77,204,949,714,794,869,102,801,90,995,734,768,342,561,551,864,303,811,772,
65,489,962,822,275,527,929,226,470,343,239,944,772,443,893,486,589,115,589,742,557,936,476,325,278,389,229,142,692,40,267,757,882,229,931,
157,757,212,383,579,908,974,875,680,417,120,167,358,235,108,100,792,44,576,470,322,317,699,816,9,91,83,118,325,313,402,483,422,614,218,353,
522,193,228,555,962,348,722,321,936,182,773,728,226,702,550,900,19,601,716,29,45,152,499,370,817,901,205,239,516,424,592,390,617,172,945,
931,520,19,604,456,201,378,537,779,80,87,679,451,41,748,832,86,900,332,808,717,233,14,308,101,790,252,492,759,424,789,690,944,809,295,753,
362,25,290,494,457,729,173,908,122,273,741,208,525,425,369,594,658,383,902,760,173,154,604,932,578,393,974,875,554,621,628,269,646,270,763,
103,351,288,364,474,914,457,34,439,882,403,34,892,138,288,652,311,795,608,595,725,2,922,600,908,543,580,177,190,202,292,293,554,933,9,28,
847,466,414,286,348,818,672,241,956,961,245,620,756,854,567,481,208,489,434,468,33,366,998,223,569,290,868,123,223,878,503,422,344,917,709,
45,87,733,286,396,46,883,16,802,737,583,636,297,73,422,766,458,788,764,681,709,406,901,184,982,131,687,404,828,957,465,873,396,199,511,792,
245,394,160,400,484,96,388,781,521,162,899,979,950,663,12,12,70,913,196,52,45,236,456,873,193,274,98,941,473,609,86,70,355,246,470,839,342,
210,621,215,372,872,194,675,536,206,687,958,472,883,362,869,119,170,94,664,444,192,958,269,153,44,340,508,642,162,348,337,373,321,552,745,193,
99,420,81,305,459,39,129,695,753,350,166,924,444,183,368,988,141,638,141,537,978,2,179,492,350,516,865,23,69,963,568,168,383,650,825,195,41,
307,890,147,657,56,71,102,239,791,442,732,429,584,269,759,586,449,252,288,317,469,663,386,432,231,906,168,233,84,363,627,391,605,774,400,661,
845,854,253,988,297,337,418,881,607,529,819,408,133,459,725,603,122,464,387,705,722,555,939,158,918,918,901,523,692,302,537,889,156,142,877,
453,831,647,686,790,529,857,198,662,316,276,617,438,92,5,144,166,560,435,325,831,353,226,706,397,880,595,638,389,89,515,842,921,515,881,711,
44,738,910,706,407,538,676,197,630,681,693,796,241,128,473,424,833,52,131,230,932,726,868,321,816,736,516,737,251,397,800,295,487,62,353,246,
600,29,444,582,62,137,731,656,266,204,80,99,256,211,682,541,290,902,862,458,638,378,547,889,127,347,536,967,762,242,213,362,623,657,297,686,
795,380,342,413,584,774,864,193,338,546,86,628,449,948,438,439,679,337,681,158,684,217,125,446,811,339,161,435,348,810,473,495,190,815,908,
126,941,};
for(int i = 0, end = sizeof(del_arr)/sizeof(int); i < end; ++i)
{
//btree_print(tp);
if(del_arr[i] == 448)
{
btree_delete(tp , del_arr[i]);
}
else
{
btree_delete(tp , del_arr[i]);
}
}
int ins_arr[] = {125,671,279,671,757,259,472,58,697,912,737,34,593,895,71,162,373,869,326,64,382,761,412,192,586,908,382,753,168,509,694,293,
180,974,317,290,233,141,348,283,405,85,317,350,332,740,513,705,610,839,769,344,952,534,537,538,794,919,291,962,780,337,256,313,311,925,603,545,
66,951,828,472,388,497,822,720,238,687,778,200,878,547,544,182,433,433,72,227,705,715,190,485,53,798,150,364,723,753,261,141,704,441,965,92,
291,140,165,881,827,943,81,58,842,977,592,276,763,665,503,468,380,45,305,785,843,456,150,918,209,763,412,266,205,377,710,496,517,875,377,697,
170,810,107,13,139,699,289,902,716,144,370,97,190,676,882,385,484,384,656,693,148,68,311,705,797,22,201,315,249,930,364,420,740,823,433,231,522,
74,134,239,218,856,688,760,532,922,146,368,659,154,62,807,222,725,864,19,747,417,686,997,347,402,417,439,225,202,670,100,276,804,339,846,13,379,
607,545,301,105,266,312,259,328,471,833,405,335,204,153,752,243,502,451,645,919,890,223,121,913,323,749,69,14,595,82,393,202,980,46,659,246,359,
918,926,182,103,331,518,308,484,622,551,986,74,548,257,964,771,730,229,446,479,299,460,75,381,205,629,361,604,289,607,315,207,533,497,311,865,
15,971,701,990,522,40,64,422,297,380,546,380,610,992,859,909,805,286,290,10,916,4,614,205,611,281,764,497,779,427,362,146,398,63,136,272,455,
552,695,753,933,241,133,543,585,344,804,390,631,446,401,547,450,367,104,414,649,868,911,780,648,273,278,46,688,767,671,496,319,366,249,252,959,
734,147,544,430,303,935,61,750,688,960,552,407,64,966,408,285,229,188,933,854,819,331,895,586,2,391,905,720,640,510,679,726,9,576,156,665,863,
570,767,551,530,319,958,947,638,367,584,867,907,517,722,726,848,617,664,203,8,922,923,0,432,955,78,793,531,234,458,394,156,225,297,687,897,607,
986,535,326,570,402,586,439,476,664,639,445,329,842,453,251,118,805,35,73,883,828,604,470,639,350,978,864,999,17,761,958,3,648,285,925,403,871,
716,879,535,356,325,216,550,130,467,668,288,854,93,171,683,49,993,674,751,972,538,750,989,652,709,345,300,346,270,703,569,987,935,456,695,260,
673,597,742,492,618,30,347,711,554,382,113,547,56,864,871,946,615,213,598,676,558,251,22,180,954,943,519,241,399,566,501,72,164,596,917,134,626,
264,197,180,646,310,80,54,175,951,0,142,516,951,818,74,202,192,255,508,135,126,750,886,693,251,959,209,199,228,343,826,492,540,358,490,851,438,
544,378,742,896,872,258,847,42,685,49,234,292,558,721,418,308,607,463,911,918,672,111,146,15,289,990,908,647,832,111,438,728,489,180,625,361,
790,472,403,475,874,989,767,784,62,538,444,21,1,707,292,674,170,790,41,459,781,949,459,613,60,897,342,901,77,967,614,219,791,369,695,17,710,814,
153,772,704,597,146,706,305,438,732,475,228,773,287,9,723,746,975,135,643,317,389,72,636,3,291,779,373,338,149,83,505,302,208,209,900,354,915,
557,144,647,32,372,773,671,734,496,417,709,983,412,378,372,484,14,376,128,145,101,818,294,536,323,949,96,885,849,450,800,758,594,800,790,319,
573,814,53,421,231,762,756,644,140,129,480,506,857,960,3,310,131,650,846,454,599,943,691,800,745,844,558,340,644,700,11,569,514,64,342,98,178,
98,94,318,579,926,176,436,887,531,98,370,181,945,176,132,240,868,932,985,712,842,677,708,543,688,629,409,752,971,507,930,421,953,600,353,880,
128,141,119,660,240,489,193,537,665,326,777,533,610,762,245,453,440,305,348,480,934,109,585,257,617,515,31,570,468,384,802,948,525,921,608,117,
410,154,654,76,832,431,961,442,194,559,247,986,864,947,818,151,57,403,408,26,271,439,948,739,175,751,687,701,24,648,170,435,802,825,863,986,256,
176,780,802,735,380,140,952,327,959,103,736,714,863,114,985,655,63,724,830,166,764,883,190,412,54,977,566,879,840,904,487,17,684,290,104,64,430,
408,744,741,863,480,456,727,595,441,734,10,518,564,528,634,448,718,46,854,696,964,733,888,868,220,257,904,862,362,969,645,122,65,738,986,897,
194,65,492,988,799,854,858,363,382,492,163,453,890,17,149,206,102,389,74,675,647,330,889,361,651,534,483,716,273,469,614,819,534,458,159,333,
313,17,49,47,861,564,500,751,934,1,957,36,391,383,63,38,714,};
for(int i = 0, end = sizeof(ins_arr)/sizeof(int); i < end; ++i)
{
btree_print(tp);
if(ins_arr[i] == 71)
{
btree_print(tp);
btree_insert(tp , ins_arr[i]);
}
else
{
btree_insert(tp , ins_arr[i]);
}
}
}
void random_test(treep tp, int t_size)
{
srand((unsigned)time(NULL));
int a = 0;
for(int i = 1 ; i < t_size ; ++ i)
{
printf("顺序删除开始\n");
//btree_print(tp);
for(int i = t_size ; i > 0 ; -- i)
{
if(i == 883)
{
btree_delete(tp , i);
}
else
{
btree_delete(tp , i);
}
//btree_print(tp);
}
printf("顺序删除结束\n");
//btree_print(tp);
for(int i = 1 ; i < t_size ; ++ i)
{
btree_insert(tp , i);
//btree_print(tp);
}
printf("顺序插入结束\n");
//btree_print(tp);
/*
for(int i = 0 ; i < t_size ; ++ i)
{
keyType r = btree_search(tp->root , i);
if(r != i)
{
printf("error r = %d\n" , r);
}
}
*/
printf("随机删除1{");
for(int i = t_size ; i > 0 ; -- i)
{
a = rand() % t_size;
printf("%d,", a);
btree_delete(tp , a);
//btree_print(tp);
}
printf("}\n");
//btree_print(tp);
printf("随机插入1{");
for(int i = t_size ; i > 0 ; -- i)
{
a = rand() % t_size;
printf("%d,", a);
btree_insert(tp , a);
//btree_print(tp);
}
printf("}\n");
//btree_print(tp);
printf("随机删除2{");
for(int i = t_size ; i > 0 ; -- i)
{
a = rand() % t_size;
printf("%d,", a);
btree_delete(tp , a);
//btree_print(tp);
}
printf("}\n");
printf("顺序删除开始\n");
//btree_print(tp);
for(int i = t_size ; i > 0 ; -- i)
{
btree_delete(tp , i);
//btree_print(tp);
}
printf("顺序删除结束\n");
printf("随机插入2{");
for(int i = t_size ; i > 0 ; -- i)
{
a = rand() % t_size;
printf("%d,", a);
btree_insert(tp , a);
//btree_print(tp);
}
printf("}\n");
}
btree_print(tp);
}
nodep allocate_node(void)
{
nodep node = calloc(1 , sizeof(struct B_TREE_NODE));
if(!node)
{
return NULL;
}
node->keys = calloc((T << 1) - 1, sizeof(keyType));
node->childs = calloc(T << 1, sizeof(nodep));
//calloc 不需要手动初始化
//node->size = 0;
//默认叶子节点
node->leaf = TRUE;
return node;
}
treep btree_create(void)
{
treep tree = calloc(1, sizeof(struct B_TREE));
tree->root = allocate_node();
return tree;
}
keyType btree_search(nodep x , keyType k)
{
int i = 0;
for(; i < x->size; ++i)
{
if(k <= x->keys[i])
{
break;
}
}
if(x->keys[i] == k)
{
return x->keys[i];
}
else if(TRUE == x->leaf)
{
//null
return 0;
}
else
{
return btree_search(x->childs[i], k);
}
}
int btree_bin_find_idx(nodep x, keyType k)
{
int i = -1;
int l = 0, r = x->size - 1;
while(r >= l)
{
//int m = (l + r) >> 1;
int m = l + ((r - l) >> 1);
int mk = x->keys[m];
if(mk == k)
{
i = m;
break;
}
else if(mk > k)
{
r = m - 1;
}
else
{
l = m + 1;
}
}
return i;
}
void btree_insert(treep tp , keyType k)
{
//printf("add----------------********%2d*******-------------------\n", k);
nodep root = tp->root;
if(root->size == (T << 1) - 1)
{
nodep x = allocate_node();
x->childs[0] = root;
x->leaf = FALSE;
tp->root = x;
btree_split_child(x, 0);
btree_insert_nonfull(x, k);
}
else
{
btree_insert_nonfull(root, k);
}
}
void btree_split_child(nodep x , int i)
{
nodep y = x->childs[i];
nodep z = allocate_node();
z->leaf = y->leaf;
int hs = y->size >> 1;
for(int i = 0; i < hs; ++i)
{
z->keys[i] = y->keys[hs + i + 1];
z->childs[i] = y->childs[hs + i + 1];
}
z->size = hs;
z->childs[hs] = y->childs[y->size];
y->size = hs;
//将x元素的key 和 childs向后挪动一个位置
for(int j = x->size; j > i; --j)
{
x->keys[j] = x->keys[j - 1];
x->childs[j + 1] = x->childs[j];
}
++x->size;
x->childs[i + 1] = z;
x->keys[i] = y->keys[hs];
}
void btree_insert_nonfull(nodep x , keyType k)
{
if(x->leaf == TRUE)
{
//
int i = btree_bin_find_idx(x, k);
if(i >= 0)
{
x->keys[i] == k;
}
else
{
i = x->size;
for(; i > 0; --i)
{
if(k < x->keys[i - 1])
{
x->keys[i] = x->keys[i - 1];
}
else
{
break;
}
}
x->keys[i] = k;
++ x->size;
}
}
else
{
int i = 0;
for(; i < x->size; ++i)
{
if(k <= x->keys[i])
{
break;
}
}
//相同key时更新数据
if(i < x->size && k == x->keys[i])
{
x->keys[i] = k;
return;
}
nodep child = x->childs[i];
if(child->size >= (T << 1) -1)
{
btree_split_child(x, i);
btree_insert_nonfull(x, k);
}
else
{
btree_insert_nonfull(child, k);
}
}
}
/**
* @brief 指针执行删除的入口方法,并检查root节点。
*
* @param tree
* @param k
* @return int
*/
int btree_delete(treep tree, keyType k)
{
//printf("del----------------********%2d*******-------------------\n", k);
nodep root = tree->root;
int result = btree_delete_do(root, k);
//由于合并导致root节点上的元素个数会变为0,并且root有子节点,此时将root的第一个孩子设为root。
if(root->size == 0 && root->leaf == FALSE)
{
free(root);
tree->root = root->childs[0];
}
return result;
}
/**
* @brief 合并x 的第i个元素两边的节点
*
* @param x
* @param i
* @return int
*/
int btree_delete_merge(nodep x, int i)
{
nodep dest = x->childs[i];
nodep src = x->childs[i + 1];
//将 x第i个元素和 src所有的元素和childs挪到dest中
dest->keys[dest->size] = x->keys[i];
++dest->size;
memcpy(dest->keys + dest->size, src->keys, src->size * sizeof(keyType));
memcpy(dest->childs + dest->size, src->childs, (src->size + 1) * sizeof(nodep));
dest->size += src->size;
free(src);
//合并后将x i之后的元素向前移动一个位置
for(int j = i; j < x->size - 1; ++j)
{
x->keys[j] = x->keys[j + 1];
x->childs[j + 1] = x->childs[j + 2];
}
--x->size;
return 1;
}
int btree_delete_do(nodep x, keyType k)
{
// 为叶子节点,做真正的删除动作
if(x->leaf == TRUE)
{
// 叶子节点可以使用二分查找
int i = btree_bin_find_idx(x, k);
if(i >= 0)
{
for(int j = i, end = x->size - 1; j < end; ++ j)
{
x->keys[j] = x->keys[j + 1];
}
-- x->size;
return 1;
}
else
{
return 0;
}
}
else
{
int i = 0;
for(; i < x->size; ++i)
{
if(k <= x->keys[i])
{
break;
}
}
// k在当前节点中
if(i < x->size && x->keys[i] == k)
{
//先判断左右孩子是否需要合并
nodep l = x->childs[i], r = x->childs[i + 1];
if(l->size + r->size < (T << 1) - 1)
{
btree_delete_merge(x, i);
return btree_delete_do(l, k);
}
else
{
nodep t = l;
// 从左子节点选出最大的key
while(t->leaf == FALSE)
{
//此时l相当于t的父节点
//l = t;
t = t->childs[t->size];
}
//比k小的最大key
keyType lm = t->keys[t->size - 1];
x->keys[i] = lm;
if(l->size == T - 1)
{
if(t == l)
{
//进到此处 k已经被替换掉,不能继续删除lm
-- t->size;
lm = k;
//return 1;
}
btree_rotate_left(x, i, l, r);
}
return btree_delete_do(l, lm);
}
}
else
{
nodep l = NULL, r = NULL;
if(i < x->size)
{
//先判断左右孩子是否需要合并
l = x->childs[i];
r = x->childs[i + 1];
if(l->size + r->size < (T << 1) - 1)
{
// 往left节点合并
btree_delete_merge(x, i);
//
return btree_delete_do(l, k);
}
//目标节点存在的key个数等于最小约定个数时,经过x ,从邻居节点挪一个key和child
if(l->size == T - 1 )
{
btree_rotate_left(x, i, l, r);
}
return btree_delete_do(l, k);
}
else
{
//先判断左右孩子是否需要合并
l = x->childs[i - 1];
r = x->childs[i];
if(l->size + r->size < (T << 1) - 1)
{
// 往left节点合并
btree_delete_merge(x, i - 1);
//
return btree_delete_do(l, k);
}
//目标节点存在的key个数等于最小约定个数时,经过x ,从邻居节点挪一个key和child
if(r->size == T - 1)
{
btree_rotate_right(x, i - 1, l, r);
}
return btree_delete_do(r, k);
}
}
}
}
void btree_free_tree(treep tp)
{
btree_free_node(tp->root , 1);
free(tp->root);
tp->root = NULL;
free(tp);
tp = NULL;
}
void btree_print(treep tp)
{
btree_print_recursive(tp->root , 1);
//printf("\n-------------------*******pend*******-------------------\n");
}
void btree_print_recursive(nodep x , int level)
{
if(!x)
{
return;
}
int size = x->size;
//log4c_category_t* mycat = log4c_category_get("btree");
//char line[500];
printf("level = %d\tsize = %d\tcurr=%p\tleaf=%d", level, size, x, x->leaf);
//sprintf(line, "level = %d\tsize = %d\tcurr=%p", level, size, x);
for(int i = 0; i < level; ++i){
printf("\t");
//strcat(line, "\t");
}
printf("[");
//strcat(line, "[");
//printf("parent=%p\t[", x->parent);
//MIN(x->n , T << 1)
for(int i = 0; i < size; ++ i)
{
if(i == (size - 1))
{
printf("%d" , x->keys[i]);
}
else
{
printf("%d," , x->keys[i]);
}
//strcat(line, x->keys[i]);
}
printf("]\n");
//strcat(line, "]\n");
//printf(line);
//log4c_category_log(mycat, LOG4C_PRIORITY_ERROR, line);
for(int i = 0 ; i <= size; ++ i)
{
// 第一个元素为空,其后的元素不需要释放
if(x->childs && *(x->childs))
{
btree_print_recursive(x->childs[i] , level + 1);
}
else
{
break;
}
}
}
void btree_free_node(nodep x , int level)
{
if(!x)
{
return;
}
int size = x->size;
/*
printf("level = %d,n = %d\np=%p\t[" , level, size, x);
//MIN(x->n , T << 1)
for(int i = 0; i < size; ++ i)
{
if(i == (size - 1))
{
printf("%d" , x->keys[i]);
}
else
{
printf("%d," , x->keys[i]);
}
}
printf("]\n");
*/
for(int i = 0 ; i <= size; ++ i)
{
// 第一个元素为空,其后的元素不需要释放
if(x->childs && *(x->childs))
{
btree_free_node(x->childs[i] , level + 1);
}
else
{
free(x->childs);
x->childs = NULL;
break;
}
}
free(x->keys);
x->keys = NULL;
//x是可能是某个数组中的元素,导致多次释放
//free(x);
x = NULL;
}
void btree_rotate_right(nodep x, int i, nodep l, nodep r)
{
for(int j = r->size; j > 0; --j)
{
r->keys[j] = r->keys[j - 1];
if(r->leaf == FALSE)
{
r->childs[j + 1] = r->childs[j];
}
}
r->childs[1] = r->childs[0];
++r->size;
r->keys[0] = x->keys[i];
r->childs[0] = l->childs[l->size];
--l->size;
x->keys[i] = l->keys[l->size];
}
void btree_rotate_left(nodep x, int i, nodep l, nodep r)
{
l->keys[l->size] = x->keys[i];
++l->size;
l->childs[l->size] = r->childs[0];
x->keys[i] = r->keys[0];
for(int j = 0, end = r->size - 1; j < end; ++ j)
{
r->keys[j] = r->keys[j + 1];
if(r->leaf == FALSE)
{
r->childs[j] = r->childs[j + 1];
}
}
r->childs[r->size - 1] = r->childs[r->size];
// 此句和上一句写在一出现问题?r->childs[r->size - 1] = r->childs[r->size--];
-- r->size;
}