//list.h
#pragma once
struct list_head {
struct list_head *next;
struct list_head *prev;
};
#define LIST_HEAD(head) \
struct list_head (head) = { &(head), &(head)}
/*
inline: 内联,主要修饰函数,内联函数不占用内存空间
当编译器编译时,当发现有内联函数被调用,将拷贝该函数的函数体到调用的位置,省去了函数寻址,传参返回的过程,提高程序执行的效率
弊端: 程序的体积有所增大
特点:
1. inline仅仅是个建议,inline能否成立还需要遵循一些规则
2. 规则:
a) 函数功能比较简洁,10行一下的代码量
b) 不允许出现循环、递归、多分支语句,(if支持)
c) 不允许使用函数指针指向该函数
d) 一般与static配合使用,防止作用域中名称冲突
*/
static inline void INIT_LIST_HEAD(struct list_head *node)
{
node->next = node;
node->prev = node;
}
static inline void __list_add(struct list_head *node,
struct list_head *Prev, struct list_head *Next)
{
node->next = Next;
node->prev = Prev;
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 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);
}
static inline int list_is_empty(struct list_head *head)
{
return head->next == head && head->prev == head;
}
#define list_for_each(cur, head) \
for (cur = (head)->next; cur != (head); cur = (cur)->next)
#define list_for_each_reverse(cur, head) \
for (cur = (head)->prev; cur != (head); cur = (cur)->prev)
#define list_for_each_safe(cur, Next, head) \
for (cur = (head)->next; cur != (head) &&\
(Next) = (cur)->next; cur = (Next))
/*小指针转大指针*/
#define offset_of(type, member) \
((size_t)&(((type *)0)->member))
#define container_of(ptr, type, member) \
((type *)((char *)ptr - offset_of(type, member)))
#define list_entry(ptr, type, member) \
container_of(ptr, type, member)
#define list_for_each_from(cur, head) \
//sort_list.c
#include <stdio.h>
#include "list.h"
struct data_info {
char *name;
int age;
struct list_head list;
};
#define NMEMB(array) ((sizeof array) / sizeof(array[0]))
/*比较*/
int cmp_age(const struct list_head *a, const struct list_head *b)
{
struct data_info *pa = list_entry(a, struct data_info, list);
struct data_info *pb = list_entry(b, struct data_info, list);
return pa->age - pb->age;
}
/*交换*/
void swap(struct list_head *a, struct list_head *b)
{
struct list_head tmp = {NULL, NULL};
__list_add(&tmp, b->prev, b);
list_del_init(b);
__list_add(b, a->prev, a);
list_del_init(a);
__list_add(a, tmp.prev, &tmp);
list_del_init(&tmp);
}
void sort_bubble(struct list_head *head,
int (*cmp)(const struct list_head *a,
const struct list_head *b))
{
struct list_head *last, *begin;
for (last = head->prev; last != head; last = last->prev) {
for (begin = head->next; begin != last;
begin = begin->next) {
if (cmp(begin, begin->next) > 0) {
swap(begin, begin->next);
/*重新置位:以从正确位置开始*/
begin = begin->prev;
if (begin == last) {
last = last->next;
}
}
}
}
}
void sort_select(struct list_head *head,
int (*cmp)(const struct list_head *a,
const struct list_head *b))
{
struct list_head *i, *j, *min;
for (i = head->next; i != head->prev; i = i->next) {
min = i;
for (j = i->next; j != head; j = j->next) {
if (cmp(j, min) < 0) {
min = j;
}
}
if (min != i) {
swap(i, min);
/*重新置位*/
i = min;
}
}
}
void sort_insert(struct list_head *head,
int (*cmp)(const struct list_head *a,
const struct list_head *b))
{
struct list_head *i, *j;
for (i = head->next->next; i != head; i = i->next) {
j = i->prev;
if (cmp(i , j) > 0) {
continue;
}
list_del_init(i);
for (; j != head; j = j->prev) {
if (cmp(j, i) <= 0) {
break;
}
}
__list_add(i, j, j->next);
}
}
int main()
{
struct data_info s[] = {
{"tom", 18}, {"niko", 22}, {"frank", 17}, {"kevin", 28},
{"richard", 22}, {"mark", 20} , {"tube", 21}, {"jack", 23} };
LIST_HEAD(head);
int i;
for (i = 0; i < NMEMB(s); ++i) {
list_add_tail(&s[i].list, &head);
}
//swap(&s[0].list, &s[1].list);
struct data_info *pdata = NULL;
list_for_each_entry(pdata, &head, list) {
printf("%s:%d\n", pdata->name, pdata->age);
}
printf(".......sorting....\n");
//sort_bubble(&head, cmp_age);
sort_select(&head, cmp_age);
//sort_insert(&head, cmp_age);
list_for_each_entry(pdata, &head, list) {
printf("%s:%d\n", pdata->name, pdata->age);
}
return 0;
}
for (; cur != (head); cur = (cur)->next)
#define list_for_each_continue(cur, head) \
for (cur = (cur)->next; cur != (head); cur = (cur)->next)
#define list_for_each_from_safe(cur, Next, head) \
for (; (cur != (head)) && (Next = (cur)->next); cur = Next)
#define list_for_each_continue_safe(cur, Next, head) \
for (cur = (cur)->next; (cur != (head)) && (Next = (cur)->next); cur = Next)
#define list_for_each_entry(Pos, head, member) \
for (Pos = list_entry((head)->next, typeof(*Pos), member);\
&((Pos)->member) != (head); \
Pos = list_entry((Pos)->member.next, typeof(*Pos),member))