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)
#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_reverse(cur, head) \
for (cur = (head)->prev; \
(cur) != (head); \
cur = (cur)->prev)
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 ELEM(n) ((char*)base + size * (n))
#define BIG_SWAP_SIZE 512
static void swap(void *a, void *b, size_t size)
{
char *tmp = NULL;
if (size > BIG_SWAP_SIZE) {
char *s = (char*)malloc(size);
tmp = s;
} else {
char s[size];
tmp = s;
}
memcpy(tmp, a, size);
memcpy(a, b, size);
memcpy(b, tmp, size);
if (size > BIG_SWAP_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);
}
}
}
struct data_info {
int data;
};
static int cmp(const void *a, const void *b)
{
return ((struct data_info*)a)->data - ((struct data_info*)b)->data;
}
int main()
{
/* int a = 100;
* int b = 300;
* swap(&a, &b, sizeof(int));
* printf("a=%d, b=%d\n", a, b);*/
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,
};
sort[0](s, sizeof(s) / sizeof(struct data_info),
sizeof(struct data_info), cmp);
size_t i = 0;
for (i = 0; i < sizeof(s) / sizeof(struct data_info); ++i) {
printf("%d ", s[i].data);
}
printf("\n");
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 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);
}
/* swap(&s[0].list, &s[4].list);*/
select_sort(&head, cmp);
struct data_info *ptr = NULL;
list_for_each_entry(ptr, &head, list) {
printf("%ld ", ptr->data);
}
printf("\n");
return 0;
}