12sort

来源:互联网 发布:2016社交软件排名 编辑:程序博客网 时间:2024/04/27 22:26

list.h

struct list_head {    struct list_head *prev;    struct list_head *next;};#define LIST_HEAD(head) struct list_head head = {&head, &head}static inline void INIT_LIST_HEAD(struct list_head *node){    node->prev = node;    node->next = node;}static inline void __list_add(struct list_head *node,        struct list_head *prev,        struct list_head *next){    node->prev = prev;    node->next = next;    prev->next = node;    next->prev = node;}static inline void list_add(struct list_head *node,        struct list_head *head){    __list_add(node, head, head->next);}static inline void list_add_tail(struct list_head *node,        struct list_head *head){    __list_add(node, head->prev, head);}


 

static inline int list_emtpy(struct list_head *head){    return head->next == head;}static inline void list_del(struct list_head *node){    node->prev->next = node->next;    node->next->prev = node->prev;}static inline void list_del_init(struct list_head *node){    list_del(node);    INIT_LIST_HEAD(node);}


 

#define offsetof(type, member) \    ((size_t)(&((type*)0)->member))#define container_of(ptr, type, member) \    ({const typeof(((type*)0)->member) *__mptr = ptr; \     (type*)((char*)__mptr - offsetof(type, member));})


 

/* @cur: ?..list_head?..?.复?舵.? * @head: 澶磋.?圭.?板. */#define list_for_each(cur, head) \    for (cur = (head)->next; \        (cur) != (head); \        cur = (cur)->next)/* @cur: ?..list_head?..?.复?舵.? * @tmp: ?..cur涓.?涓..?圭.涓存.?.. * @head: 澶磋.?圭.?板. */#define list_for_each_safe(cur, tmp, head) \    for (cur = (head)->next, tmp = (cur)->next; \        (cur) != (head); \        cur = tmp, tmp = (tmp)->next)/* @ptr: ?..list_head?..?€?ㄧ.澶х??.??..?.复?舵.? * @head: 澶磋.?圭.?板. */#define list_for_each_entry(ptr, head, member) \    for ( ptr = container_of((head)->next, typeof(*(ptr)), member); \        &(ptr)->member != (head); \        ptr = container_of((ptr)->member.next, typeof(*(ptr)), member) )#define list_for_each_entry_safe(ptr, tmp, head, member) \    for ( ptr = container_of((head)->next, typeof(*(ptr)), member); \        (&(ptr)->member != (head)) && (tmp = container_of((ptr)->member.next, typeof(*(ptr)), member)); \        ptr = tmp )


 

#define list_for_each_continue(cur, head) \    for (cur = (cur)->next; \        (cur) != (head); \        cur = (cur)->next)#define list_for_each_continue_safe(cur, tmp, head) \    for (cur = (cur)->next, tmp = (cur)->next; \        (cur) != (head); \        cur = tmp, tmp = (tmp)->next)#define list_for_each_reverse(cur, head) \    for (cur = (head)->prev; \        (cur) != (head); \        cur = (cur)->prev)#define list_for_each_reverse_continue(cur, head) \    for (cur = (cur)->prev; \        (cur) != (head); \        cur = (cur)->prev)


 

struct hlist_node {    struct hlist_node *next;    struct hlist_node **pprev;};struct hlist_head {    struct hlist_node *first;};#define HLIST_HEAD(head) struct hlist_head head = {NULL}static inline void INIT_HLIST_HEAD(struct hlist_head *head){    head->first = NULL;}static inline void INIT_HLIST_NODE(struct hlist_node *node){    node->next = NULL;    node->pprev = NULL;}static inline void hlist_add_head(struct hlist_node *node,        struct hlist_head *head){    node->next = head->first;    node->pprev = &head->first;    head->first = node;    if (node->next) {        node->next->pprev = &node->next;    }}


 

static inline void hlist_add_before(struct hlist_node *node, struct hlist_node *next){    node->next = next;    node->pprev = next->pprev;    *node->pprev = node;    next->pprev = &node->next;}static inline void hlist_add_after(struct hlist_node *prev,        struct hlist_node *node){    node->next = prev->next;    node->pprev = &prev->next;    prev->next = node;    if (node->next) {        node->next->pprev = &node->next;    }}


 

static inline void hlist_del(struct hlist_node *node){    *node->pprev = node->next;    if (node->next) {        node->next->pprev = node->pprev;    }}static inline void hlist_del_init(struct hlist_node *node){    hlist_del(node);    INIT_HLIST_NODE(node);}static inline int hlist_empty(struct hlist_head *head){    return head->first == NULL;}


 

#define hlist_for_each(cur, head) \    for (cur = (head)->first; \        cur; cur = (cur)->next)#define hlist_for_each_safe(cur, tmp, head) \    for (cur = (head)->first; \        cur && ({tmp = (cur)->next; 1;}); \        cur = tmp)#define hlist_for_each_continue(cur, head) \    for (cur = (cur)->next; \        cur; cur = (cur)->next)#define hlist_for_each_from(cur, head) \    for (; cur; cur = (cur)->next)#define hlist_for_each_entry(ptr, cur, head, member) \    for (cur = (head)->first; \        cur && (ptr = container_of(cur, typeof(*(ptr)), member)); \        cur = (cur)->next)#define hlist_for_each_entry_safe(ptr, cur, tmp, head, member) \    for (cur = (head)->first; \        cur && (tmp = (cur)->next, 1) && \        (ptr = container_of(cur, typeof(*(ptr)), member)); \        cur = tmp)


sort.c

#include <stdio.h>#include <stdlib.h>#include <string.h>#define DEBUG#ifdef DEBUG#define DBG_PRT(fmt, arg...) printf(fmt, arg);#else#define DBG_PRT(fmt, arg...)#endifstruct data_info {    int data;};static void print_array(const void *s, size_t nmemb);#define ELEM(n) ((char*)base + size * (n))#define BIG_SWAP_SIZE 512static void swap(void *a, void *b, size_t size){    char *tmp = (char*)malloc(size);    memcpy(tmp, a, size);    memcpy(a, b, size);    memcpy(b, tmp, size);    free(tmp);}


 

static void select_sort(void *base, size_t nmemb,        size_t size,        int (*cmp)(const void *, const void *)){    size_t i = 0;    size_t j = 0;    size_t min = 0;    for (i = 0; i < nmemb - 1; ++i) {        min = i;        for (j = i + 1; j < nmemb; ++j) {            if (cmp(ELEM(min), ELEM(j)) > 0) {                min = j;            }        }        if (min != i) {            swap(ELEM(min), ELEM(i), size);        }    }}


 

static void bubble_sort(void *base, size_t nmemb,        size_t size,        int (*cmp)(const void *, const void *)){    size_t i = 0;    size_t j = 0;    for (i = 1; i < nmemb; ++i) {        for (j = 0; j < nmemb - i; ++j) {            if (cmp(ELEM(j), ELEM(j+1)) > 0) {                swap(ELEM(j), ELEM(j+1), size);            }        }    }}


 

static void insert_sort(void *base, size_t nmemb,        size_t size,        int (*cmp)(const void *, const void *)){    size_t i = 0;    ssize_t j = 0;    char *tmp = NULL;    tmp = (char*)malloc(size);    for (i = 1; i < nmemb; ++i) {        if (cmp(ELEM(i), ELEM(i-1)) >= 0) {            continue;        }        memcpy(tmp, ELEM(i), size);        for (j = i - 1; j >= 0; --j) {            if (cmp(tmp, ELEM(j)) < 0) {                memcpy(ELEM(j+1), ELEM(j), size);            } else {                memcpy(ELEM(j+1), tmp, size);                break;            }        }        //i?..?€?..绱..姣.澶э?姝ゆ.i搴..?ュ.0?峰.绱..浣.疆        if (j < 0) {            memcpy(ELEM(0), tmp, size);        }    }    free(tmp);}


 

static void shell_sort(void *base, size_t nmemb,        size_t size,        int (*cmp)(const void *, const void *)){    size_t i = 0;    ssize_t j = 0;    char *tmp = (char*)malloc(size);    ssize_t step = 0;    ssize_t offset = 0;    for (step = 3; step >= 1; --step) {    for (offset = 0; offset < step; ++offset) {    //?..?.?    print_array(base, nmemb);    for (i = offset + step; i < nmemb; i += step) {        if (cmp(ELEM(i), ELEM(i-step)) >= 0) {            continue;        }        memcpy(tmp, ELEM(i), size);        for (j = i - step; j >= offset; j -= step) {            if (cmp(tmp, ELEM(j)) < 0) {                memcpy(ELEM(j+step), ELEM(j), size);            } else {                memcpy(ELEM(j+step), tmp, size);                break;            }        }        //i?..?€?..绱..姣.澶э?姝ゆ.i搴..?ュ.0?峰.绱..浣.疆        if (j < offset) {            memcpy(ELEM(offset), tmp, size);        }    }


 

    } //endof offset    } //endof k    free(tmp);}


 

static void merge_sort(void *base, size_t nmemb,        size_t size,        int (*cmp)(const void *, const void *)){    if (nmemb > 2) {        merge_sort(base, nmemb / 2, size, cmp);        merge_sort(ELEM(nmemb / 2), nmemb - nmemb / 2, size, cmp);    } else if (nmemb < 2) {        return;    }    char *s = (char*)malloc(nmemb * size);    size_t l = 0;    size_t r = nmemb / 2;    size_t s_offset = 0;    for (; (l < nmemb / 2) && (r < nmemb); ++s_offset) {        if (cmp(ELEM(l), ELEM(r)) <= 0) {            memcpy(s + s_offset * size , ELEM(l), size);            ++l;        } else {            memcpy(s + s_offset * size, ELEM(r), size);            ++r;        }    }    if (l < nmemb / 2) {        memcpy(s + s_offset * size, ELEM(l), (nmemb / 2 - l) * size);    } else {        memcpy(s + s_offset * size, ELEM(r), (nmemb - r) * size);    }    memcpy(base, s, nmemb * size);    free(s);}


 

static void quick_sort(void *base, size_t nmemb,        size_t size,        int (*cmp)(const void *, const void *)){    if (nmemb < 2) {        return;    }    size_t l = 0;    size_t r = nmemb - 1;    //浠诲.涓€涓..绱.?涓?ivot    size_t ipivot = nmemb / 2;    char *pivot = (char*)malloc(size);    memcpy(pivot, ELEM(ipivot), size);    print_array(base, nmemb);    printf("pivot=%d\n", ((struct data_info*)pivot)->data);    for (; (cmp(ELEM(l), pivot) <= 0) && (l < ipivot); ++l) {}    if (l < ipivot) {        memcpy(ELEM(ipivot), ELEM(l), size);    }    while (l < r) {        for (; (cmp(ELEM(r), pivot) >= 0) && (l < r); --r) {}        if (l < r) {            memcpy(ELEM(l), ELEM(r), size);            ++l;        } else {            break;        }


 

        for (; (cmp(ELEM(l), pivot) <= 0) && (l < r); ++l) {}        if (l < r) {            memcpy(ELEM(r), ELEM(l), size);            --r;        }    }    memcpy(ELEM(l), pivot, size);    free(pivot);    print_array(base, nmemb);    quick_sort(base, l, size, cmp);    quick_sort(ELEM(l+1), nmemb - l - 1, size, cmp);}


 

static void __check_heap(void *base, size_t nmemb,        size_t size, size_t cur,        int (*cmp)(const void *, const void *)){#define LCHILD(n) (2 * (n) + 1)#define RCHILD(n) (2 * (n) + 2)    size_t max_child = 0;    while (LCHILD(cur) < nmemb) { //?..瀛..?        if ((RCHILD(cur) < nmemb)            && (cmp(ELEM(LCHILD(cur)), ELEM(RCHILD(cur))) < 0)) {            max_child = RCHILD(cur);        } else {            max_child = LCHILD(cur);        }        if (cmp(ELEM(max_child), ELEM(cur)) > 0) {            swap(ELEM(max_child), ELEM(cur), size);            cur = max_child;        } else {            break;        }    }}


 

static void heap_sort(void *base, size_t nmemb,        size_t size,        int (*cmp)(const void *, const void *)){    //?.钩?存5?    //?惧.?€?.?涓..?跺.?..?.??    size_t cur = 0;    if (nmemb % 2) {        cur = (nmemb - 3) / 2;    } else {        cur = (nmemb - 2) / 2;    }    for (; cur > 0; --cur) {        __check_heap(base, nmemb, size, cur, cmp);    }    //?.?    for (; nmemb > 1; --nmemb) {        __check_heap(base, nmemb, size, 0, cmp);        swap(ELEM(0), ELEM(nmemb-1), size);    }}


 

static void print_array(const void *s, size_t nmemb){    size_t i = 0;    for (i = 0; i < nmemb; ++i) {        printf("%d ", ((struct data_info *)s)[i].data);    }    printf("\n");}static int cmp(const void *a, const void *b){    return ((struct data_info*)a)->data - ((struct data_info*)b)->data;}int main(){    struct data_info s[] = {        {5}, {6}, {1}, {-9}, {0}, {6}, {7}, {2}, {4}, {-2}, {5}, {-1}, {15}, {19}, {7},    };    void (*sort[])(void*, size_t, size_t,        int (*)(const void*, const void*)) = {        select_sort,    //0        bubble_sort,    //1        insert_sort,    //2        shell_sort, //3        merge_sort, //4        quick_sort, //5        heap_sort,  //6    };    sort[6](s, sizeof(s) / sizeof(struct data_info),        sizeof(struct data_info), cmp);    print_array(s, sizeof(s) / sizeof(struct data_info));

       return 0;

}

 

sort_list.c

#include <stdio.h>#include "list.h"struct data_info {    ssize_t data;    struct list_head list;};static void swap(struct list_head *a, struct list_head *b){    LIST_HEAD(tmp);    __list_add(&tmp, a, a->next);    list_del(a);    __list_add(a, b, b->next);    list_del(b);    __list_add(b, tmp.prev, &tmp);    list_del(&tmp);}


 

static void select_sort(struct list_head *head,        int (*cmp)(struct list_head *,            struct list_head *)){    struct list_head *min = NULL;    struct list_head *i = NULL;    struct list_head *j = NULL;    struct list_head *tmp = NULL;    list_for_each_safe(i, tmp, head) {        min = i;        j = i;        list_for_each_continue(j, head) {            if (cmp(min, j) > 0) {                min = j;            }        }        if (min != i) {            swap(min, i);        }    }}


 

static void bubble_sort(struct list_head *head,        int (*cmp)(struct list_head *,            struct list_head *)){    struct list_head *i = NULL;    struct list_head *j = NULL;    list_for_each_reverse(i, head) {        list_for_each(j, head) {            if (j == i) {                break;            }            if (cmp(j, j->next) > 0) {                swap(j, j->next);                j = j->prev;                if (i == j) {                    i = i->next;                }            }        }    }}


 

static void insert_sort(struct list_head *head,        int (*cmp)(struct list_head *,            struct list_head *)){    struct list_head *i = head->next;    struct list_head *j = NULL;    struct list_head *tmp = NULL;    list_for_each_continue_safe(i, tmp, head) {        j = i;        if (cmp(i, i->prev) >= 0) {            continue;        } else {            list_del(i);        }        list_for_each_reverse_continue(j, head) {            if (cmp(i, j) >= 0) {                __list_add(i, j, j->next);                break;            }        }        if (j == head) {            list_add(i, head);        }    }}


 

static int cmp(struct list_head *a, struct list_head *b){    struct data_info *pa = container_of(a, struct data_info, list);    struct data_info *pb = container_of(b, struct data_info, list);    return pa->data - pb->data;}int main(){    struct data_info s[] = {        {5}, {6}, {1}, {-9}, {0}, {6}, {7}, {2}, {4}, {-2}, {5}, {-1}, {15}, {19}, {7},    };    LIST_HEAD(head);    size_t i = 0;    for (i = 0; i < sizeof(s) / sizeof(struct data_info); ++i) {        list_add_tail(&s[i].list, &head);    }    insert_sort(&head, cmp);    struct data_info *ptr = NULL;    list_for_each_entry(ptr, &head, list) {        printf("%ld ", ptr->data);    }    printf("\n");    return 0;}