list_add_tail()雙向鏈表實現分析


 

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。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM