一种算法导论B树删除实现

简述

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;
}

编译运行

参考博客

算法导论 之 B树 - 删除[C语言]_祁峰的博客-CSDN博客

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值