У меня есть структура записей о пациентах в больнице с именем record, которая работает просто отлично. Я попытался создать дерево R / B, которое вместо int хранит указатель на эту структуру и для проверки того, какое значение меньше, я проверяю даты входа. Код, кажется, в порядке, так как я проверил онлайн, и метод, который я использую, похож на подтвержденные методы для вставки. Программа получает пациентов из текстового файла. Чем больше файл, тем больше у меня проблем. Например, в файле с 100 записями, когда я печатаю свое дерево в порядке уровней, я получаю 74 записи и некоторые пробелы между ними, но в файле 10000 записей программа даже не достигает печати.
Мои структуры здесь (работает просто отлично, потому что я сначала создал список из них, читающий из тех же файлов, и вся информация была прочитана и правильно сохранена):
typedef struct date{
int day;
int month;
int year;
}date;
typedef struct record{
char* recordID;
char* firstName;
char* surName;
char* disease;
char* country;
date* entry;
date* exit;
}record;
Это функция, которую я сделал для сравнения дат:
int compare_dates(date* date1, date* date2 ){
if(date1->year < date2->year){
return -1;
}
else if(date1->year > date2->year){
return 1;
}
else{
if(date1->month < date2->month){
return -1;
}
else if(date1->month > date2->month){
return 1;
}
else if(date1->day < date2->day){
return -1;
}
else if(date1->day > date2->day){
return -1;
}
else{
return 0;
}
}
}
Это мои структуры для дерева:
typedef struct RBNodeType {
int color; //0 for black, 1 for red
record* Record;
struct RBNodeType* parent;
struct RBNodeType* llink;
struct RBNodeType* rlink;
} RBNode;
typedef struct RBTree{
RBNode* root;
}RBTree;
А это функции для создания дерева и необходимые методы для вставки:
RBTree* createTree(){
RBTree* temp = malloc(sizeof(RBTree));
temp->root = NULL;
return temp;
}
//Initialize, desmeuei xwro gia enan kombo
RBNode* initialize(record* aRecord){
//desmeuw xwro mnimis gia ton kombo
RBNode* theNode = (RBNode*)malloc(sizeof(RBNode));
theNode->color = 1; //arxika to xrwma ginetai kokkino
theNode->Record = aRecord; //to content einai -1 (aprosdioristo)
theNode->parent = NULL;
theNode->llink = NULL; //o kombos den exei aristero paidi
theNode->rlink = NULL; //o kombos den exei deksi paidi
//epistrefw ton dimiourgithenta kombo
return theNode;
};
int height(RBNode* aNode){
//san in order diasxisi: ypologizw anadromika to height tou aristerou ypodentrou, to height to deksiou ypodentrou, kratw to megalytero kai to auksanw kata 1 gia ton trexonta kombo-riza
if (aNode != NULL){
int leftHeight = height(aNode->llink);
int rightHeight = height(aNode->rlink);
if (leftHeight > rightHeight){
return leftHeight+1;
}
else{
return rightHeight+1;
}
}
return 0;
}
//i visit apla typwnei to pedio content tou kombou kai to xrwma tou se parenthesi
void visit(RBNode* aNode){
if (aNode != NULL){
if (aNode->color == 0){ //black
printf("---Black--- \n");
printRecord(aNode->Record);
}
else{ //red
printf("---Red--- \n");
printRecord(aNode->Record);
}
}
else{
printf("NULL ");
}
}
void printLevel(RBNode* aNode, int level){
if (aNode == NULL){
return;
}
if (level == 1){
visit(aNode);
}
else{ //if (level>1)
printLevel(aNode->llink, level-1);
printLevel(aNode->rlink, level-1);
printf("\n");
}
}
//level order
void levelOrder(RBNode* root){
int h = height(root);
int i;
for(i=1; i<=h; i++){
printLevel(root, i);
}
}
//sarwnw to dentro kai typwnw kathe kombo tou me levelorder
void printTree(RBNode* root){
levelOrder(root);
}
void insertNode(RBTree* tree, record* aRecord){
RBNode* current= tree->root;
RBNode* parent = NULL;
while(current != NULL){
//an to key pros eisagwgi brisketai idi ston kombo current, tote den kanw eisagwgi kai teleiwnw
if(!strcmp(aRecord->recordID, current->Record->recordID)){
return;
}
//an to key pros eisagwgi einai mikrotero apo ton kombo current, tote paw sto aristero ypodentro
else if(compare_dates(aRecord->entry, current->Record->entry) <= 0){
//krataw sto parent ton kombo gonio
parent = current;
current = current->llink;
}
//an to key pros eisagwgi einai megalytero apo ton kombo current, tote paw sto deksi ypodentro
else{ //if (key>current->content)
//krataw sto parent ton kombo gonio
parent = current;
current = current->rlink;
}
}
//twra eftasa se current==null, diladi se fyllo
//ftiaxnw neo kombo gia to key
RBNode* newNode = initialize(aRecord);
//an to parent einai null, tote den yparxei kombos gonios, diladi molis egine eisagwgi toy prwtou komboy riza.
if(parent == NULL){
//kanw tin riza mauri (i riza panta prepei na einai mauri)
newNode->color = 0; //0:black, 1:red
tree->root = newNode;
}
//alliws bazw ton kombo ws paidi tou parent
else{
newNode->parent = parent;
//an to key einai mikrotero tou parent, to bazw ws aristero paidi
if (compare_dates(aRecord->entry, parent->Record->entry) <= 0){
parent->llink = newNode;
}
//alliws to bazw ws deksi paidi
else{
parent->rlink = newNode;
}
//twra elegxw gia problimata me to xrwma:
checkColorProperties(newNode, tree->root);
return;
}
}
//elegxei tis idiotites xrwmatos gia ton neo kombo kai pio panw. O 2os kombos einai i riza tou dentrou pou endexetai na allaksei (meta apo restructuring, gi ayto tin pernaw ws parametro)
void checkColorProperties(RBNode* z, RBNode* root){
//Elegxw an o z exei problima double red (me ton gonio tou)
if(doubleRed(z) == 1){
//koitazw ton aderfo w tou goniou v (an yparxei). Pappous einai o u
RBNode* v = z->parent;
RBNode* u = v->parent;
//an o pappous u yparxei
if(u != NULL){
//o w einai o aderfos tou goniou v
RBNode* w = NULL;
//an to v einai aristero paidi tou pappou u, tote w einai to deksi paidi tou pappou u
if(v == u->llink){
w = u->rlink;
}
//alliws (an to v einai deksi paidi tou pappou u, tote w einai to aristero paidi tou pappou u)
else{
w = u->llink;
}
//an o aderfos w den yparxei (null) tote thewreitai oti exei mauro xrwma, ara prepei na kanw restructuring stous z, v kai u. Pernaw kai tin riza root ws parametro, giati to dentro endexetai na allaksei riza meta to restructuring
if(w == NULL){
restructuring(z, v, u, root);
}
//an o aderfos w yparxei kai exei mauro xrwma, tote prepei na kanw restructuring stous z, v kai u. Pernaw kai tin riza root ws parametro, giati to dentro endexetai na allaksei riza meta to restructuring
else if(w->color == 0){
restructuring(z, v, u, root);
}
//an o aderfos w yparxei kai exei kokkino xrwma, tote prepei na kanw recoloring ston gonio v kai ston aderfo w kai ston pappou u
//kai meta prepei na kanw CheckColorProperties anadromika ston parent tou parent
else{ //if (w->color==1)
recoloring(v, w, u);
checkColorProperties(u, root);
}
}
}
//an den yparxei doublered problima, tote den kanw tipote kai teleiwnw
}
//epistrefei 1 an yparxei problima double red me ton kombo aNode (kai ton gonio tou), alliws epistrefei 0.
int doubleRed(RBNode* aNode){
if (aNode != NULL && aNode->parent != NULL){
if (aNode->color == 1 && aNode->parent->color == 1){
return 1;
}
}
return 0;
}
//kanei recoloring stous kombous paidia v kai w kai ston kombo gonio u. Oi v kai w ginontai mauroi kai o gonios u kokkinos. An o u einai riza, tote ginetai mauros
void recoloring(RBNode* v, RBNode* w, RBNode* u){
if(v != NULL && w != NULL && u != NULL){
v->color = 0;//black
w->color = 0;//black
//o gonios ginetai kokkinos
u->color = 1;//red
//an o gonios einai i riza, tote prepei na ginei ypoxrewtika mauri. Riza tha einai an to parent tis einai null
if (u->parent == NULL){
u->color = 0;//black
}
}
}
void restructuring(RBNode* z, RBNode* v, RBNode* u, RBNode* root){
if(z != NULL && v != NULL && u != NULL && root != NULL){
//briskw poios einai o a (mikroteros), o b (mesaios) kai o c (megalyteros)
RBNode* a = NULL;
RBNode* b = NULL;
RBNode* c = NULL;
RBNode* lz = NULL;//aristero paidi tou z
RBNode* rz = NULL;//deksi paidi tou z
RBNode* lv = NULL;//aristero paidi tou v
RBNode* rv = NULL;//deksi paidi tou v
//RBNode* lu=NULL; //aristero paidi tou u
//RBNode* ru=NULL; //deksi paidi tou u
RBNode* pu = NULL;//gonios tou u
lz = z->llink; rz = z->rlink;
lv = v->llink; rv = v->rlink;
//lu=u->llink; ru=u->rlink;
pu = u->parent;
//oi periptwseis den einai 6, einai 4.
//ta v kai z eite tha einai kai ta 2 mikrotera tou u eite tha einai kai ta 2 megalytera tou u
//1i periptwsi, slide 16 tou pdf Red black trees
if(compare_dates(z->Record->entry, v->Record->entry) <= 0 && compare_dates(v->Record->entry, u->Record->entry) <= 0){
a = z; b = v; c = u;
c->llink = rv;
//an to rv den einai null, tote gonios tou rv prepei na ginei to c
if(rv != NULL){
rv->parent = c;
}
b->rlink = u;
c->parent = v;
b->parent = pu;
//an to pu den einai null, tote paidi tou pu prepei na ginei to b (kai prepei na elegksoume an tha itan deksi paidi i aristero paidi)
if(pu != NULL){
//an to u einai aristero paidi tou pu, tote aristero paidi tou pu ginetai to b
if(u == pu->llink){
pu->llink = b;
}
//alliws, an to u einai deksi paidi tou pu, tote deksi paidi tou pu ginetai to b
else{
pu->rlink = b;
}
}
//ftiaxnw ta xrwmata twn kombwn
b->color = 0;//black
a->color = 1;//red
c->color = 1;//red
//an to u itan i riza, twra to b einai i riza
if (u == root){
root = b;
}
}
//auti i periptwsi den symbainei:
//else if (z->content < u->content && u->content < v->content)
//{ a=z; b=u; c=v; }
//2i periptwsi, slide 17 tou pdf Red black trees
else if(compare_dates(v->Record->entry, z->Record->entry) <= 0 && compare_dates(z->Record->entry, u->Record->entry) <= 0){
a = v; b = z; c = u;
c->llink = rz;
//an to rz den einai null, tote gonios tou rz prepei na ginei to c
if(rz!=NULL){
rz->parent = c;
}
a->rlink = lz;
//an to lz den einai null, tote gonios tou lz prepei na ginei to a
if(lz!=NULL){
lz->parent = a;
}
b->llink = v;
b->rlink = u;
a->parent = z;
c->parent = z;
b->parent = pu;
//an to pu den einai null, tote paidi tou pu prepei na ginei to b (kai prepei na elegksoume an tha itan deksi paidi i aristero paidi)
if(pu != NULL){
//an to u einai aristero paidi tou pu, tote aristero paidi tou pu ginetai to b
if(u == pu->llink){
pu->llink = b;
}
//alliws, an to u einai deksi paidi tou pu, tote deksi paidi tou pu ginetai to b
else{
pu->rlink = b;
}
}
//ftiaxnw ta xrwmata twn kombwn
b->color = 0;//black
a->color = 1;//red
c->color = 1;//red
//an to u itan i riza, twra to b einai i riza
if(u == root){
root = b;
}
}
//auti i periptwsi den symbainei:
//else if (v->content < u->content && u->content < z->content)
//{ a=v; b=u; c=z; }
//3i periptwsi, slide 18 tou pdf Red black trees
else if (compare_dates(u->Record->entry, v->Record->entry) <= 0 && compare_dates(v->Record->entry, z->Record->entry) <= 0){
a = u; b = v; c = z;
a->rlink = lv;
//an to lv den einai null, tote gonios tou lv prepei na ginei to a
if(lv != NULL)
lv->parent = a;
b->llink = u;
a->parent = v;
b->parent = pu;
//an to pu den einai null, tote paidi tou pu prepei na ginei to b (kai prepei na elegksoume an tha itan deksi paidi i aristero paidi)
if(pu != NULL){
//an to u einai aristero paidi tou pu, tote aristero paidi tou pu ginetai to b
if (u == pu->llink){
pu->llink = b;
}
//alliws, an to u einai deksi paidi tou pu, tote deksi paidi tou pu ginetai to b
else{
pu->rlink = b;
}
}
//ftiaxnw ta xrwmata twn kombwn
b->color = 0;//black
a->color = 1;//red
c->color = 1;//red
//an to u itan i riza, twra to b einai i riza
if(u == root){
root = b;
}
}
//4i periptwsi, slide 19 tou pdf Red black trees
else{ //if (u->content < z->content && z->content < v->content)
a = u; b = z; c = v;
c->llink = rz;
//an to rz den einai null, tote gonios tou rz prepei na ginei to c
if(rz != NULL){
rz->parent = c;
}
a->rlink = lz;
//an to lz den einai null, tote gonios tou lz prepei na ginei to a
if(lz != NULL){
lz->parent = a;
}
b->llink = u;
b->rlink = v;
a->parent = z;
c->parent = z;
b->parent = pu;
//an to pu den einai null, tote paidi tou pu prepei na ginei to b (kai prepei na elegksoume an tha itan deksi paidi i aristero paidi)
if(pu != NULL){
//an to u einai aristero paidi tou pu, tote aristero paidi tou pu ginetai to b
if(u == pu->llink){
pu->llink = b;
}
//alliws, an to u einai deksi paidi tou pu, tote deksi paidi tou pu ginetai to b
else{
pu->rlink = b;
}
}
//ftiaxnw ta xrwmata twn kombwn
b->color = 0;//black
a->color = 1;//red
c->color = 1;//red
//an to u itan i riza, twra to b einai i riza
if(u == root){
root = b;
}
}
}
}
//sbinw to dentro: prwto to aristero ypodentro, meta to deksi ypodentro, meta tin riza (apeleutherwnw tis theseis mnimis)
void deleteRBNode(RBNode* root){
if(root != NULL){
deleteRecord(root->Record);
deleteRBNode(root->llink);
deleteRBNode(root->rlink);
free(root);
}
}
Наконец, в основном я делаю это:
int main(int argc, char** argv){
if ( argc != 9 ){
printf("Invalid number of args, exiting\n");
return -1;
}
char* filename = NULL;
int bucketSize, diseaseHashTableSize, countryHashTableSize;
for (int i = 1; i <= 7 ; i += 2 ){
if (!strcmp(argv[i], "-p" )){
filename = strdup(argv[i + 1]);
}
else if(!strcmp(argv[i], "-h1")){
diseaseHashTableSize = atoi(argv[i + 1]);
}
else if(!strcmp(argv[i], "-h2")){
countryHashTableSize = atoi(argv[i + 1]);
}
else if(!strcmp(argv[i], "-b")){
bucketSize = atoi(argv[i + 1]);
}
else{
if(filename != NULL){
free(filename);
}
printf("Error in arguments flags, exiting\n");
return -1;
}
}
printf("Filename %s, bucket size %d, diseaseSize %d and countrySize %d\n", filename, bucketSize, diseaseHashTableSize, countryHashTableSize );
char* read = NULL;
size_t len = 0;
FILE *f1;
RBTree* tree1 = createTree();
f1 = fopen(filename, "r");
printf("f1 is NULL = %d\n", f1 == NULL);
int counter = 0;
while(getline(&read, &len, f1) != -1){
record* newRecord = createRecord(read);
insertNode(tree1, newRecord);
}
printTree(tree1->root);
deleteRBNode(tree1->root);
free(read);
fclose(f1);
free(filename);
free(tree1);
return 0;
}
Не обращайте внимания на комментарии в "//", они на греческом sh и извините за длинный пост, но я сжимаю свой разум 2 дней и не могу найти настоящую проблему. Если вам нужна дополнительная информация о чем-то более глубоком и не показанном здесь, я отвечу вам здесь.