双向链接表 linux

 1 #ifndef __LIST_H__
 2 #define __LIST_H__
 3 
 4 typedef struct LIST LIST;
 5 struct LIST
 6 {
 7   LIST *next;
 8   LIST *prev;
 9 };
10 
11 typedef struct LIST_HEAD
12 {
13   int count;
14   LIST first;
15 } LIST_HEAD;
16 
17 #define DO_LIST_INIT(name)     \
18   { &(name),  &(name)}
19 
20 #define LIST_INIT(head)        \
21   LIST head = DO_LIST_INIT(head)
22 
23 #define INIT_LIST(head)        \
24   do { (head)->next = (head); (head)->prev = (head); } while (0)
25 
26 // list is first member of struct
27 #define LIST_ITEM_PTR_CAST(list_ptr, item_type) ((item_type *)(list_ptr) )
28 
29 // list is not first member of struct
30 #define LIST_ITEM_PTR(list_ptr, item_type, list_member) \
31     ((item_type *)((char *)(list_ptr)-(unsigned int)(&((item_type *)0)->list_member)))
32 
33 LIST * list_get_prev(LIST *entry);
34 LIST * list_get_next(LIST *entry);
35 
36 unsigned int list_is_empty(LIST *head);
37 unsigned int list_is_empty_careful(LIST *head);
38 unsigned int list_is_last(LIST *entry, LIST *head);
39 
40 void list_item_add(LIST_HEAD * head, LIST * item);
41 void list_item_del(LIST_HEAD * head, LIST * item);
42 
43 void list_add_after_head(LIST *entry, LIST *head); // head entry ... tail
44 void list_add_before_head(LIST *entry, LIST *head); // entry head ... tail
45 
46 void list_add_after(LIST *entry, LIST * where);
47 void list_add_before(LIST *entry, LIST * where);
48 
49 void list_del_after_head(LIST *head);
50 void list_del_before_head(LIST *head);
51 void list_del(LIST *entry);
52 
53 void list_splice_after_head(LIST * list, LIST * head);
54 void list_splice_before_head(LIST * list, LIST * head);
55 
56 void list_replace(LIST *old, LIST *new);
57 
58 void list_move_after_head(LIST *entry, LIST *head);
59 void list_move_before_head(LIST *entry, LIST *head);
60 
61 void list_init(LIST *list); // INIT_LIST(list)
62 
63 #endif /* __LIST_H__ */

 

 

  1 #include "list.h"
  2 
  3 unsigned int list_is_empty(LIST *head)
  4 {
  5   return head->next == head;
  6 }
  7 
  8 unsigned int list_is_empty_careful(LIST *head)
  9 {
 10   LIST *next = head->next;
 11   return ( next == head ) && ( next == head->prev );
 12 }
 13 
 14 unsigned int list_is_last(LIST *entry, LIST *head)
 15 {
 16   return entry->next == head;
 17 }
 18 
 19 LIST * list_get_prev(LIST *entry)
 20 {
 21   return entry->prev;
 22 }
 23 
 24 LIST * list_get_next(LIST *entry)
 25 {
 26   return entry->next;
 27 }
 28 
 29 void __list_add(LIST *entry, LIST *prev, LIST *next)
 30 {
 31   next->prev = entry;
 32   entry->next = next;
 33   entry->prev = prev;
 34   prev->next = entry;
 35 }
 36 
 37 // head entry ... tail
 38 void list_add_after_head(LIST *entry, LIST *head)
 39 {
 40   __list_add( entry, head, head->next );
 41 }
 42 
 43 // entry head ... tail
 44 void list_add_before_head(LIST *entry, LIST *head)
 45 {
 46   __list_add( entry, head->prev, head );
 47 }
 48 
 49 // ... where entry ...
 50 void list_add_after(LIST *entry, LIST * where)
 51 {
 52   list_add_after_head( entry, where );
 53 }
 54 
 55 // ... entry where ...
 56 void list_add_before(LIST *entry, LIST * where)
 57 {
 58   list_add_before_head( entry, where );
 59 }
 60 
 61 void __list_del(LIST *prev, LIST *next)
 62 {
 63   next->prev = prev;
 64   prev->next = next;
 65 }
 66 
 67 // head [ **entry** ] ... tail
 68 void list_del_after_head(LIST *head)
 69 {
 70   __list_del( head, head->next );
 71 }
 72 
 73 // [ **entry** ] head ... tail
 74 void list_del_before_head(LIST *head)
 75 {
 76   __list_del( head->prev, head );
 77 }
 78 
 79 // ... [ **entry** ] ...
 80 void list_del(LIST *entry)
 81 {
 82   __list_del( entry->prev, entry->next );
 83   INIT_LIST( entry );
 84 }
 85 
 86 // prev : list->next list->prev : next
 87 void __list_splice(const LIST *list, LIST *prev, LIST *next)
 88 {
 89   LIST *first = list->next;
 90   LIST *last = list->prev;
 91 
 92   first->prev = prev;
 93   prev->next = first;
 94 
 95   last->next = next;
 96   next->prev = last;
 97 
 98 }
 99 
100 // head list_tail ... list_head ... tail
101 void list_splice_after_head(LIST * list, LIST * head)
102 {
103   if (!list_is_empty( list ))
104   {
105     __list_splice( list, head, head->next );
106     INIT_LIST( list );
107   }
108 }
109 
110 // list_tail ... list_head --- head ... tail
111 void list_splice_before_head(LIST * list, LIST * head)
112 {
113   if (!list_is_empty( list ))
114   {
115     __list_splice( list, head->prev, head );
116     INIT_LIST( list );
117   }
118 }
119 
120 void list_replace(LIST *old, LIST *new)
121 {
122   new->next = old->next;
123   new->next->prev = new;
124   new->prev = old->prev;
125   new->prev->next = new;
126   INIT_LIST( old );
127 }
128 
129 // head --- entry --- ... --- tail
130 void list_move_after_head(LIST *entry, LIST *head)
131 {
132   __list_del( entry, head );
133   list_add_after_head( entry, head );
134 }
135 
136 // head --- ... --- tail --- entry
137 void list_move_before_head(LIST *entry, LIST *head)
138 {
139   __list_del( entry, head );
140   list_add_before_head( entry, head );
141 }
142 
143 void list_init(LIST *list)
144 {
145   list->next = list;
146   list->prev = list;
147 }
148 
149 void list_item_add(LIST_HEAD * head, LIST * item)
150 {
151   // head --> 0 --> 1 --> 2 --> 3 --> head
152   list_add_before_head( item, & ( head->first ) );
153   head->count++;
154 }
155 
156 void list_item_del(LIST_HEAD * head, LIST * item)
157 {
158   list_del( item );
159   head->count--;
160 }
161 
162 #define LIST_ITEM_COUNT ( 3 )
163 void list_demo(void)
164 {
165   typedef struct ITEM
166   {
167     LIST list;
168     int a;
169   } ITEM;
170 
171   LIST_HEAD head;
172   ITEM items [ LIST_ITEM_COUNT ];
173 
174   head.count = 0;
175   INIT_LIST( &head.first );
176 
177   // head --> 0 --> 1 --> 2 --> 3 --> head
178   for (unsigned int i = 0; i < LIST_ITEM_COUNT; i++)
179   {
180     list_item_add( &head, &items [ i ].list );
181   }
182 
183   unsigned int i = 0;
184   for (LIST * entry = head.first.next; entry != &head.first; entry =
185     entry->next)
186   {
187     LIST_ITEM_PTR(entry, ITEM, list) ->a = i++;
188     //LIST_ITEM_PTR_CAST(entry, ITEM) ->a = i++;
189   }
190 
191   list_item_del( &head, &items [ LIST_ITEM_COUNT - 2 ].list );
192   list_item_del( &head, &items [ LIST_ITEM_COUNT - 1 ].list );
193   list_item_del( &head, &items [ 0 ].list );
194 }
posted @ 2012-09-10 08:48  IAmAProgrammer  阅读(456)  评论(0编辑  收藏  举报