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);
}

 

转载于:https://www.cnblogs.com/wenqiang/p/4743058.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
一、linux内核链表 1、普通链表的数据区域的局限性 之前定义数据区域时直接int data,我们认为我们的链表需要存储的是一个int类型的数。但是实际上现实编程链接的节点不可能这么简单,而是多种多样的。 一般实际项目链表,节点存储的数据其实是一个结构体,这个结构体包含若干的成员,这些成员加起来构成了我们的节点数据区域。 2、一般性解决思路:即把数据区封装为一个结构体 (1)因为链表实际解决的问题是多种多样的,所以内部数据区域的结构体构成也是多种多样的。 这样也导致了不同程序当链表总体构成是多种多样的。 我们无法通过一套泛性的、普遍适用的操作函数来访问所有的链表,意味着我们设计一个链表就得写一套链表的操作函数(节点创建、插入、删除、遍历……)。 (2)实际上深层次分析会发现 不同的链表虽然这些方法不能通用需要单独写,但是实际上内部的思路和方法是相同的,只是函数的局部地区有不同。 实际上链表操作是相同的,而涉及到数据区域的操作就有不同 (3)问题 能不能有一种办法把所有链表操作方法里共同的部分提取出来用一套标准方法实现,然后把不同的部分留着让具体链表实现者自己去处理。 3、内核链表的设计思路 (1)内核链表实现一个纯链表的封装,以及纯链表的各种操作函数 纯链表就是没有数据区域,只有前后向指针; 各种操作函数是节点创建、插入、删除、遍历。 这个纯链表本身自己没有任何用处,它的用法是给我们具体链表作为核心来调用。 4、list.h文件简介 (1)内核核心纯链表实现在include/linux/list.h文件 (2)list.h就是一个纯链表的完整封装,包含节点定义和各种链表操作方法。 二、内核链表的基本算法和使用简介 1、内核链表的节点创建、删除、遍历等 2、内核链表的使用实践 (1)问题:内核链表只有纯链表,没有数据区域,怎么使用? 使用方法是将内核链表作为将来整个数据结构的结构体的一个成员内嵌进去。类似于公司收购,实现被收购公司的功能。 这里面要借助container_of宏。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值