声明
看书上的看不懂,就自己瞎想了一个。不知道还能不能叫做B树。它的本质是一串排好序的链表,然后根据B树的性质对顺序链表分层实现的。测试数据很少,不确定代码的正确性。
思路
- 插入一个数的时候进行链表的排序操作,并置这个数的层数为1(层数从下往上数)
- 遍历顺序链表,检查是否存在相等的层数出现的次数之和(查询期间没有遇到高层的数)等于阶数,存在意味着溢出
- 溢出处理,将位于m/2(向上取整)位置的这个数的层数加一,加一后仍然溢出再重复此操作。
代码
创建
#include <stdio.h>
#include <stdlib.h>
#define N 3//阶数
typedef struct List{
int data;
int n;//从下往上层数
struct List *next;
struct List *child[N];
}List;//链表
typedef struct LList{
List *front;
List *root[N];//头指针
int d;//最高层数
int len;//总关键字
}BTList;//存放链表头指针和B树头指针
//初始化
int init_BTList(BTList *l){
l->front=(List *)malloc(sizeof(List));
if(!l->front) return 0;
l->d=0;
l->len=0;
return 1;
}
//判断是否溢出
int find_Spilt(BTList *l,int d,int n){
List *p,*q;
int t=0,flag;
q=p=l->front;
//向上取整
if(N%2>0) flag=N/2+1;
else flag=N/2;
//溢出检查
while (p->next){
if(p->next->n==d){
t=t+1;
if(t==flag) q=p->next;
}
if(p->next->n>d) t=0;
//溢出处理
if(t==N){
q->n=q->n+1;
if(q->n > l->d) l->d=q->n;
if(n) find_Spilt(l,q->n,n--);//处理后仍然溢出
return 1;
}
p=p->next;
}
return 1;
}
//插入关键字
int insert_BTList(BTList *l,int a){
if(l->len){
List *p;
p=l->front;
//排序
while (p->next)
{
if(p->next->data==a) return 1;
else if(p->next->data<a){
if(p->next->next) p=p->next;
else{
List *q;
q=(List *)malloc(sizeof(List));
q->data=a;
q->n=1;
p->next->next=q;
q->next=NULL;
l->len++;
//溢出判断与处理
find_Spilt(l,1,l->d);
return 1;
}
}else{
List *q;
q=(List *)malloc(sizeof(List));
q->data=a;
q->n=1;
q->next=p->next;
p->next=q;
l->len++;
//溢出判断与处理
find_Spilt(l,1,l->d);
return 1;
}
}
}else{
l->front->next=(List *)malloc(sizeof(List));
l->front->next->data=a;
l->front->next->n=1;
l->front->next->next=NULL;
l->len++;
return 1;
}
}
//树的根节点
int root_BTList(BTList *l){
List *p;int i=0;
p=l->front;
//根节点就是最高层数的数
while (p->next)
{
if(p->next->n==l->d){
l->root[i]=p->next;
i++;
l->len=i;
}
//输出树中的详情
printf("值: %d 层数: %d ",p->next->data,p->next->n);
printf("子值:");
for(int i=0;i<N;i++){
if(p->next->child[i]) printf(" %d ",p->next->child[i]->data);
}
printf("\n");
p=p->next;
}
}
//分配树的孩子节点
/*
n是孩子节点层数,m是父节点层数
遍历链表,记录阶数等于n的节点,然后第一次等于m的节点的孩子节点指向他们
*/
int child_BTList(BTList *l,int n,int m){
if(n==N){
return 1;
}else{
List *p,*q[N],*t;
int flag=0,e=0,k=0;
p=l->front;
while (p->next)
{
if(p->next->n==n){
q[flag]=p->next;
flag++;
}
if(p->next->n>=m && e==1){
for (int i = 0; i < flag; i++)
{
t->child[i]=q[i];
}
flag=0;
e=0;
k=1;
}
if(p->next->n==m && e==0){
t=p->next;
e=1;
}
p=p->next;
}
for (int i = 0; i < flag; i++)
{
t->child[i]=q[i];
}
child_BTList(l,n+1,m+1);
}
}
//查找
int find_BTone(List *l[],int n){
int k=0;
if(l){
for (int i = 0; i < N; i++)
{
if(l[i]){
if(l[i]->data==n){//找到
printf("该值为:%d 所在层数为:%d",l[i]->data,l[i]->n);
return 1;
}
else{//未找到 去孩子那查找
if(l[i]->data<n) k=i;//对应孩子位置
else break;
}
}else{
break;
}
}
if(l[k]){//
if(l[k]->child) find_BTone(l[k]->child,n);
}
else{
printf("没找到");
return 0;
}
}else{
printf("没找到");
return 0;
}
}
测试
int seach_BT(int a[],int n){
BTList L;
init_BTList(&L);
for(int i=0;i<n;i++){
insert_BTList(&L,a[i]);
}
child_BTList(&L,1,2);
root_BTList(&L);
printf("层数为:%d\n",L.d);
//查找值为10的数
find_BTone(L.root,10);
}
测试数据:5,8,7,1,3,2,6,10,4,9,20
结果