摘自:《算法:C语言实现 (第1~4部分)》
//B_tree.h
typedef char Item;
typedef Item Key;
#define key(A) (A)
#define M 6
#define NULLitem (-1)
typedef struct STnode *link;
void STinit();
Item STsearch(Key v);
void STinsert(Item item);
//B_tree.cpp
#include <iostream>
#include <malloc.h>
#include "B_tree.h"
using namespace std;
typedef struct
{
Key key;
union {link next; Item item;} ref;
} entry;
struct STnode
{
entry b[M];
int m;
};
static link head;
static int H, N;
link NEW()
{
link x = (link)malloc(sizeof *x);
x->m = 0;
return x;
}
void STinit()
{
head = NEW(); H = 0; N = 0;
}
//搜索
Item searchR(link h, Key v, int H)
{
int j;
if(H == 0)
for (j = 0; j < h->m; j++)
if(v == h->b[j].key)
return h->b[j].ref.item;
if(H != 0)
for (j = 0; j < h->m; j++)
if((j+1 == h->m) || (v < h->b[j+1].key))
return searchR(h->b[j].ref.next, v, H-1);
return NULLitem;
}
Item STsearch(Key v)
{
return searchR(head, v, H);
}
/************************************************************************/
/* M为偶数,树中的每个节点至多只有M-1个数据项,
对一个节点分裂之前可以插入第M个数据项 */
/************************************************************************/
link split(link h)
{
int j;
link t = NEW();
for(j = 0; j < M/2; j++)
t->b[j] = h->b[j + M/2];
t->m = M/2;
h->m = M/2;
return t;
}
//插入操作
link insertR(link h, Item item, int H)
{
int i, j;
Key v = key(item);
entry x;
link t, u;
x.key = v;
x.ref.item = item;
if (H == 0)
for(j = 0; j < h->m; j++)
if(v < h->b[j].key)
break;
if(H != 0)
for(j = 0; j < h->m; j++)
if((j+1 == h->m) || (v < h->b[j+1].key))
{
t = h->b[j++].ref.next;
u = insertR(t, item, H-1);
if(u == NULL)
return NULL;
x.key = u->b[0].key;
x.ref.next = u;
break;
}
for(i = (h->m)++; i > j; i--)
h->b[i] = h->b[i-1];
h->b[j] = x;
if(h->m < M) //数据项到M就会分裂,即最多保持M-1个,
return NULL; //但第M个可以插入
else
return split(h);
}
void STinsert(Item item)
{
link t, u = insertR(head, item, H);
if(u == NULL) return;
t = NEW(); //分裂根节点
t->m = 2;
t->b[0].key = head->b[0].key;
t->b[0].ref.next = head;
t->b[1].key = u->b[0].key;
t->b[1].ref.next = u;
head = t;
H++;
}
//main.cpp 测试主函数
#include <iostream>
#include "B_tree.h"
using namespace std;
int main(void)
{
STinit();
char c;
STinit();
while ((c = getchar()) != EOF)
{
if(c == ' ' || c == '\t' || c == '\n')
continue;
STinsert(c);
}
while ((c = getchar()) != EOF)
{
if(c == ' ' || c == '\t' || c == '\n')
continue;
if(c == STsearch(c))
cout << "found " << c << endl;
else
cout << "not found " << c << endl;
}
}