12sort

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...)
#endif

struct 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 512
static 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;
}


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值