首頁 > 運維 > linux運維 > Linux中關於核心鍊錶的程式碼實例分享

Linux中關於核心鍊錶的程式碼實例分享

黄舟
發布: 2017-08-08 11:48:54
原創
1764 人瀏覽過

這篇文章主要介紹了Linux中的內核鍊錶實例詳解的相關資料,鍊錶中一般都要進行初始化、插入、刪除、顯示、釋放鍊錶,尋找節點這幾個操作,需要的朋友可以參考下

Linux中的核心鍊錶實例詳解

連結中一般都要初始化、插入、刪除、顯示、釋放鍊錶,尋找節點這幾個操作,以下我對這幾個操作進行簡單的介紹,因為我的能力不足,可能有些東西理解的不夠深入,造成一定的錯誤,請各位博友指出。

A、Linux核心鍊錶中的幾個主要函數(下面是核心中的原始碼拿出來給大家分析一下)

1)初始化:


1

2

3

#define INIT_LIST_HEAD(ptr) do { \

(ptr)->next = (ptr); (ptr)->prev = (ptr); \

} while (0)  // ptr为struct list_head,其中包括两个指针next和prev,这里已经可以看出内核链表是双向循环链表

登入後複製

2)尾部插入:


1

2

3

4

static inline void list_add_tail(struct list_head *new, struct list_head *head)

{

__list_add(new, head->prev, head);

} //尾部插入,传入的参数是新节点中的两个指针和头结点中的两个指针

登入後複製

3)頭部插入函數


1

2

3

4

static inline void list_add(struct list_head *new, struct list_head *head)

{

__list_add(new, head, head->next);

} //头插入函数,传入的参数是新节点中的两个指针和头结点中的两个指针

登入後複製

4)刪除節點函數


1

2

3

4

5

6

static inline void list_del(struct list_head *entry)  //传入要删除节点中的指针域

{

__list_del(entry->prev, entry->next);//两个参数分别为所删除节点前一个节点和后一个节点

entry->next = (void *) 0;//删除节点后置为空

entry->prev = (void *) 0;

}

登入後複製

5)顯示函數(如果要列印出鍊錶中的資訊的話要自己寫成列印的函數,例如printf,因為這個其實是遍歷的函數,沒有顯示的功能)


1

2

3

4

5

6

7

8

9

10

#define list_for_each_entry(pos, head, member) \

for (pos = list_entry((head)->next, typeof(*pos), member); \

&pos->member != (head); \

pos = list_entry(pos->member.next, typeof(*pos), member))

 

/* 这个函数用于遍历链表

pos为节点指针,

head是头结点中的两个指针的地址

member为各节点中的指针域

*/

登入後複製

6)刪除鍊錶


1

2

3

4

5

#define list_for_each_safe(pos, n, head) \

for (pos = (head)->next, n = pos->next; pos != (head); \

pos = n, n = pos->next)

 

//这里面的pos和n都是list_head指针,n指针是用于在删除时不让链表断链

登入後複製

7)尋找節點(這也是用的核心中的遍歷函數)


1

2

3

4

#define list_for_each_entry(pos, head, member) \

for (pos = list_entry((head)->next, typeof(*pos), member); \

&pos->member != (head); \

pos = list_entry(pos->member.next, typeof(*pos), member))

登入後複製

B.下面來段程式碼給大家看看具體的運用方法


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

#include"kernel.h"

#include<errno.h>

#include<stdio.h>

#include<stdlib.h>

 

typedef struct list_node

{

int data;

struct list_head list;//节点的指针域是被封装在struct list_head这个结构体内

//这个结构体中包括struct list_head *next,*prev

}*node,node1;

 

 

node init_head(node head)//初始化空链表

{

head = (node)malloc(sizeof(node1));//为节点分配空间

if(head == NULL)

{

perror("head");

return NULL;

}

INIT_LIST_HEAD(&(head->list));//#define INIT_LIST_HEAD(ptr) do { \

(ptr)->next = (ptr); (ptr)->prev = (ptr); \

} while (0)//调用内核中的初始化函数,传入的参数是

//节点的中两个指针,即struct list_head结构体中的两个指针

return head;

}

 

node insert_tail(node head,int data)//尾部插入函数

{

node new = (node)malloc(sizeof(node1));//为新节点分配空间

if(new == NULL)//判断一下分配空间是否成功

{

perror("new:");

return NULL;

}

new->data = data;

list_add_tail(&(new->list),&(head->list));//调用内核中的从尾部插入的函数,传入的参数为新节点中的两个指针

//和头结点中的两个指针

return 0;

}

 

  

 

head_insert_node(node head,int data)//头插入函数

{

node new;//创建一个新节点

new = (node)malloc(sizeof(node1));//为新节点分配空间

if(new == NULL)//判断一下分配空间是否成功

{

perror("new:");

return 0;

}

new->data = data;

list_add(&(new->list),&(head->list));//调用内核中从头插入的函数,传入的参数为新节点的两个指针和头结点的两个指针

return 0;

}

 

node search_node(node head,int data)//寻找节点函数

{

node p = NULL;

list_for_each_entry(p,&(head->list),list) //内核中的遍历函数

{

if(p->data == data) //p即为需要找的节点

{

printf("found the data:%d\n",p->data);

goto OK;

}

}

 

puts("not found the data!");

return NULL;

 

OK:

return p;

}

 

int show_node(node tmp)

{

if(tmp == NULL)

{

puts("tmp is NULL!");

return -1;

}

printf("the data is %d\n",tmp->data);

return 0;

}

 

int delete_node(node head,int data)

{

node p = NULL;

list_for_each_entry(p,&(head->list),list)

{

if(p->data == data)

{

printf("found the data which you want to delete!\n");

goto f;

}

}

 

f:

list_del(&(p->list));

free(p);

return 0;

}

int show_list(node head)

{

node p = NULL;

list_for_each_entry(p,&(head->list),list)

{

printf("data:%d\n",p->data);

}

return 0;

}

int delete_list(node head)//删除链表函数

{

node p,q;

list_for_each_entry_safe(p,q,&(head->list),list)//这是内核中的安全删除函数

{

list_del(&(p->list));

free(p);

}

list_del(&(head->list));

free(head);

return 0;

}

int main(int argc,char **argv)

{

node head;

node tmp;

head = init_head(head);//初始化空链表函数

insert_tail(head,45);//从末尾插入函数

insert_tail(head,55);

insert_tail(head,65);

head_insert_node(head,75);//从头插入函数

show_list(head); //显示链表函数

 

tmp = search_node(head,55);//寻找结点函数

show_node(head);

delete_node(head,55);

//show_list(head);

delete_list(head);//删除链表函数

return 0;

}

登入後複製

以上是Linux中關於核心鍊錶的程式碼實例分享的詳細內容。更多資訊請關注PHP中文網其他相關文章!

相關標籤:
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
最新問題
centos7 - git的linux版本沒有centos的?
來自於 1970-01-01 08:00:00
0
0
0
學習Linux的先行知識
來自於 1970-01-01 08:00:00
0
0
0
Linux下連接資料庫
來自於 1970-01-01 08:00:00
0
0
0
Linux 批次修改檔名
來自於 1970-01-01 08:00:00
0
0
0
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板