complexity of mergesort with linked list

前端 未结 3 1107
死守一世寂寞
死守一世寂寞 2021-01-15 17:31

i have code for mergesort using linked list,it works fine,my question what is complexity of this algorithm?is it O(nlog(n))?also is it stable?i am interested because as i

3条回答
  •  孤城傲影
    2021-01-15 18:01

    Mergesort means split&merge. The splitting in the fragment below is not perfect (it leads to quadratic behavior on equally distributed runlengths, see the comment from Christoph)), but it will do the trick:

    #include 
    #include 
    
    struct llist {
            struct llist *next;
            char *payload;
            };
    
    int llist_cmp(struct llist *l, struct llist *r);
    struct llist * llist_split(struct llist **hnd
                            , int (*cmp)(struct llist *l, struct llist *r) );
    struct llist * llist_merge(struct llist *one, struct llist *two
                            , int (*cmp)(struct llist *l, struct llist *r) );
    struct llist * llist_sort(struct llist *ptr
                            , int (*cmp)(struct llist *l, struct llist *r) );
    
    struct llist * llist_split(struct llist **hnd, int (*cmp)(struct llist *l, struct llist *r) )
    {
    struct llist *this, *save, **tail;
    
    for (save=NULL, tail = &save; this = *hnd; ) {
            if (! this->next) break;
            if ( cmp( this, this->next) <= 0) { hnd = &this->next; continue; }
            *tail = this->next;
            this->next = this->next->next;
            tail = &(*tail)->next;
            *tail = NULL;
            }
    return save;
    }
    
    struct llist * llist_merge(struct llist *one, struct llist *two, int (*cmp)(struct llist *l, struct llist *r) )
    {
    struct llist *result, **tail;
    
    for (result=NULL, tail = &result; one && two; tail = &(*tail)->next ) {
            if (cmp(one,two) <=0) { *tail = one; one=one->next; }
            else { *tail = two; two=two->next; }
            }
    *tail = one ? one: two;
    return result;
    }
    struct llist * llist_sort(struct llist *ptr, int (*cmp)(struct llist *l, struct llist *r) )
    {
    struct llist *save;
    
    save=llist_split(&ptr, cmp);
    if (!save) return ptr;
    
    save = llist_sort(save, cmp);
    
    return llist_merge(ptr, save, cmp);
    }
    
    int llist_cmp(struct llist *l, struct llist *r)
    
    {
    if (!l) return 1;
    if (!r) return -1;
    return strcmp(l->payload,r->payload);
    }
    
    
    struct llist lists[] =
    {{ lists+1, "one" }
    ,{ lists+2, "two" }
    ,{ lists+3, "three" }
    ,{ lists+4, "four" }
    ,{ lists+5, "five" }
    ,{ lists+6, "six" }
    ,{ lists+7, "seven" }
    ,{ lists+8, "eight" }
    ,{ lists+9, "nine" }
    ,{ NULL, "ten" }
            };
    
    int main()
    {
    struct llist *root,*tmp;
    
    root = lists;
    
    fprintf(stdout, "## %s\n", "initial:" );
    for (tmp=root; tmp; tmp=tmp->next) {
            fprintf(stdout, "%s\n", tmp->payload);
            }
    
    fprintf(stdout, "## %s\n", "sorting..." );
    root = llist_sort(root, llist_cmp);
    for (tmp=root; tmp; tmp=tmp->next) {
            fprintf(stdout, "%s\n", tmp->payload);
            }
    fprintf(stdout, "## %s\n", "done." );
    
    return 0;
    }
    

提交回复
热议问题