之前看到一篇单向链表的博文,代码也看着很舒服,于是乎记录下来,留给自己~,循序渐进,慢慢

  延伸到真正的内核链表~(敢问路在何方?路在脚下~)

  1. 简介

  链表是Linux 内核中最简单,最普通的数据结构。链表是一种存放和操作可变数量元素(常称为节点)

  的数据结构,链表和静态数组的不同之处在于,它所包含的元素都是动态创建并插入链表的,在编译

  时不必知道具体需要创建多少个元素,另外也因为链表中每个元素的创建时间各不相同,所以它们在

  内存中无须占用连续内存区。正是因为元素不连续的存放,所以各个元素需要通过某种方式被链接在

  一起,于是每个元素都包含一个指向下一个元素的指针,当有元素加入链表或从链表中删除元素时,

  简单调整一下节点的指针就可以了。

  根据它的特性,链表可分为:单链表,双链表,单向循环链表和双向循环链表,今天总结记录的就是

  最简单的单链表,

  1.1 节点类型描述

  1 typedef struct node_t {

  2 data_t data; /* 节点数据域 */

  3 struct node_t *next; /* 节点的后继指针域 */

  4 }linknode_t, *linklist_t;

  另一种写法

  1 struct node_t {

  2 data_t data;

  3 struct node_t *next;

  4 }

  5 typedef struct node_t linknode_t;

  6 typedef struct node_t* linklist_t;

  细看说明:

  * linknode_t A;

  * linklist_t p = &A;

  *

  * 结构变量A为所描述的节点,而指针变量p为指向此类型节点的指针(p值为节点的地址)

  * 这样看来 linknode_t 和 linklist_t 的作用是一样的,那么为什么我们要定义两个数据类

  * 型(同一种)呢? 答曰:主要为了代码的可读性,我们要求标识符要望文识义,便于理解

  *

  * linknode_t *pnode 指向一个节点

  * linklist_t list 指向一个整体

  1.2 头节点 head (~黄河之水天上来~)

  在顺序存储线性表,如何表达一个空表{ },是通过list->last = -1来表现的,所谓的空表就是

  数据域为NULL,而链表有数据域和指针域,我们如何表现空链表呢?这时,就引入了头结点

  的概念,头结点和其他节点数据类型一样,只是数据域为NULL,head->next = NULL,下面

  我们看一个创建空链表的函数,如何利用头结点来创建一个空链表,只要头节点在,链表就还在~

  

  1 // 创建一个空链表

  2 linklist_t

  3 CreateEmptyLinklist()

  4 {

  5 linklist_t list;

  6 list = (linklist_t)malloc(sizeof(linknode_t));

  7

  8 if(NULL != list) {

  9 list->next = NULL;

  10 }

  11

  12 return list;

  13 }

  

  2. 链表基本运算的相关"算法"操作 or 操刀(~烹羊宰牛且为乐,会须一饮三百杯~)

  链表的运算除了上面的创建空链表,还有数据的插入,删除,查找等函数,链表的运算有各种实现方

  法,如何写出一个高效的,封装性较好的函数是我们要考虑的,比如数据插入函数,我们就要尽可能

  考虑所有能出现的结果,比如:1)如果需插入数据的链表是个空表;2)所插入的位置超过了链表的

  长度;如果我们的函数能包含所有能出现的情况,不仅能大大提高我们的开发效率,也会减少代码的

  错误率。下面看一个可用性较强的链表插入操作的函数实现~

  

  int

  InsertLinklist(linklist_t list, int at, data_t x)

  {

  linknode_t * node_prev, * node_at, * node_new;

  int pos_at;

  int found = 0;

  if (NULL == list) return -1;

  /* at must >= 0 */

  if (at < 0) return -1;

  /*第一步、新节点分配空间*/

  node_new = (linklist_t)malloc(sizeof(linknode_t));

  if (NULL == node_new) {

  return -1;

  }

  node_new->data = x; /* assigned value */

  /*

  *节点如果插入超过链表长度的位置,会接到尾节点后面,

  *这样,node_new成了尾节点,node_new->next = NULL

  */

  node_new->next = NULL;

  /*第二步、定位*/

  node_prev = list; //跟随指针,帮助我们更好的定位

  node_at = list->next; //遍历指针

  pos_at = 0;

  while(NULL != node_at) {

  if(pos_at == at){

  found = 1; //找到正确的位置,跳出循环

  break;

  }

  /* move to the next pos_at */

  node_prev = node_at; //跟随指针先跳到遍历指针的位置

  node_at = node_at->next; //遍历指针跳到下一个节点的位置

  pos_at++;

  }

  /*第三步、插入*/

  if(found) {

  /* found = 1,找到正确的位置,插入 */

  node_new->next = node_at; //插入的节点next指向node_at

  node_prev->next = node_new; //插入节点的前一个节点

  }

  else {

  /*若是没找到正确的位置,即所插入位置超越了链表的长度,

  *则接到尾节点的后面,同样,这样适用于{ }即空链表,这样

  *我们可以建立一个空链表,利用这个函数,实现链表的初始化

  */

  node_prev->next = node_new;

  }

  return 0;

  }

  

  3. 正文开始 Demo(~与君歌一曲,请君为我倾耳听~)

  listlink.h

 

  1 #ifndef _LIST_LINK_H_

  2 #define _LIST_LINK_H_

  3

  4 typedef int data_t;

  5

  6 typedef struct node_t {

  7 data_t data; /* 节点数据域 */

  8 struct node_t * next; /* 节点的后继指针域 */

  9 }linknode_t, * linklist_t;

  10

  11

  12

  13 /* 链表操作函数*/

  14

  15 // 创建一个空链表

  16 linklist_t CreateEmptyLinklist();

  17

  18 // 销毁链表

  19 void DestroyLinklist(linklist_t list);

  20

  21 // 清空链表

  22 void ClearLinklist(linklist_t list);

  23

  24 // 是否为空链表

  25 int IsEmptyLinklist(linklist_t list);

  26

  27 // 链表长度

  28 int LengthLinklist(linklist_t list);

  29

  30 // 获去链表节点数据

  31 int GetLinklist(linklist_t list, int at, data_t * x);

  32

  33 // 设置链表节点数据

  34 int SetLinklist(linklist_t list, int at, data_t x);

  35

  36 // 插入节点

  37 int InsertLinklist(linklist_t list, int at, data_t x);

  38

  39 // 删除节点

  40 int DeleteLinklist(linklist_t list, int at);

  41

  42 // 链表转置

  43 linklist_t ReverseLinklist(linklist_t list);

  44

  45 // 打印链表

  46 int Display(linklist_t list);

  47

  48

  49 #endif // _LIST_LINK_H_

  

  listlink.c

  

  1 #include

  2 #include

  3 #include "listlink.h"

  4

  5 // 创建一个空链表

  6 linklist_t

  7 CreateEmptyLinklist()

  8 {

  9 linklist_t list;

  10 list = (linklist_t)malloc(sizeof(linknode_t));

  11

  12 if(NULL != list) {

  13 list->next = NULL;

  14 }

  15

  16 return list;

  17 }

  18

  19 // 销毁链表

  20 void

  21 DestroyLinklist(linklist_t list)

  22 {

  23 if(NULL != list) {

  24 ClearLinklist(list);

  25 free(list);

  26 }

  27 }

  28

  29 // 清空链表

  30 void

  31 ClearLinklist(linklist_t list)

  32 {

  33 linknode_t * node; /* pointer to the node to be remove */

  34 if(NULL == list) return;

  35

  36 while(NULL != list->next) {

  37 node = list->next;

  38 list->next = node->next; //此时node->next是第二node节点元素依次往后

  39 free(node);

  40 }

  41 return;

  42 }

  43

  44 // 是否为空链表

  45 int

  46 IsEmptyLinklist(linklist_t list)

  47 {

  48 if(NULL != list) {

  49 if(NULL == list->next) // 只有头节点

  50 return 1; // 返回1,是个空链表

  51 else

  52 return 0; // 返回0,链表非空

  53

  54 } else

  55 return -1; // 返回-1, 错误的类型

  56 }

  57

  58 // 链表长度

  59 int

  60 LengthLinklist(linklist_t list)

  61 {

  62 int len = 0;

  63 linknode_t * node; // 遍历指针

  64

  65 if(NULL == list) return -1;

  66

  67 node = list->next; // node指针指向第一个节点

  68 while(NULL != node) {

  69 len++;

  70 node = node->next;

  71 }

  72

  73 return len;

  74 }

  75

  76 // 获去一个链表指定节点数据域的数据值

  77 int

  78 GetLinklist(linklist_t list, int at, data_t * x)

  79 {

  80 linknode_t *node; // 遍历节点的指针

  81 int pos; // 用于遍历比较

  82

  83 if(NULL == list) return -1;

  84 /*at 必须要 >= 0*/

  85 if(at < 0) return -1;

  86

  87 /* 从第一个元素开始 */

  88 node = list->next; // node指针指向一个元素

  89 pos = 0;

  90 while(NULL != node) {

  91 if(at == pos) {

  92 if(NULL != x)

  93 *x = node->data;

  94 return 0;

  95 }

  96 // 下一个元素

  97 node = node->next;

  98 pos++;

  99 }

  100 return -1;

  101 }

  102

  103 // 设置一个指定链表节点的数据域值

  104 int

  105 SetLinklist(linklist_t list, int at, data_t x)

  106 {

  107 linknode_t * node; // 遍历链表

  108 int pos;

  109 int found = 0;

  110

  111 if(!list) return -1;

  112 /*at 必须 >= 0*/

  113 if(at < 0) return -1;

  114

  115 /* node指针指向第一个元素 */

  116 node = list->next;

  117 pos = 0;

  118 while(NULL != node) {

  119 if(at == pos) {

  120 found = 1; // 找到了位置

  121 node->data = x;

  122 break;

  123 }

  124 /*往后移动元素*/

  125 node = node->next;

  126 pos++;

  127 }

  128 if(1 == found)

  129 return 0;

  130 else

  131 return -1;

  132 }

  133

  134 // 插入节点

  135 int

  136 InsertLinklist(linklist_t list, int at, data_t x)

  137 {

  138 /*

  139 * node_at and pos_at are used to locate the position of node_at.

  140 * node_prev follows the node_at and always points to previous node

  141 * of node_at.

  142 * node_new is used to point to the new node to be inserted.

  143 */

  144 linknode_t * node_prev, * node_at, * node_new;

  145 int pos_at;

  146 int found = 0;

  147

  148 if(NULL == list) return -1;

  149

  150 /* at 必须 >= 0 */

  151 if(at < 0) return -1;

  152

  153 node_new = malloc(sizeof(linknode_t));

  154 if(NULL == node_new)

  155 return -1;

  156 node_new->data = x; // assigned value

  157 node_new->next = NULL;

  158

  159 node_prev = list; // head

  160 node_at = list->next; //node_at指针指向第一元素

  161 pos_at = 0;

  162 while(NULL != node_at) {

  163 if(pos_at == at) {

  164 found = 1; // found the node ‘at'

  165 break;

  166 }

  167 /* move to the next pos_at */

  168 node_prev = node_at;

  169 node_at = node_at->next;

  170 pos_at++;

  171 }

  172

  173 if(found) {

  174 /* insert */

  175 node_new->next = node_at;

  176 node_prev->next = node_new;

  177 } else{

  178 /*

  179 * If not found,means the provided 'at'

  180 * exceeds the upper limit of the list, just

  181 * append the new node to the end of the list

  182 */

  183 node_prev->next = node_new;

  184 }

  185

  186 return 0;

  187 }

  188

  189 // 删除节点

  190 int

  191 DeleteLinklist(linklist_t list, int at)

  192 {

  193 /*

  194 * node_at and pos_at are used to locate the position of node_at.

  195 * node_prev follows the node_at and always points to previous node

  196 * of node_at.

  197 */

  198 linknode_t * node_prev, * node_at;

  199 int pos_at;

  200 int found = 0;

  201

  202 if(!list) return -1;

  203 if(at < 0) return -1;

  204

  205 node_prev = list; // node_prev指针指向链表头

  206 node_at = list->next; // node_at指针指向第一元素

  207 pos_at = 0;

  208

  209 while(NULL != node_at) {

  210 if(pos_at == at) {

  211 // found the node 'at'

  212 found = 1;

  213 break;

  214 }

  215 // move to the next pos_at

  216 node_prev = node_at;

  217 node_at = node_at->next;

  218 pos_at++;

  219 }

  220 if(found) {

  221 // remove

  222 node_prev->next = node_at->next;

  223 free(node_at);

  224 return 0;

  225 }else

  226 return -1;

  227 }

  228

  229 // 链表转置

  230 linklist_t

  231 ReverseLinklist(linklist_t list)

  232 {

  233 linknode_t * node; // iterator

  234 linknode_t * node_prev; // previous node of iterator

  235 linknode_t * node_next; /* next node of iterator

  236 * used to backup next of iterator

  237 */

  238 if(NULL == list) return NULL;

  239 node_prev = NULL;

  240 node = list->next; // node指针指向第一个元素

  241 while(NULL != node) {

  242 /*

  243 * step1: backup node->next

  244 * due to the next of iterator will be

  245 * modified in step2

  246 */

  247 node_next = node->next;

  248 /*

  249 * when iterator reaches the last node

  250 * of original list, make the list head

  251 * point to the last node, so the original

  252 * last one becomes the first one.

  253 */

  254 if(NULL == node_next)

  255 list->next = node;

  256 /*

  257 * step2: reverse the linkage between nodes

  258 * make the node pointer to the previous node,

  259 * not the next node

  260 */

  261 node->next = node_prev;

  262 /*

  263 * step3: move forward

  264 */

  265 node_prev = node;

  266 node = node_next;

  267 }

  268

  269 return list;

  270 }

  271

  272 // 打印链表

  273 int

  274 Display(linklist_t list)

  275 {

  276 linknode_t * node;

  277

  278 if(NULL == list) return -1;

  279

  280 node = list->next;

  281 while(node != NULL) {

  282 printf(" %d ", node->data);

  283 node = node->next;

  284 }

  285 printf("\n");

  286

  287 return 0;

  288 }

  289

  290

  291 int main(int argc, char * argv[])

  292 {

  293 int i;

  294 data_t x;

  295 linklist_t p;

  296

  297 /*创建链表*/

  298 p = CreateEmptyLinklist();

  299 Display(p);

  300 data_t a[10] = {1,3,5,7,9,11,13,15,17,19};

  301

  302 for(i = 0; i < 10; i++) {

  303 /*插入链表*/

  304 InsertLinklist(p, i, a[i]);

  305 }

  306 Display(p);

  307

  308 /*链表转置*/

  309 ReverseLinklist(p);

  310 /*链表长度*/

  311 printf("The length of the list is [%d]\n", LengthLinklist(p));

  312 Display(p);

  313

  314 /*获取特定节点值*/

  315 GetLinklist(p, 4, &x);

  316 printf("The No.4 of this list is [%d]\n", x);

  317

  318 /*设置特定节点的值*/

  319 SetLinklist(p, 4, 100);

  320 GetLinklist(p, 4, &x);

  321 printf("After updating! The No.4 of this list is [%d]\n", x);

  322 Display(p);

  323

  324 /*删除节点*/

  325 DeleteLinklist(p,5);

  326 printf("After delete!The length of list is [%d]\n", LengthLinklist(p));

  327 Display(p);

  328

  329 /*清空链表*/

  330 ClearLinklist(p);

  331 if(IsEmptyLinklist(p))

  332 printf("This list is empty!\n");

  333 /*销毁链表*/

  334 DestroyLinklist(p);

  335 printf("This list is destroyed!\n");

  336

  337

  338 return 0;

  339

  340 }
  1 #include

  2 #include

  3 #include "listlink.h"

  4

  5 // 创建一个空链表

  6 linklist_t

  7 CreateEmptyLinklist()

  8 {

  9 linklist_t list;

  10 list = (linklist_t)malloc(sizeof(linknode_t));

  11

  12 if(NULL != list) {

  13 list->next = NULL;

  14 }

  15

  16 return list;

  17 }

  18

  19 // 销毁链表

  20 void

  21 DestroyLinklist(linklist_t list)

  22 {

  23 if(NULL != list) {

  24 ClearLinklist(list);

  25 free(list);

  26 }

  27 }

  28

  29 // 清空链表

  30 void

  31 ClearLinklist(linklist_t list)

  32 {

  33 linknode_t * node; /* pointer to the node to be remove */

  34 if(NULL == list) return;

  35

  36 while(NULL != list->next) {

  37 node = list->next;

  38 list->next = node->next; //此时node->next是第二node节点元素依次往后

  39 free(node);

  40 }

  41 return;

  42 }

  43

  44 // 是否为空链表

  45 int

  46 IsEmptyLinklist(linklist_t list)

  47 {

  48 if(NULL != list) {

  49 if(NULL == list->next) // 只有头节点

  50 return 1; // 返回1,是个空链表

  51 else

  52 return 0; // 返回0,链表非空

  53

  54 } else

  55 return -1; // 返回-1, 错误的类型

  56 }

  57

  58 // 链表长度

  59 int

  60 LengthLinklist(linklist_t list)

  61 {

  62 int len = 0;

  63 linknode_t * node; // 遍历指针

  64

  65 if(NULL == list) return -1;

  66

  67 node = list->next; // node指针指向第一个节点

  68 while(NULL != node) {

  69 len++;

  70 node = node->next;

  71 }

  72

  73 return len;

  74 }

  75

  76 // 获去一个链表指定节点数据域的数据值

  77 int

  78 GetLinklist(linklist_t list, int at, data_t * x)

  79 {

  80 linknode_t *node; // 遍历节点的指针

  81 int pos; // 用于遍历比较

  82

  83 if(NULL == list) return -1;

  84 /*at 必须要 >= 0*/

  85 if(at < 0) return -1;

  86

  87 /* 从第一个元素开始 */

  88 node = list->next; // node指针指向一个元素

  89 pos = 0;

  90 while(NULL != node) {

  91 if(at == pos) {

  92 if(NULL != x)

  93 *x = node->data;

  94 return 0;

  95 }

  96 // 下一个元素

  97 node = node->next;

  98 pos++;

  99 }

  100 return -1;

  101 }

  102

  103 // 设置一个指定链表节点的数据域值

  104 int

  105 SetLinklist(linklist_t list, int at, data_t x)

  106 {

  107 linknode_t * node; // 遍历链表

  108 int pos;

  109 int found = 0;

  110

  111 if(!list) return -1;

  112 /*at 必须 >= 0*/

  113 if(at < 0) return -1;

  114

  115 /* node指针指向第一个元素 */

  116 node = list->next;

  117 pos = 0;

  118 while(NULL != node) {

  119 if(at == pos) {

  120 found = 1; // 找到了位置

  121 node->data = x;

  122 break;

  123 }

  124 /*往后移动元素*/

  125 node = node->next;

  126 pos++;

  127 }

  128 if(1 == found)

  129 return 0;

  130 else

  131 return -1;

  132 }

  133

  134 // 插入节点

  135 int

  136 InsertLinklist(linklist_t list, int at, data_t x)

  137 {

  138 /*

  139 * node_at and pos_at are used to locate the position of node_at.

  140 * node_prev follows the node_at and always points to previous node

  141 * of node_at.

  142 * node_new is used to point to the new node to be inserted.

  143 */

  144 linknode_t * node_prev, * node_at, * node_new;

  145 int pos_at;

  146 int found = 0;

  147

  148 if(NULL == list) return -1;

  149

  150 /* at 必须 >= 0 */

  151 if(at < 0) return -1;

  152

  153 node_new = malloc(sizeof(linknode_t));

  154 if(NULL == node_new)

  155 return -1;

  156 node_new->data = x; // assigned value

  157 node_new->next = NULL;

  158

  159 node_prev = list; // head

  160 node_at = list->next; //node_at指针指向第一元素

  161 pos_at = 0;

  162 while(NULL != node_at) {

  163 if(pos_at == at) {

  164 found = 1; // found the node ‘at'

  165 break;

  166 }

  167 /* move to the next pos_at */

  168 node_prev = node_at;

  169 node_at = node_at->next;

  170 pos_at++;

  171 }

  172

  173 if(found) {

  174 /* insert */

  175 node_new->next = node_at;

  176 node_prev->next = node_new;

  177 } else{

  178 /*

  179 * If not found,means the provided 'at'

  180 * exceeds the upper limit of the list, just

  181 * append the new node to the end of the list

  182 */

  183 node_prev->next = node_new;

  184 }

  185

  186 return 0;

  187 }

  188

  189 // 删除节点

  190 int

  191 DeleteLinklist(linklist_t list, int at)

  192 {

  193 /*

  194 * node_at and pos_at are used to locate the position of node_at.

  195 * node_prev follows the node_at and always points to previous node

  196 * of node_at.

  197 */

  198 linknode_t * node_prev, * node_at;

  199 int pos_at;

  200 int found = 0;

  201

  202 if(!list) return -1;

  203 if(at < 0) return -1;

  204

  205 node_prev = list; // node_prev指针指向链表头

  206 node_at = list->next; // node_at指针指向第一元素

  207 pos_at = 0;

  208

  209 while(NULL != node_at) {

  210 if(pos_at == at) {

  211 // found the node 'at'

  212 found = 1;

  213 break;

  214 }

  215 // move to the next pos_at

  216 node_prev = node_at;

  217 node_at = node_at->next;

  218 pos_at++;

  219 }

  220 if(found) {

  221 // remove

  222 node_prev->next = node_at->next;

  223 free(node_at);

  224 return 0;

  225 }else

  226 return -1;

  227 }

  228

  229 // 链表转置

  230 linklist_t

  231 ReverseLinklist(linklist_t list)

  232 {

  233 linknode_t * node; // iterator

  234 linknode_t * node_prev; // previous node of iterator

  235 linknode_t * node_next; /* next node of iterator

  236 * used to backup next of iterator

  237 */

  238 if(NULL == list) return NULL;

  239 node_prev = NULL;

  240 node = list->next; // node指针指向第一个元素

  241 while(NULL != node) {

  242 /*

  243 * step1: backup node->next

  244 * due to the next of iterator will be

  245 * modified in step2

  246 */

  247 node_next = node->next;

  248 /*

  249 * when iterator reaches the last node

  250 * of original list, make the list head

  251 * point to the last node, so the original

  252 * last one becomes the first one.

  253 */

  254 if(NULL == node_next)

  255 list->next = node;

  256 /*

  257 * step2: reverse the linkage between nodes

  258 * make the node pointer to the previous node,

  259 * not the next node

  260 */

  261 node->next = node_prev;

  262 /*

  263 * step3: move forward

  264 */

  265 node_prev = node;

  266 node = node_next;

  267 }

  268

  269 return list;

  270 }

  271

  272 // 打印链表

  273 int

  274 Display(linklist_t list)

  275 {

  276 linknode_t * node;

  277

  278 if(NULL == list) return -1;

  279

  280 node = list->next;

  281 while(node != NULL) {

  282 printf(" %d ", node->data);

  283 node = node->next;

  284 }

  285 printf("\n");

  286

  287 return 0;

  288 }

  289

  290

  291 int main(int argc, char * argv[])

  292 {

  293 int i;

  294 data_t x;

  295 linklist_t p;

  296

  297 /*创建链表*/

  298 p = CreateEmptyLinklist();

  299 Display(p);

  300 data_t a[10] = {1,3,5,7,9,11,13,15,17,19};

  301

  302 for(i = 0; i < 10; i++) {

  303 /*插入链表*/

  304 InsertLinklist(p, i, a[i]);

  305 }

  306 Display(p);

  307

  308 /*链表转置*/

  309 ReverseLinklist(p);

  310 /*链表长度*/

  311 printf("The length of the list is [%d]\n", LengthLinklist(p));

  312 Display(p);

  313

  314 /*获取特定节点值*/

  315 GetLinklist(p, 4, &x);

  316 printf("The No.4 of this list is [%d]\n", x);

  317

  318 /*设置特定节点的值*/

  319 SetLinklist(p, 4, 100);

  320 GetLinklist(p, 4, &x);

  321 printf("After updating! The No.4 of this list is [%d]\n", x);

  322 Display(p);

  323

  324 /*删除节点*/

  325 DeleteLinklist(p,5);

  326 printf("After delete!The length of list is [%d]\n", LengthLinklist(p));

  327 Display(p);

  328

  329 /*清空链表*/

  330 ClearLinklist(p);

  331 if(IsEmptyLinklist(p))

  332 printf("This list is empty!\n");

  333 /*销毁链表*/

  334 DestroyLinklist(p);

  335 printf("This list is destroyed!\n");

  336

  337

  338 return 0;

  339

  340 }

  运行

视频学习资料

单链表
http://www.makeru.com.cn/live/5413_1924.html?s=45051

循环链表及线性表的应用
http://www.makeru.com.cn/course/details/1902?s=45051

学习交流资料下载群:830802928

Linux C 数据结构 ->单向链表的更多相关文章

  1. Linux C 数据结构 ->单向链表<-(~千金散尽还复来~)

    之前看到一篇单向链表的博文,代码也看着很舒服,于是乎记录下来,留给自己~,循序渐进,慢慢 延伸到真正的内核链表~(敢问路在何方?路在脚下~) 1. 简介 链表是Linux 内核中最简单,最普通的数据结 ...

  2. linux内核数据结构之链表

    linux内核数据结构之链表 1.前言 最近写代码需用到链表结构,正好公共库有关于链表的.第一眼看时,觉得有点新鲜,和我之前见到的链表结构不一样,只有前驱和后继指针,而没有数据域.后来看代码注释发现该 ...

  3. linux内核数据结构之链表【转】

    转自:http://www.cnblogs.com/Anker/p/3475643.html 1.前言 最近写代码需用到链表结构,正好公共库有关于链表的.第一眼看时,觉得有点新鲜,和我之前见到的链表结 ...

  4. 数据结构-单向链表 C和C++的实现

    数据结构,一堆数据的存放方式. 今天我们学习数据结构中的 链表: 链表的结构: 链表是一种特殊的数组,它的每个元素称为节点,每个节点包括两个部分: 数据域:存放数据,此部分与数组相同 指针域:存放了下 ...

  5. python数据结构——单向链表

    链表 ( Linked List ) 定义:由许多相同数据类型的数据项按照特定顺序排列而成的线性表. 特点:各个数据在计算机中是随机存放且不连续. 优点:数据的增删改查都很方便,当有新的数据加入的时候 ...

  6. Python3玩转单链表——逆转单向链表pythonic版

    [本文出自天外归云的博客园] 链表是由节点构成的,一个指针代表一个方向,如果一个构成链表的节点都只包含一个指针,那么这个链表就是单向链表. 单向链表中的节点不光有代表方向的指针变量,也有值变量.所以我 ...

  7. 玩转C线性表和单向链表之Linux双向链表优化

    前言: 这次介绍基本数据结构的线性表和链表,并用C语言进行编写:建议最开始学数据结构时,用C语言:像栈和队列都可以用这两种数据结构来实现. 一.线性表基本介绍 1 概念: 线性表也就是关系户中最简单的 ...

  8. C# 单向链表数据结构 (一)

    单向链表数据结构是有节点组成,每个节点包含两部分,第一部分为存储数据,第二部分为指向下一个节点的指针.注意,有两个特色的节点,分别为“头节点”和“尾节点”,头节点本身没有数据,只存储下一个节点的指针, ...

  9. 数据结构(1) 第一天 算法时间复杂度、线性表介绍、动态数组搭建(仿Vector)、单向链表搭建、企业链表思路

    01 数据结构基本概念_大O表示法 无论n是多少都执行三个具体步骤 执行了12步 O(12)=>O(1) O(n) log 2 N = log c N / log c N (相当于两个对数进行了 ...

随机推荐

  1. Fastjson反序列化漏洞基础

    Fastjson反序列化漏洞基础 FastJson是alibaba的一款开源JSON解析库,可用于将Java对象转换为其JSON表示形式,也可以用于将JSON字符串转换为等效的Java对象. 0x0 ...

  2. ElasticSearch集成SpringData史上最全查询教程

    1.简单介绍 springboot 使用springdata操作es,ElasticsearchRepository使用QueryBuilder构造查询条件 2.集成es //maven集成 < ...

  3. Vmware 15 安装 win7 虚拟机 (初学者操作与详解教程)

    @ 目录 一.镜像下载 1.什么是镜像 2.常见的系统镜像文件格式 3.下载win7旗舰版镜像 二.VMware Workstation 下载 1.什么是虚拟机 2.VMware 主要功能 3.VMw ...

  4. PHP的内置WEB服务器

    在很多时候,我们需要简单的运行一个小 demo 来验证一些代码或者轮子是否可用,是否可以运行起来,但是去配 nginx 或者 apache 都很麻烦,其实,PHP CLI 已经提供了一个简单的测试服务 ...

  5. TP生成二维码插件

    安装 composer require endroid/qrcode 使用: use Endroid\QrCode\QrCode 然后 这个类库要改一下 在路径:你的项目路径\vendor\endro ...

  6. Docker系列(2)- Docker中的名词概念

    Docker工作流程 名词概念 镜像(image): docker镜像就好比一个模板,可以通过这个模板来创建容器服务,tomcat镜像===>run===>tomcat01(提供服务器) ...

  7. SpringBoot 整合 Elastic Stack 最新版本(7.14.1)分布式日志解决方案,开源微服务全栈项目【有来商城】的日志落地实践

    一. 前言 日志对于一个程序的重要程度不用过多的言语修饰,本篇将以实战的方式讲述开源微服务全栈项目 有来商城 是如何整合当下主流日志解决方案 ELK +Filebeat . 话不多说,先看实现的效果图 ...

  8. Jmeter线程组设置

    添加线程组:右键测试计划->添加->Threads->线程组 左侧树形标签栏中,显示标签信息. 选中线程组,右侧内容栏中显示线程组的相关信息. 名称:可以给线程组设置一个个性化的命名 ...

  9. 一文让你彻底理解SQL连接查询

    表结构 内连接 笛卡尔积问题 普通内连接:inner join on 隐式内连接: 外连接 内连接与外连接查询的区别 内连接查询是查询两张表交集的数据,主外键关联的数据. 左连接查询是查询左表中的所有 ...

  10. 7.JVM调优-方法区,堆,栈调优详解

    通常我们都知道在堆空间新生代Eden区满了,会触发minor GC, 在老年代满了会触发full GC, 触发full GC会导致Stop The World, 那你们知道还有一个区域满了一会触发Fu ...