我想了解Linux內核實現的鏈表和哈希表。實施的鏈接是here。我瞭解鏈接列表的實現。但是我對hlist(** pprev)中使用雙指針的原因感到困惑。 hlist的鏈接是here。我知道hlist用於執行散列表,因爲列表的頭部只需要一個指針並且節省了空間。爲什麼不能使用單個指針來完成(就像鏈表一樣* prev)?請幫幫我。在linux內核中使用雙指針哈希列表實現
16
A
回答
19
之所以可以在評論的一個發現:
547/*
548 * Double linked lists with a single pointer list head.
549 * Mostly useful for hash tables where the two pointer list head is
550 * too wasteful.
551 * You lose the ability to access the tail in O(1).
552 */
如果你有*分組,而不是** pprev,因爲我們正試圖以節省內存,不包括*分組中頭,那麼我們hlist實施看起來是這樣的:
struct hlist_head {
struct hlist_node *first = null;
};
struct hlist_node {
struct hlist_node *next;
struct hlist_node *prev;
};
注意,prev
指針不能指向頭部,或head->first
(不像**pprev
)。這個複雜的hlist實施,你會看到,當我們實現hlist_add_before()
:
void
hlist_init(struct hlist_head *head) {
head->first = null;
}
void
hlist_add_head(struct hlist_head *head, struct hlist_node *node) {
struct hlist_node *next = head->first;
head->first = node;
node->next = next;
node->prev = NULL;
if (next) {
next->prev = node;
}
}
注意prev
沒有任何指向,在hlist_add_head()
上述imeplementation。所以,現在當你實現hlist_add_before()
它看起來像這樣:
void
hlist_add_before(struct hlist_head *head,
struct hlist_node *node,
struct hlist_next *next) {
hlist_node *prev = next->prev;
node->next = next;
node->prev = prev;
next->prev = node;
if (prev) {
prev->next = node;
} else {
head->first = node;
}
}
注意,現在我們需要在head
傳遞以及對hlist_add_before()
,這需要在棧上推head
額外push
指令。此外,還有一個額外的條件檢查實施,這進一步減慢了事情。
現在,嘗試執行其他hlist操作,使用*prev
而不是**pprev
,並且您會發現您的實現將比您在Linux內核中看到的要慢。
相關問題
- 1. Linux內核哈希表struct hlist_head
- 2. 指針的指針在哈希表
- 3. 雙探針哈希表
- 4. Linux中的指針計算內核分配實現
- 5. 實現使用哈希表中的Java
- 6. 哈希表實現
- 7. 理解PID哈希表在Linux內核中
- 8. 實現在哈希表
- 9. 如何使用linux內核列表實現隊列?
- 10. Linux內核實現
- 11. 如何使用BST實現哈希表?
- 12. 使用矢量C++實現哈希表
- 13. 哈希表 - 散列函數實現
- 14. 哈希表如何在JavaScript中實現
- 15. 在C中的哈希表實現?
- 16. 持久哈希表實現
- 17. 實現哈希表的
- 18. Java哈希表實現
- 19. Java哈希表實現
- 20. 使用鏈接列表數組實現哈希表
- 21. 在Linux內核中的memcpy實現
- 22. ArrayList哈希表空指針異常
- 23. C哈希表指針錯誤
- 24. Linux內核編程:「無法處理內核NULL指針引用」
- 25. 哈希碼實現
- 26. Linux內核:copy_from_user - 結構與指針
- 27. 如何用鏈接實現哈希表?
- 28. C++中的哈希表實現
- 29. python中的哈希表實現
- 30. C指針列表(雙指針)
感謝您的回答。但我懷疑爲什麼沒有* prev並且有一個雙向鏈表。使用這個你可以遍歷兩種方式。您可以在O(1)中添加和刪除節點。兩種情況下使用的內存都相同。我顯然在這裏錯過了一些東西。你能指出我的錯誤嗎? – bala1486 2010-06-17 14:31:30
看我的詳細答案是否有用。 :) – Sudhanshu 2010-06-18 06:30:54
非常感謝... – bala1486 2010-06-24 18:39:10