Создано красное / черное дерево структурных записей, но при печати некоторые записи не отображаются - PullRequest
1 голос
/ 24 марта 2020

У меня есть структура записей о пациентах в больнице с именем 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 дней и не могу найти настоящую проблему. Если вам нужна дополнительная информация о чем-то более глубоком и не показанном здесь, я отвечу вам здесь.

...