首页 > 代码库 > 第十八天:双向链表与内核链表

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

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

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

 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 = http://www.mamicode.com/container_of(min,struct person,li); 88             curvalue = http://www.mamicode.com/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宏和双链表的操作结合起来了。综合性比较强。

 

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