„Wenn ein Arbeiter seine Arbeit gut machen will, muss er zuerst seine Werkzeuge schärfen.“ – Konfuzius, „Die Gespräche des Konfuzius. Lu Linggong“
Titelseite > Programmierung > Skiplist-Implementierung

Skiplist-Implementierung

Veröffentlicht am 25.11.2024
Durchsuche:679

skiplist implementation

Ich teile hier meine Skiplist-Implementierung. Es ist eine gute Idee, sich in der C-Sprache weiterzubilden.

#include 
#include 
#include 

#define LOGLEVEL 3

// a skip list is made of a single linked where each element has an
// array of pointers to the next element of the same level.
// I will name `level_pointer` the array of pointers,
// for each element "e" in the list e.level_pointer[n] points to
// the next element "e1" at the same level.
// Every pointer with m smaller than n, the e.level_pointer[m] points
// to an element "e2" such that e =m such that
// e level_pointer = (struct skiplist**) calloc(1, sizeof(struct skiplist*));
    slc->maxlevel = 1;
    slc->level_pointer[0] = NULL;
    slc->cmp = cmp;
    return slc;
}

void logit(const char *restrict format, ...) {
    va_list ap;
    va_start( ap, format );
    vprintf(format, ap);
}

void sklist_insert(struct sklist* slc, void *element) {
    // create the new node
    struct skiplist * sknode = (struct skiplist*) malloc(sizeof(struct skiplist*));
    sknode->element = element;
    sknode->maxlevel = 1;
    // toss a coin to determine the element maxlevel
    while ((rand() % 2) == 1)  {
        sknode->maxlevel  ;
    }
    #if LOGLEVEL == 3
    logit("INSERTING %d at LEVE %d\n",*(int*)element, sknode->maxlevel);
    #endif
    sknode->level_pointer = (struct skiplist**) calloc(sknode->maxlevel, sizeof(struct skiplist*));
    int from_level = sknode->maxlevel-1;
    if (sknode->maxlevel > slc->maxlevel ) {
        // if the new element has the tallest level_pointer
        // it means all the pointers with higher level points to the new element
        slc->level_pointer = (struct skiplist**) realloc(slc->level_pointer, sknode->maxlevel * sizeof(struct skiplist*));
        int i;
        for (i = slc->maxlevel; imaxlevel; i  ) {
            slc->level_pointer[i] = sknode;
            sknode->level_pointer[i] = NULL;
        }
        from_level = slc->maxlevel - 1;
        slc->maxlevel = sknode->maxlevel;
    }
    // starting from_level the insertion must be checked
    struct skiplist ** left_p = slc->level_pointer;
    for(;from_level>=0;from_level--) {
        // peak the next element pointed, still staying a position before
        // keeping in mind that head is smaller than anything,
        // then left_p belong to something smaller than sknode
        while( (left_p[from_level] != NULL) && slc->cmp(left_p[from_level]->element, sknode->element)level_pointer;
        }
        sknode->level_pointer[from_level] = left_p[from_level];
        left_p[from_level] = sknode;
    #if LOGLEVEL == 3
        logit("Inserted %d\n", *(int*) sknode->element);
    #endif
        //printf("left %d\n", *(int*) left_p[from_level]->level_pointer[from_level]->element);
    }
}

struct skiplist * sklist_exists(struct sklist* slc, void *element) {
    // search for element and return it if it exists, return NULL otherwise
    int maxlevel = slc->maxlevel-1;
    struct skiplist ** lpoint = slc->level_pointer;
    for (;maxlevel>=0; maxlevel--) {
        struct skiplist ** prev;
        while (lpoint[maxlevel]!=NULL && slc->cmp(lpoint[maxlevel]->element, element) element, maxlevel);
            prev = lpoint;
            lpoint = lpoint[maxlevel]->level_pointer;
        }
        if (lpoint[maxlevel]!=NULL && slc->cmp(lpoint[maxlevel]->element, element) == 0) {
            return lpoint[maxlevel];
        } else {
            lpoint = prev;
        }
    }
    return NULL;
}

struct skiplist * sklist_extract(struct sklist* slc, void *element) {
    // search for element and return it if it exists, return NULL otherwise
    int maxlevel = slc->maxlevel-1;
    struct skiplist ** lpoint = slc->level_pointer;
    struct skiplist * el_pile = NULL;
    while (maxlevel>=0) {
        struct skiplist ** prev = NULL;
        while (lpoint[maxlevel]!=NULL && slc->cmp(lpoint[maxlevel]->element, element) element, maxlevel);
            #endif
            prev = lpoint;
            lpoint = lpoint[maxlevel]->level_pointer;
        }
        if (lpoint[maxlevel]!=NULL && slc->cmp(lpoint[maxlevel]->element, element) == 0) {
            #if LOGLEVEL == 3
            logit("FOUND HHHHH l:%d\n",lpoint[maxlevel]->maxlevel);
            #endif
            // remove everything from this level here to below:
            if (el_pile == NULL && lpoint[maxlevel]->maxlevel == slc->maxlevel)  {
                el_pile = lpoint[maxlevel];
                // it must resize the maxlevel of the main structure
                // for this just inspect the main level_pointer and this element level_pointer
                // until the second one is NULL and the first one is exactly this element
                // reduce the maxlevel of the mail structure
                int i = el_pile->maxlevel-1;
                while(i>0 && (slc->level_pointer[i] == el_pile && el_pile->level_pointer[i] == NULL)) i--;
                slc->maxlevel = i 1; // the level is the size
                maxlevel = slc->maxlevel;
                #if LOGLEVEL == 3
                logit("shrink level %d\n", maxlevel);
                #endif
            }
            // eat one pos
            lpoint[maxlevel] = lpoint[maxlevel]->level_pointer[maxlevel];
        } else {
            lpoint = prev;
        }
        maxlevel--;
    }
    return el_pile;
    //return NULL;
}

int compare_ints(void *X, void *Y) {
    int *x = (int*) X;
    int *y = (int*) Y;
    if(*xmaxlevel);
    int l = slc->maxlevel;
    for(int i=0;ilevel_pointer[i];
        printf("\nLEVEL: %d\n",i);
        while (head != NULL) {
            printf("%d\t-\t", *(int*) (head->element));
            head = head->level_pointer[i];
        }
    }
    printf("\n");
}

void pile_print_it(struct sklist* slc) {
    printf("PILE staff: maxlevel: %d\n", slc->maxlevel);
    int l = slc->maxlevel;
    for(int i=0;ilevel_pointer[i];
        struct skiplist * head0 = slc->level_pointer[0];
        while (head != NULL) {
            while (head0!= head) {
                printf("--\t-\t");
                head0 = head0->level_pointer[0];
            }
            printf("%d\t-\t", *(int*) (head->element));
            head = head->level_pointer[i];
            head0 = head0->level_pointer[0];
        }
    }
    printf("\n");
}

int main() {
    int *i;
    *i = 190;
    int j = 12;
    printf("COMPARE %d vs %d : %d\n", j, *i, compare_ints((void*) &j, (void *) i));
    // *j = 12;
    struct sklist *skipl = create_skip(compare_ints);
    print_it(skipl);
    sklist_insert(skipl, (void*)i);
    print_it(skipl);
    sklist_insert(skipl, (void*)&j);
    print_it(skipl);
    int k = 23;
    sklist_insert(skipl, (void*)&k);
    print_it(skipl);
    int kk = 123;
    sklist_insert(skipl, (void*)&kk);
    pile_print_it(skipl);
    int kk2 = 23;
    struct skiplist *el = sklist_exists(skipl, (void*) &kk2);
    if(el!=NULL) {
        printf("FOUND!!!!!\n");
    } else {
        printf("NOOOOT FOUND!!\n");
    }
    for(;;) {
        printf("command (I_nsert/L_ookup): \n");
        char command = (char) getchar();
        //if (command == '\n') command = (char) getchar();
        switch (command) {
            case 'i':
            case 'I':
            {
                printf("insert a num: ");
                int *xx = malloc(sizeof(int));
                scanf("%d", xx);
                sklist_insert(skipl, (void*)xx);
                pile_print_it(skipl);
            }
            break;
            case 'l':
            case 'L':
            {
                printf("lookup a num: ");
                int *xx = malloc(sizeof(int));
                scanf("%d", xx);
                struct skiplist *el = sklist_exists(skipl, (void*) xx);
                if(el!=NULL) {
                    printf("%d FOUND!!!!!\n", *xx);
                } else {
                    printf("%d NOOOOT FOUND!!\n", *xx);
                }
            }
            break;
            case 'e':
            case 'E':
            {
                printf("extract a num: ");
                int *xx = malloc(sizeof(int));
                scanf("%d", xx);
                struct skiplist *el = sklist_extract(skipl, (void*) xx);
                if(el!=NULL) {
                    printf("%d FOUND!!!!!\n", *xx);
                } else {
                    printf("%d NOOOOT FOUND!!\n", *xx);
                }
                //free(el);
            }
            case 'p':
            case 'P':
                pile_print_it(skipl);
                break;
            case 'x':
                return 0;
        }
    }
}

Da sind einige Fehler drin, die behoben werden müssen

Freigabeerklärung Dieser Artikel ist abgedruckt unter: https://dev.to/danielecr/skiplist-implementation-3h2j Bei Verstößen wenden Sie sich bitte an [email protected], um ihn zu löschen
Neuestes Tutorial Mehr>

Haftungsausschluss: Alle bereitgestellten Ressourcen stammen teilweise aus dem Internet. Wenn eine Verletzung Ihres Urheberrechts oder anderer Rechte und Interessen vorliegt, erläutern Sie bitte die detaillierten Gründe und legen Sie einen Nachweis des Urheberrechts oder Ihrer Rechte und Interessen vor und senden Sie ihn dann an die E-Mail-Adresse: [email protected] Wir werden die Angelegenheit so schnell wie möglich für Sie erledigen.

Copyright© 2022 湘ICP备2022001581号-3