码迷,mamicode.com
首页 > 其他好文 > 详细

第十八天:双向链表与内核链表

时间:2014-10-30 20:46:48      阅读:267      评论:0      收藏:0      [点我收藏+]

标签:style   blog   io   color   ar   sp   div   on   log   

  对于双向链表就是在单向链表的基础上加了一个向前的结构体指针。对于一些操作的思想更加的简单。麻烦的事情就是要判断的内容更多了。因为内核链表中运用到的都是双向链表。所以要学习内核链表。就先要会对双向链表进行基本的操作。比如新增和显示。

    内核链表中的实现思想类似与面向对象的思想,成员和方法分开写。比如下面这个简单的代码:

 1 #include<stdio.h>
 2 
 3 struct boy;
 4 struct file_operations;
 5 
 6 struct boy{
 7     int age;//成员
 8     char *gf;
 9     struct file_operations *ops;
10 };
11 struct file_operations{ //方法
12     void (*fp)(struct boy *);
13 };
14 void eat(struct boy *t)//t 为this指针
15 {
16     printf("please %s\n",t->gf);
17 }
18 int main()
19 {
20     struct file_operations file;
21     file.fp = eat;
22 
23     struct boy tom;
24     tom.gf = "lily";
25     tom.ops = &file;
26     tom.ops->fp(&tom);
27 
28     struct boy jim;
29     jim.gf = "lucy";
30     jim.ops = &file;
31     jim.ops->fp(&jim);
32 }

 在这个函数中,定义了两个结构体,boy和file_operations ,在file_operations结构体中定义了函数指针,boy的结构体中定义了file_operations结构体。这样做,boy的成员就能过通过函数指针来访问函数。

   下面的代码是今晚最终的作业,对内核链表进行排序。这个就是对前面知识的大综合了。没有什么新的内容。

  1 #include<stdio.h>
  2 #include<stdlib.h>
  3 #define container_of(ptr,type,mem) (type*)((unsigned long)ptr - (unsigned long)&((type *)0)->mem)
  4 
  5 struct list_head{
  6     struct list_head *pre;
  7     struct list_head *next;
  8 };
  9 struct person{
 10     struct list_head li;
 11     int age;
 12 };
 13 struct list_head *insert(struct list_head * head ,int age);
 14 void show(struct list_head  *head);
 15 void show_pre(struct list_head *head);
 16 struct list_head *sort(struct list_head *head);
 17 int main()
 18 {
 19     struct list_head  *head = NULL;
 20     head = insert(head,10);
 21     head = insert(head,12);
 22     head = insert(head,13);
 23     head = insert(head,19);
 24     head = insert(head,21);
 25     head = insert(head,20);
 26     show(head);
 27     printf("---------\n");
 28     show_pre(head);
 29     printf("---------\n");
 30     head = sort(head);
 31     show(head);
 32 }
 33 struct list_head *insert(struct list_head * head ,int age){
 34 
 35     struct  person * p = (struct person *)malloc(sizeof(struct person));
 36     p->age = age;
 37     if(head == NULL){
 38         p->li.pre = NULL;
 39         p->li.next = NULL;
 40     }else{
 41         p->li.pre  = NULL;
 42         p->li.next = head; 
 43         head->pre  = &p->li;
 44     }
 45     return &p->li ;
 46 }
 47 
 48 void show(struct list_head  *head){
 49     struct person *tmp;
 50     while(head){
 51         tmp = container_of(head,struct person,li);
 52         printf("age is %d\n",tmp->age);
 53         head = head ->next;
 54     }
 55 }
 56 void show_pre(struct list_head *head){
 57     if(head ==NULL)
 58         return ;
 59     struct list_head *tail = head;
 60     while(tail->next)
 61         tail = tail ->next;
 62     struct person *tmp;
 63     while(tail){
 64         tmp = container_of(tail,struct person,li);
 65         printf("age is %d\n",tmp->age);
 66         tail = tail->pre;
 67     }
 68 }
 69 struct list_head *sort(struct list_head *head){
 70 
 71     if(head == NULL||head->next == NULL)
 72         return head;
 73     struct list_head *min = NULL;
 74     struct list_head *oldhead = head;
 75     struct list_head *newhead = NULL;
 76     struct list_head *cur =NULL ;
 77     struct list_head *tmp =NULL;
 78     struct list_head *tail =NULL;
 79     struct person *minvalue;
 80     struct person *curvalue;
 81     while(oldhead){
 82         //找到最小的
 83         min = oldhead;    
 84         cur = oldhead;
 85         tail = oldhead;
 86         while(cur){
 87             minvalue = container_of(min,struct person,li);
 88             curvalue = container_of(cur,struct person,li);
 89             if(minvalue->age > curvalue->age){
 90                 min = cur;
 91             }
 92             cur = cur->next;
 93         }
 94         //切下 分成四种情况 
 95         while(tail->next)
 96             tail = tail->next;
 97         if(oldhead ->next == NULL){
 98             oldhead = oldhead ->next;
 99         }else if(min == oldhead){
100             min->next->pre = NULL;    
101             oldhead = oldhead ->next;
102         }else if(min == tail){
103             min->pre->next = NULL;    
104 
105         }else{
106             min->pre->next = min->next;
107             min->next->pre = min->pre;
108             min->pre = NULL;
109         }
110         min->next = NULL;    
111         //链接到新的链表中
112         if(newhead ==NULL){
113             newhead = min;
114             tmp = newhead;
115         }else{
116             tmp ->next = min;
117             min ->next = NULL;
118             min->pre = tmp;
119             tmp = tmp->next;
120         }
121     }
122     return newhead;
123 }

 

  发现代码越写越长了。这个代码就是内核链表的实现。内核里面的链表结构大概如此。自己实现一遍后,对于以后的内核源码阅读会很有帮助。

 这个代码就是将container_of宏和双链表的操作结合起来了。综合性比较强。

 

第十八天:双向链表与内核链表

标签:style   blog   io   color   ar   sp   div   on   log   

原文地址:http://www.cnblogs.com/linrong/p/4063519.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!