linux简单内核链表排序

#include <stdio.h>
#include <stdlib.h>

#define container_of(ptr, type, mem)(type *)((unsigned long)ptr -(unsigned long)&((type *)NULL)->mem) 

struct person {
    struct person *next;
    struct person *pre;
};

struct boy {
    struct person p;
    int age;
};

struct person *creat(struct person *head, int age);
struct person *choose_sort(struct person *head);
struct person *insert_sort(struct person *head);
void show(struct person *head);

int main()
{
    struct person *head = NULL;
    head = creat(head, 30);
    head = creat(head, 20);
    head = creat(head, 25);
    head = creat(head, 80);
    head = creat(head, 60);
    head = creat(head, 40);
    head = insert_sort(head);
    show(head);    

}
struct person *creat(struct person *head, int age)
{
    struct boy *tmp = NULL;
    struct person *find = NULL;

    tmp = (struct boy *)malloc(sizeof(struct boy));
    tmp->age = age;
    tmp->p.next = NULL;
    tmp->p.pre = NULL;

    if(NULL == head) {
        head = &tmp->p;
        head->next = head;
        head->pre = head;
        return head;
    }

    find = head;
    while(find->next != head) {
        find = find->next;
    }

    find->next = &tmp->p;
    tmp->p.pre = find;
    tmp->p.next = head;
    head->pre = &tmp->p;

    return head;
}
#if 0
struct person *choose_sort(struct person *head)
{
    struct person *tmp = NULL;
    struct boy *min = NULL;
    struct person *newhead = NULL;
    struct person *tail = NULL;
    struct boy *find = NULL;

    while(head) {
        tmp = head;
        min = container_of(head, struct boy, p);

        do {
            find = container_of(tmp, struct boy, p);
            if(find->age < min->age) {
                min = find;
            }
            tmp = tmp->next;

        } while(tmp != head);

        struct person *min_p = &min->p;
        if(min_p == head && head->next != head) {
            head = head->next;
            head->pre = min_p->pre;
            min_p->pre->next = head;
            min_p->pre = NULL;
            min_p->pre = NULL;
        }
        else {
            if(min_p == head && head->next == head) {
                head->next = NULL;
                head->pre = NULL;
                head = head->next;
            }

            else {
                min_p->pre->next = min_p->next;
                min_p->next->pre = min_p->pre;
                min_p->next = NULL;
                min_p->pre = NULL;
            }
        }
        if(NULL == newhead) {
            newhead = min_p;
            newhead->next = newhead;
            newhead->pre = newhead;
            tail = newhead;
            continue;
        }
        tail->next = min_p;
        min_p->pre = tail;
        min_p->next = newhead;
        newhead->pre = min_p;
        tail = min_p;
    }
    return newhead;
}

#else
struct person *choose_sort(struct person *head)
{
    struct person *tmp = NULL;
    struct boy *min = NULL;
    struct person *newhead = NULL;
    struct person *tail = NULL;
    struct boy *find = NULL;

    while(head) {
        tmp = head;
        min = container_of(head, struct boy, p);

        do {
            find = container_of(tmp, struct boy, p);
            if(find->age < min->age) {
                min = find;
            }
            tmp = tmp->next;

        } while(tmp != head);

        if(&min->p == head && head->next != head) {
            head = head->next;
            head->pre = min->p.pre;
            min->p.pre->next = head;
            min->p.pre = NULL;
            min->p.next = NULL;
        }
        else {
            if(&min->p == head && head->next == head) {
                head->next = NULL;
                head->pre = NULL;
                head = head->next;
            }

            else {
                min->p.pre->next = min->p.next;
                min->p.next->pre = min->p.pre;
                min->p.next = NULL;
                min->p.pre = NULL;
            }
        }
        if(NULL == newhead) {
            newhead = &min->p;
            newhead->next = newhead;
            newhead->pre = newhead;
            tail = newhead;
            continue;
        }
        tail->next = &min->p;
        min->p.pre = tail;
        min->p.next = newhead;
        newhead->pre = &min->p;
        tail = &min->p;
    }
    return newhead;
}
#endif

struct person *insert_sort(struct person *head)
{
    struct boy *tmp = NULL;
    struct boy *new = NULL;
    struct person *find = NULL;
    struct person *list = NULL;
    struct person *newhead = NULL;
    struct person *tail = NULL;
    struct boy *key = NULL;

    while(head) {
        find = head;
        tmp = container_of(find, struct boy, p);
        if(head->next == head) {
            head->next = NULL;
            head = head->next;
            find->pre = NULL;
        }
        else {
            head = head->next;
            head->pre = find->pre;
            find->pre->next = head;
            find->pre = NULL;
            find->next = NULL;
        }

        if(NULL == newhead) {
            newhead = find;
            newhead->pre = newhead;
            newhead->next = newhead;
            continue;
        }
        new = container_of(newhead, struct boy, p);
        if(tmp->age < new->age) {
            find->next = newhead;
            find->pre = newhead->pre;
            newhead->pre->next = find;
            newhead->pre = find;
            newhead = find;
            continue;
        }

        list = newhead;
        do {
            key = container_of(list, struct boy, p);
            if(key->age > tmp->age)
                    break;
            list = list->next;
        } while(list != newhead);

        if(key->age < tmp->age) {
            list->next = find;
            find->pre = list;
            find->next = newhead;
            newhead->pre = find;
        }
        else {
            find->next = list;
            find->pre = list->pre;
            list->pre->next = find;
            list->pre = find;
        }
    }
    return newhead;
}

void show(struct person *head)
{
    struct person *tmp = NULL;
    struct boy *find = NULL;
    tmp = head;
    do {
        find = container_of(tmp, struct boy, p);
        printf("age is %d\n", find->age);
        tmp = tmp->next;    

    } while(tmp != head);

    printf("-------------------------------------\n");
    do {
        find = container_of(tmp, struct boy, p);
        printf("age is %d\n", find->age);
        tmp = tmp->pre;    

    } while(tmp != head);
}
时间: 2024-08-29 15:01:00

linux简单内核链表排序的相关文章

Linux 内核 链表 的简单模拟(2)

接上一篇Linux 内核 链表 的简单模拟(1) 第五章:Linux内核链表的遍历 /** * list_for_each - iterate over a list * @pos: the &struct list_head to use as a loop cursor. * @head: the head for your list. */ #define list_for_each(pos, head) for (pos = (head)->next; pos != (head);

Linux 内核 链表 的简单模拟

第零章:扯扯淡 出一个有意思的题目:用一个宏定义FIND求一个结构体struct里某个变量相对struc的编移量,如 struct student { int a; //FIND(struct student,a) 等于0 char b; //FIND(struct student,b)等于4 double c; }; 参考答案:#define FIND(type,member) ((size_t)&((type*)0)->member) 我这样理解(可能不太正确): (type*)0,0在

例说Linux内核链表(二)

链表使用 我认为熟悉内核链表功能最好的方法就是看一些简单的实例,实例是一个非常好的素材去更好的理解链表. 下面是一个例子,包含创建,添加,删除和遍历链表. <span style="font-size:14px;"><span style="color:#330099;">#include <stdio.h> #include <stdlib.h> #include "list.h" struct

linux驱动开发要知道的那些知识(二)------list内核链表

内核链表 链表数据结构简介 链表是一种常用的组织有序数据的数据结构,它通过指针将一系列数据节点连接成一条数据链,是线性表的一种重要实现方式.相对于数组,链表具有更好的动态性,建立链表时无需预先知道数据总量,可以随机分配空间,可以高效地在链表中的任意位置实时插入或删除数据.链表的开销主要是访问的顺序性和组织链的空间损失. 通常链表数据结构至少应包含两个域:数据域和指针域,数据域用于存储数据,指针域用于建立与下一个节点的联系.按照指针域的组织以及各个节点之间的联系形式,链表又可以分为单链表.双链表.

Linux 内核链表使用举例

链表数据结构的定义很简洁: struct list_head { struct list_head *next, *prev; }; list_head结构包含两个指向list_head结构的指针prev和next,该内核链表具备双链表功能,通常它都组织成双循环链表,这里的list_head没有数据域.在Linux内核链表中,不是在链表结构中包含数据,而是在数据结构中包含链表节点.下面是一个简单的内核模块的例子,包含了对链表进行插入.删除.遍历的一些函数: list.c: #include <l

链表的艺术——Linux内核链表分析

引言: 链表是数据结构中的重要成员之中的一个.因为其结构简单且动态插入.删除节点用时少的长处,链表在开发中的应用场景许多.仅次于数组(越简单应用越广). 可是.正如其长处一样,链表的缺点也是显而易见的.这里当然不是指随机存取那些东西,而是因为链表的构造方法(在一个结构体中套入其同类型指针)使得链表本身的逻辑操作(如添加结点,删除结点,查询结点等),往往与其应用场景中的业务数据相互混杂.这导致我们每次使用链表都要进行手工打造,做过链表的人肯定对此深有了解. 是否能将链表从变换莫測的业务数据中抽象出

Linux中的内核链表

链表中一般都要进行初始化.插入.删除.显示.释放链表,寻找节点这几个操作,下面我对这几个操作进行简单的介绍,因为我的能力不足,可能有些东西理解的不够深入,造成一定的错误,请各位博友指出. A.Linux内核链表中的几个主要函数(下面是内核中的源码拿出来给大家分析一下) 1)初始化: #define INIT_LIST_HEAD(ptr) do { \ (ptr)->next = (ptr); (ptr)->prev = (ptr); \} while (0)   // ptr为struct l

C语言 Linux内核链表(企业级链表)

//Linux内核链表(企业级链表) #define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #include<stdlib.h> #include<string.h> #define offscfof(TYPE,MEMBER) ((size_t)&((TYPE *)0)->MEMBER) #define container_of(ptr,type,member) (type *)((char *)ptr-off

Linux内核链表复用实现队列

有了前面Linux内核复用实现栈的基础,使用相同的思想实现队列,也是非常简单的.普通单链表复用实现队列,总会在出队或入队的时候有一个O(n)复杂度的操作,大多数采用增加两个变量,一个head,一个tail来将O(n)降成O(1).但是在内核链表中,天然的双向循环链表,复用实现队列,无论出队还是入队,都是O(1)时间复杂度. /* main.c */ #include <stdio.h> #include <stdlib.h> #include "queue.h"