я новичок здесь и прежде всего, я хочу извиниться, если я делаю ошибки в вопросе. Моя проблема: я хочу реализовать B-дерево в C, используя файл для хранения дерева... моя программа читает 10000 строк по 10 символов в каждой из текстового файла и сохраняет это содержимое в двоичном файле .DAT, организовано через B-дерево; то пользователь может искать строку.
Я использую алгоритмы "Cormen, et al. - Introduction to Algorithms (3ed)", которые кажутся правильными, понятными и функциональными. НО, моя программа просто получает ошибки времени выполнения... такие как Segmentation Fault и Infinite Loop. Я пытался отладить в течение 5 дней, но безуспешно! Функции B-дерева рекурсивны, что я лично ненавижу... я думаю, что именно рекурсия делает отладку такой сложной!
Мой код относительно большой, и он разделен на 2 файла, один источник, один заголовок. Я просто опубликую здесь функции B-дерева и объявления переменных. Но, если кто-то хочет увидеть полный код, я опубликую ссылку «iFile.it» (разрешено ли это? Извините, если нет!)...
Большое спасибо за внимание и помощь... извините за большой вопрос!
Ссылка на источник [не так важно, просто main()]: http://ifile.it/n73drmc/b-tree_file.c
Ссылка на заголовок [все функции здесь]: http://ifile.it/u1fa3kp/b-tree_file.h
Текстовый файл со строками: http://ifile.it/7hu95ot/arq_5.txt
ПРИМЕЧАНИЯ о коде:
i) Free() ведут себя очень странно... поэтому я прокомментировал их, потому что, если я их использую, моя программа будет глючить еще больше!
ii) Все комментарии к коду являются моими идеями, чтобы попытаться решить проблемы, и следует учитывать, что я пробовал их.
iii) Я носитель португальского языка, поэтому функции и переменные могут иметь странные имена для носителей английского языка... извините за это!
КОД:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
//defs of pre-compiler
#ifdef __linux
#define PAUSA "read p"
#define CLRSCR "clear"
#else
#define PAUSA "Pause"
#define CLRSCR "cls"
#endif
#define T 5 // minimum degree of B-tree
#define Min (T-1)
#define Max ((2*T)-1)
//
//global vars
FILE *arqt, *arqb;
char VAL[11];
long int lt = 0;
typedef struct {
unsigned int num;
long int pos;
char chave[(Max+1)][11]; //chave in portuguese = key in english!
short int folha; //folha in portuguese = leaf in english!
long int c[(Max+2)];
} Nod;
Nod *raiz = NULL; //raiz in portuguese = root in english!
//
void b_split(Nod *x, unsigned int i, Nod *y) { //B-TREE-SPLIT-CHILD //that function split a B-tree node
Nod *z = NULL;
unsigned int j=1;
z = (Nod*)realloc(z,sizeof(Nod));
fseek(arqb,0,SEEK_END);
z->pos = ftell(arqb);
z->folha = y->folha;
z->num = Min;
for(j=1;j<=Min;j++) {strcpy(z->chave[j],y->chave[j+T]);}
if (y->folha == 0) {
for(j=1;j<=T;j++) {z->c[j] = y->c[j+T];}
}
y->num = Min;
for(j=(x->num + 1);j<=(i+1);j--) {x->c[(j+1)] = x->c[j];}
x->c[(i+1)] = z->pos;
for(j=x->num;j<=i;j--) { strcpy(x->chave[j+1],x->chave[j]); }
strcpy(x->chave[i],y->chave[T]);
x->num = x->num + 1;
fseek(arqb,x->pos,SEEK_SET);
fwrite(x,sizeof(Nod),1,arqb);
fseek(arqb,y->pos,SEEK_SET);
fwrite(y,sizeof(Nod),1,arqb);
fseek(arqb,z->pos,SEEK_SET);
fwrite(z,sizeof(Nod),1,arqb);
//free(z);
//free(y);
}
void b_ins(Nod *x, char *val) { //B-TREE-INSERT-NONFULL //insert a key in nonfull node
unsigned int i=0;
Nod *C = NULL;
i = x->num;
if (x->folha == 1) {
while ( (i >= 1) && (strcmp(val,x->chave[i]) < 0) ) {
strcpy(x->chave[(i+1)],x->chave[i]);
i--;
}
strcpy(x->chave[(i+1)],val);
x->num = x->num + 1;
fseek(arqb,x->pos,SEEK_SET);
fwrite(x,sizeof(Nod),1,arqb);
}
else {
while ( (i >= 1) && (strcmp(val,x->chave[i]) < 0) ) {i--;}
i++;
C = (Nod*)realloc(C,sizeof(Nod));
fseek(arqb,x->c[i],SEEK_SET);
fread(C,sizeof(Nod),1,arqb);
if (C->num == Max) {
b_split(x,i,C);
if ( strcmp(val,x->chave[i]) > 0 ) {i++;}
}
fseek(arqb,x->c[i],SEEK_SET);
fread(C,sizeof(Nod),1,arqb);
b_ins(C,val);
//free(C);
}
}
void insere_b(char *val) { //B-TREE-INSERT //i believe the problem is here!
Nod *S = NULL,*R = NULL;
R = (Nod*)realloc(R,sizeof(Nod));
R = raiz;
if (R->num == Max) {
S = (Nod*)realloc(S,sizeof(Nod));
/* fseek(arqb,0,SEEK_END);
S->pos = ftell(arqb);
*/
raiz = S;
S->folha = 0;
S->num = 0;
S->c[1] = R->pos;
/* fseek(arqb,S->pos,SEEK_SET);
fwrite(S,sizeof(Nod),1,arqb);
*/
b_split(S,1,R);
b_ins(S,val);
//free(S);
}
else {b_ins(R,val);}
//free(R);
}
void busca_b(Nod *x, char *val) { //B-TREE-SEARCH //self explanatory
unsigned int i=1;
Nod *C = NULL;
while( (i <= x->num) && ( strcmp(val, x->chave[i]) > 0 ) ) {i++;}
if ( (i <= x->num) && ( strcmp(val, x->chave[i]) == 0 ) ) {printf ("\nValor encontrado!\n");}
else {
if (x->folha == 1) {printf ("\nValor NAO encontrado!\n");}
else {
C = (Nod*)realloc(C,sizeof(Nod));
fseek(arqb,x->c[i],SEEK_SET);
fread(C,sizeof(Nod),1,arqb);
lt++;
busca_b(C,val);
//free(C);
}
}
}
void cria_b() { // cria arvore B //create the B-tree
long int i = 0;
char V[11];
raiz->folha = 1;
raiz->num = 0;
raiz->pos = 0;
for (i=1;i<=(Max+1);i++) {raiz->c[i] = -1;}
fseek(arqb,raiz->pos,SEEK_SET);
fwrite(raiz,sizeof(Nod),1,arqb);
rewind(arqt);
for (i=0;i<fSize(arqt);i++) {
fscanf(arqt,"%s\n",V);
insere_b(V);
}
}