卓越飞翔博客卓越飞翔博客

卓越飞翔 - 您值得收藏的技术分享站
技术文章78520本站已运行448

跳跃表的实现

跳跃表的实现

我在这里分享我的跳跃列表实现。继续接受 c 语言培训是个好主意。

#include <stdlib.h>
#include <stdio.h>
#include <stdarg.h>

#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-&gt;maxlevel = 1;
    slc-&gt;level_pointer[0] = NULL;
    slc-&gt;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-&gt;element = element;
    sknode-&gt;maxlevel = 1;
    // toss a coin to determine the element maxlevel
    while ((rand() % 2) == 1)  {
        sknode-&gt;maxlevel++;
    }
    #if LOGLEVEL == 3
    logit("INSERTING %d at LEVE %dn",*(int*)element, sknode-&gt;maxlevel);
    #endif
    sknode-&gt;level_pointer = (struct skiplist**) calloc(sknode-&gt;maxlevel, sizeof(struct skiplist*));
    int from_level = sknode-&gt;maxlevel-1;
    if (sknode-&gt;maxlevel &gt; slc-&gt;maxlevel ) {
        // if the new element has the tallest level_pointer
        // it means all the pointers with higher level points to the new element
        slc-&gt;level_pointer = (struct skiplist**) realloc(slc-&gt;level_pointer, sknode-&gt;maxlevel * sizeof(struct skiplist*));
        int i;
        for (i = slc-&gt;maxlevel; imaxlevel; i++) {
            slc-&gt;level_pointer[i] = sknode;
            sknode-&gt;level_pointer[i] = NULL;
        }
        from_level = slc-&gt;maxlevel - 1;
        slc-&gt;maxlevel = sknode-&gt;maxlevel;
    }
    // starting from_level the insertion must be checked
    struct skiplist ** left_p = slc-&gt;level_pointer;
    for(;from_level&gt;=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) &amp;&amp; slc-&gt;cmp(left_p[from_level]-&gt;element, sknode-&gt;element)level_pointer;
        }
        sknode-&gt;level_pointer[from_level] = left_p[from_level];
        left_p[from_level] = sknode;
    #if LOGLEVEL == 3
        logit("Inserted %dn", *(int*) sknode-&gt;element);
    #endif
        //printf("left %dn", *(int*) left_p[from_level]-&gt;level_pointer[from_level]-&gt;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-&gt;maxlevel-1;
    struct skiplist ** lpoint = slc-&gt;level_pointer;
    for (;maxlevel&gt;=0; maxlevel--) {
        struct skiplist ** prev;
        while (lpoint[maxlevel]!=NULL &amp;&amp; slc-&gt;cmp(lpoint[maxlevel]-&gt;element, element) element, maxlevel);
            prev = lpoint;
            lpoint = lpoint[maxlevel]-&gt;level_pointer;
        }
        if (lpoint[maxlevel]!=NULL &amp;&amp; slc-&gt;cmp(lpoint[maxlevel]-&gt;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-&gt;maxlevel-1;
    struct skiplist ** lpoint = slc-&gt;level_pointer;
    struct skiplist * el_pile = NULL;
    while (maxlevel&gt;=0) {
        struct skiplist ** prev = NULL;
        while (lpoint[maxlevel]!=NULL &amp;&amp; slc-&gt;cmp(lpoint[maxlevel]-&gt;element, element) element, maxlevel);
            #endif
            prev = lpoint;
            lpoint = lpoint[maxlevel]-&gt;level_pointer;
        }
        if (lpoint[maxlevel]!=NULL &amp;&amp; slc-&gt;cmp(lpoint[maxlevel]-&gt;element, element) == 0) {
            #if LOGLEVEL == 3
            logit("FOUND HHHHH l:%dn",lpoint[maxlevel]-&gt;maxlevel);
            #endif
            // remove everything from this level here to below:
            if (el_pile == NULL &amp;&amp; lpoint[maxlevel]-&gt;maxlevel == slc-&gt;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-&gt;maxlevel-1;
                while(i&gt;0 &amp;&amp; (slc-&gt;level_pointer[i] == el_pile &amp;&amp; el_pile-&gt;level_pointer[i] == NULL)) i--;
                slc-&gt;maxlevel = i+1; // the level is the size
                maxlevel = slc-&gt;maxlevel;
                #if LOGLEVEL == 3
                logit("shrink level %dn", maxlevel);
                #endif
            }
            // eat one pos
            lpoint[maxlevel] = lpoint[maxlevel]-&gt;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-&gt;maxlevel;
    for(int i=0;i<l struct skiplist head="slc-">level_pointer[i];
        printf("nLEVEL: %dn",i);
        while (head != NULL) {
            printf("%dt-t", *(int*) (head-&gt;element));
            head = head-&gt;level_pointer[i];
        }
    }
    printf("n");
}

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

int main() {
    int *i;
    *i = 190;
    int j = 12;
    printf("COMPARE %d vs %d : %dn", j, *i, compare_ints((void*) &amp;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*)&amp;j);
    print_it(skipl);
    int k = 23;
    sklist_insert(skipl, (void*)&amp;k);
    print_it(skipl);
    int kk = 123;
    sklist_insert(skipl, (void*)&amp;kk);
    pile_print_it(skipl);
    int kk2 = 23;
    struct skiplist *el = sklist_exists(skipl, (void*) &amp;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;
        }
    }
}

</l></l></stdarg.h></stdio.h></stdlib.h>

其中存在一些错误,待修复

卓越飞翔博客
上一篇: Go 语言指针
下一篇: 返回列表
留言与评论(共有 0 条评论)
   
验证码:
隐藏边栏