list_add_tail 双向链表实现分析 .
2012-09-07 14:31
411 查看
http://blog.csdn.net/panda19881/article/details/7654698
在看内核v4l2示例代码driver/media/video/vivi.c时 ,看到list_add_tail()函数,现在对其进行分析:
[cpp]
view plaincopyprint?
struct list_head {
struct list_head *next, *prev;
};
list_add_tail(&buf->vb.queue, &vid->active);
/**
* list_add_tail - add a new entry
* @new: new entry to be added
* @head: list head to add it before
*
* Insert a new entry before the specified head.
* This is useful for implementing queues.
*/
static __inline__ void list_add_tail(struct list_head *_new, struct list_head *head)
{
__list_add(_new, head->prev, head);
}
/*
* Insert a new entry between two known consecutive entries.
*
* This is only for internal list manipulation where we know
* the prev/next entries already!
*/
static __inline__ void __list_add(struct list_head * _new,
struct list_head * prev,
struct list_head * next)
{
next->prev = _new;
_new->next = next;
_new->prev = prev;
prev->next = _new;
}
很多地方说:这个函数完成的功能就是添加一个新的结点在head的左边,其实不然,它是从右向左在head->priv和head两个节点之间插入_new。
假设刚开始建立链表,只有struct list_head *head,
那么前两句话有用:将next->prev = _new;
_new->next = next;
这就是将new节点添加到head 节点的左边,那么接 下来两句没用: _new->prev = prev; prev->next = _new;
如果head左边已近有了其他节点,那么调用list_add_tail()函数后,前边两句的功能一样,都是把新的节点添加在head左边,而后两句就是把新节点添加在原来head之前节点(head->priv)右边,这样就串起来了。
那list_add就反过来,把新的节点添加在head和head之后的节点(head->next)之间;
关于list_add和list_add_tail建立栈和FIFO:
list_add和list_add_tail都是在head两边插入新的节点,所以list_add先插入的节点向右移,head->next是最后插入的节点,list_add_tail先插入的节点向左移,head->next是最先插入的节点;
遍历链表都是从head开始向下,所以用list_add建立的链表先访问的是最后插入的节点,类似于栈;list_add_tail建立的链表先访问的是最先插入的节地点,类似于FIFO。
在看内核v4l2示例代码driver/media/video/vivi.c时 ,看到list_add_tail()函数,现在对其进行分析:
[cpp]
view plaincopyprint?
struct list_head {
struct list_head *next, *prev;
};
list_add_tail(&buf->vb.queue, &vid->active);
/**
* list_add_tail - add a new entry
* @new: new entry to be added
* @head: list head to add it before
*
* Insert a new entry before the specified head.
* This is useful for implementing queues.
*/
static __inline__ void list_add_tail(struct list_head *_new, struct list_head *head)
{
__list_add(_new, head->prev, head);
}
/*
* Insert a new entry between two known consecutive entries.
*
* This is only for internal list manipulation where we know
* the prev/next entries already!
*/
static __inline__ void __list_add(struct list_head * _new,
struct list_head * prev,
struct list_head * next)
{
next->prev = _new;
_new->next = next;
_new->prev = prev;
prev->next = _new;
}
struct list_head { struct list_head *next, *prev; }; list_add_tail(&buf->vb.queue, &vid->active); /** * list_add_tail - add a new entry * @new: new entry to be added * @head: list head to add it before * * Insert a new entry before the specified head. * This is useful for implementing queues. */ static __inline__ void list_add_tail(struct list_head *_new, struct list_head *head) { __list_add(_new, head->prev, head); } /* * Insert a new entry between two known consecutive entries. * * This is only for internal list manipulation where we know * the prev/next entries already! */ static __inline__ void __list_add(struct list_head * _new, struct list_head * prev, struct list_head * next) { next->prev = _new; _new->next = next; _new->prev = prev; prev->next = _new; }
很多地方说:这个函数完成的功能就是添加一个新的结点在head的左边,其实不然,它是从右向左在head->priv和head两个节点之间插入_new。
假设刚开始建立链表,只有struct list_head *head,
那么前两句话有用:将next->prev = _new;
_new->next = next;
这就是将new节点添加到head 节点的左边,那么接 下来两句没用: _new->prev = prev; prev->next = _new;
如果head左边已近有了其他节点,那么调用list_add_tail()函数后,前边两句的功能一样,都是把新的节点添加在head左边,而后两句就是把新节点添加在原来head之前节点(head->priv)右边,这样就串起来了。
那list_add就反过来,把新的节点添加在head和head之后的节点(head->next)之间;
关于list_add和list_add_tail建立栈和FIFO:
list_add和list_add_tail都是在head两边插入新的节点,所以list_add先插入的节点向右移,head->next是最后插入的节点,list_add_tail先插入的节点向左移,head->next是最先插入的节点;
遍历链表都是从head开始向下,所以用list_add建立的链表先访问的是最后插入的节点,类似于栈;list_add_tail建立的链表先访问的是最先插入的节地点,类似于FIFO。
相关文章推荐
- list_add_tail 双向链表实现分析
- list 链表及list_add_tail 双向链表实现分析
- 用数组实现栈(Stacks)、队列(Queue)和双向链表(Doubly Linked List)的伪代码
- LinkedList的实现源码分析
- 数组转换为List后add或remove出现UnsupportedOperationException异常分析
- STL源码分析----神奇的 list 的 sort 算法实现
- LinkedList双链表简单分析,及单链表的实现代码
- 集合List和ArrayList等实现类的底层原理分析
- java中List接口的实现类 ArrayList,LinkedList,Vector 的区别 list实现类源码分析
- STL源码分析----神奇的 list 的 sort 算法实现
- java非并发容器ArrayList 和 LinkedList 优缺点比较及其实现源码分析
- 【数据结构】链表LinkedList分析与关键实现
- java中List接口的实现类 ArrayList,LinkedList,Vector 的区别 list实现类源码分析
- list_add_tail 添加双向链表结点讲解
- Java 集合之List 集合的添加方法顺序分析以及add和addAll区别
- List 使用注意: List的Add(data)。 data 地址指针未变实现的是覆盖.
- Java-----Collection 实现的LinkedList(双向链表)
- java中List集合的遍历和两种实现类的比较分析
- list_add_tail
- 数组转换为List后add或remove出现UnsupportedOperationException异常分析