C语言数据结构之双向链表(LIST)的实现

C语言数据结构之双向链表(LIST)的实现

  • 与单向链表相比,双向链表数据结构中多出一个指向链表前一个节点的节点指针prev!!!

双向链表数据类型的定义

  • 双向链表的创建 list_new
  • 双向链表的释放 list_free
  • 尾部追加 list_append
  • 头部追加 list_prepend
  • 逐项操作 list_foreach
  • 测试函数,字符串尾部追加结果:AAA BBB CCC DDD EEE
  • 字符串头部追加结果:EEE DDD CCC BBB AAA

代码如下:

c 复制代码
/* filename : list.c */
#include <stdio.h>
#include <stdlib.h>

/**/
typedef void (*LSFunc) (void *data);

/**/
typedef struct _ListNode ListNode;
struct _ListNode {
  void *data;
  ListNode *prev, *next;
};

/**/
ListNode *
list_node_new (void *data)
{
  ListNode *node = (ListNode*) malloc (sizeof(ListNode));
  node->data = data;
  node->prev = NULL;
  node->next = NULL;
  return node;
}

/**/
void
list_free (ListNode *node)
{
  ListNode *tmp = node;
  while (tmp->prev != NULL)
    tmp = tmp->prev;
  while (tmp != NULL)
    {
      ListNode *pnode = tmp->next;
      free (tmp);
      tmp = pnode;
    }
}

/**/
ListNode *
list_append (ListNode *head, void *data)
{
  ListNode *tmp = head, *node;
  while (tmp->next != NULL)
    tmp = tmp->next;
  node = list_node_new (data);
  node->prev = tmp;
  tmp->next = node;
  return head;
}

/**/
ListNode *
list_prepend (ListNode *head, void *data)
{
  ListNode *tmp = head, *node;
  while (tmp->prev != NULL)
    tmp = tmp->prev;
  node = list_node_new (data);
  node->next = tmp;
  tmp->prev = node;
  return node;
}

/**/
void
list_foreach (ListNode *node, LSFunc lsfunc)
{
  ListNode *tmp = node;
  while (tmp->prev != NULL)
    tmp = tmp->prev;
  while (tmp != NULL)
    {
      lsfunc (tmp->data);
      tmp = tmp->next;
    }
}

/* ---------------------------------------- */

/**/
void
out_string (void *data)
{
  printf ("%s ", (char*)data);
}

/**/
void
test_list_append (void)
{
  ListNode *ls;
  char *buf[5] = {"AAA", "BBB", "CCC", "DDD", "EEE"};

  ls = list_node_new (buf[0]);

  for (int i = 1; i < 5; i++)
    ls = list_append (ls, buf[i]);

  printf ("[ ");
  list_foreach (ls, out_string);
  printf ("]\n");

  list_free (ls);
}

/**/
void
test_list_prepend (void)
{
  ListNode *ls;
  char *buf[5] = {"AAA", "BBB", "CCC", "DDD", "EEE"};

  ls = list_node_new (buf[0]);

  for (int i = 1; i < 5; i++)
    ls = list_prepend (ls, buf[i]);

  printf ("[ ");
  list_foreach (ls, out_string);
  printf ("]\n");

  list_free (ls);
}

/**/
int
main (int argc, char *argv[])
{
  test_list_append ();
  test_list_prepend ();
  return 0;
}
/* --[<\|/>]-- */

编译运行,检查内存,情况如下:

bash 复制代码
songvm@ubuntu:~/works/xdn/loo$ gcc list.c -o list
songvm@ubuntu:~/works/xdn/loo$ ./list
[ AAA BBB CCC DDD EEE ]
[ EEE DDD CCC BBB AAA ]
songvm@ubuntu:~/works/xdn/loo$ valgrind --leak-check=yes ./list
==3688== Memcheck, a memory error detector
==3688== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==3688== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
==3688== Command: ./list
==3688== 
[ AAA BBB CCC DDD EEE ]
[ EEE DDD CCC BBB AAA ]
==3688== 
==3688== HEAP SUMMARY:
==3688==     in use at exit: 0 bytes in 0 blocks
==3688==   total heap usage: 11 allocs, 11 frees, 1,264 bytes allocated
==3688== 
==3688== All heap blocks were freed -- no leaks are possible
==3688== 
==3688== For counts of detected and suppressed errors, rerun with: -v
==3688== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
songvm@ubuntu:~/works/xdn/loo$ 

双向链表求长度LENGTH 插入INSERT

  • 双向链表求长度 list_length
  • 双向链表插入节点 list_insert

代码如下:

c 复制代码
/**/
int
list_length (ListNode *head)
{
  int len = 0;
  ListNode *tmp = head;
  while (tmp->prev != NULL)
    tmp = tmp->prev;
  while (tmp != NULL)
    {
      tmp = tmp->next;
      len++;
    }
  return len;
}

/**/
ListNode *
list_insert (ListNode *head, int nth, void *data)
{
  int idx = 0;
  ListNode *tmp = head;//, *node;
  while (tmp->prev != NULL)
    tmp = tmp->prev;
  while (tmp != NULL)
    {
      idx = idx + 1;
      if (idx == nth)
	{
	  ListNode *node = list_node_new (data);
	  node->next = tmp->next;
	  node->prev = tmp;
	  tmp->next = node;
	  break;
	}
      tmp = tmp->next; 
    }
  return head;
}
  • 测试函数,创建双向链表AAA BBB CCC DDD EEE,在第3个索引处插入XXXX,目标结果AAA BBB CCC XXXX DDD EEE

代码如下:

c 复制代码
/**/
void
test_list_insert (void)
{
  ListNode *ls;
  char *buf[6] = {"AAA", "BBB", "CCC", "DDD", "EEE", "XXXX"};

  ls = list_node_new (buf[0]);

  for (int i = 1; i < 5; i++)
    ls = list_append (ls, buf[i]);

  printf ("[ ");
  list_foreach (ls, out_string);
  printf ("]\n");

  printf ("List length is %d\n", list_length (ls));

  ls = list_insert (ls, 3, buf[5]);

  printf ("[ ");
  list_foreach (ls, out_string);
  printf ("]\n");

  printf ("List length is %d\n", list_length (ls));

  list_free (ls);
}

编译运行,结果如预期,输出如下:

bash 复制代码
songvm@ubuntu:~/works/xdn/loo$ gcc list.c -o list
songvm@ubuntu:~/works/xdn/loo$ ./list
[ AAA BBB CCC DDD EEE ]
List length is 5
[ AAA BBB CCC XXXX DDD EEE ]
List length is 6
songvm@ubuntu:~/works/xdn/loo$ 

双向链表的连接concat

  • 双向链表连接函数list_concat,将两个双向链表连接成为一个双向链表

代码如下:

c 复制代码
/**/
ListNode*
list_concat (ListNode *lsa, ListNode *lsb)
{
  ListNode *tmp = lsa, *node = lsb;
  while (tmp->next != NULL)
    tmp = tmp->next;
  while (node->prev != NULL)
    node = node->prev;
  tmp->next = node;
  node->prev = tmp;
  while (tmp->prev != NULL)
    tmp = tmp->prev;
  return tmp;
}
  • 测试将两个链表内容为:AAA BBB CCC DDD和XXX YYY ZZZ KKK,连接成为一个链表

代码如下:

c 复制代码
/**/
void
test_list_concat (void)
{
  char *bufa[4] = {"AAA", "BBB", "CCC", "DDD"};
  char *bufb[4] = {"XXX", "YYY", "ZZZ", "KKK"};
  ListNode *lna, *lnb, *lnx;

  lna = list_node_new (bufa[0]);
  for (int i = 1; i < 4; i++)
    lna = list_append (lna, bufa[i]);

  printf ("[ ");
  list_foreach (lna, out_string);
  printf ("]\n");

  lnb = list_node_new (bufb[0]);
  for (int i = 1; i < 4; i++)
    lnb = list_append (lnb, bufb[i]);

  printf ("[ ");
  list_foreach (lnb, out_string);
  printf ("]\n");

  lnx = list_concat (lna, lnb);

  printf ("[ ");
  list_foreach (lnx, out_string);
  printf ("]\n");

  list_free (lnx);
}

编译运行,检查内存,结果如下:

bash 复制代码
songvm@ubuntu:~/works/xdn/loo$ gcc list.c -o list
songvm@ubuntu:~/works/xdn/loo$ ./list
[ AAA BBB CCC DDD ]
[ XXX YYY ZZZ KKK ]
[ AAA BBB CCC DDD XXX YYY ZZZ KKK ]
songvm@ubuntu:~/works/xdn/loo$ valgrind --leak-check=yes ./list
==2951== Memcheck, a memory error detector
==2951== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==2951== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
==2951== Command: ./list
==2951== 
[ AAA BBB CCC DDD ]
[ XXX YYY ZZZ KKK ]
[ AAA BBB CCC DDD XXX YYY ZZZ KKK ]
==2951== 
==2951== HEAP SUMMARY:
==2951==     in use at exit: 0 bytes in 0 blocks
==2951==   total heap usage: 9 allocs, 9 frees, 1,216 bytes allocated
==2951== 
==2951== All heap blocks were freed -- no leaks are possible
==2951== 
==2951== For counts of detected and suppressed errors, rerun with: -v
==2951== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
songvm@ubuntu:~/works/xdn/loo$ 

双向链表倒转REVERSE 取链表头节点FIRST 取链表尾节点LAST

  • 双向链表倒转 list_reverse
  • 取链表头节点 list_first
  • 取链表尾节点 list_last

代码如下:

c 复制代码
/* list reverse tail to head */
ListNode*
list_reverse (ListNode *ls)
{
  ListNode *tmp = ls, *node = NULL;
  while (tmp->prev != NULL)
    tmp = tmp->prev;
  while (tmp != NULL)
    {
      ListNode *pn = tmp;
      tmp = tmp->next;
      pn->next = node;
      pn->prev = NULL;
      if (node != NULL)
	node->prev = pn;
      node = pn;
    }
  return node;
}

/* get list first node */
ListNode*
list_first (ListNode *ls)
{
  ListNode *tmp = ls;
  while (tmp->prev != NULL)
    tmp = tmp->prev;
  return tmp;
}

/* get list last node */
ListNode*
list_last (ListNode *ls)
{
  ListNode *tmp = ls;
  while (tmp->next != NULL)
    tmp = tmp->next;
  return tmp;
}
  • 测试函数,创建链表字符串AAA到HHH,倒转输出内容,再由尾部向前依次输出内容

代码如下:

c 复制代码
/**/
void
test_list_reverse (void)
{
  char *buf[8] = {"AAA", "BBB", "CCC", "DDD", "EEE", "FFF", "GGG", "HHH"};
  ListNode *ls;

  ls = list_node_new (buf[0]);
  for (int i = 1; i < 8; i++)
    ls = list_append (ls, buf[i]);

  printf ("[ ");
  list_foreach (ls, out_string);
  printf ("]\n");

  ls = list_reverse (ls);

  printf ("[ ");
  list_foreach (ls, out_string);
  printf ("]\n");

  {
    ListNode *tmp = ls;
    while (tmp->next != NULL)
      tmp = tmp->next;
    printf ("[ ");
    while (tmp != NULL)
      {
	printf ("%s ", (char*)(tmp->data));
	tmp = tmp->prev;
      }
    printf ("]\n");
  }
  list_free (ls);
}

编译运行,达到预期,效果如下:

bash 复制代码
songvm@ubuntu:~/works/xdn/loo$ gcc list.c -o list
songvm@ubuntu:~/works/xdn/loo$ ./list
[ AAA BBB CCC DDD EEE FFF GGG HHH ]
[ HHH GGG FFF EEE DDD CCC BBB AAA ]
[ AAA BBB CCC DDD EEE FFF GGG HHH ]
songvm@ubuntu:~/works/xdn/loo$ 

双向链表删除指定节点 REMOVE_NTH

  • 双向链表删除指定节点 list_remove_nth

代码如下:

c 复制代码
/**/
ListNode*
list_remove_nth (ListNode *ls, int nth)
{
  int idx = 0;
  ListNode *tmp = ls, *pn = ls;
  while (tmp->prev != NULL)
    tmp = tmp->prev;
  while (tmp != NULL)
    {
      if (idx == nth)
	{
	  if (idx == 0)
	    {
	      ls = tmp->next;
	      ls->prev = NULL;
	      free (tmp);
	      break;
	    }
	  pn->next = tmp->next;
	  tmp->next->prev = pn;
	  free (tmp);
	  break;
	}
      idx = idx + 1;
      pn = tmp;
      tmp = tmp->next;
    }
  return ls;
}
  • 测试函数,创建链表,删除第1第2节点,输出链表内容

代码如下:

c 复制代码
/**/
void
test_list_remove (void)
{
  char *txt[5] = {"AAAA", "BBBB", "CCCC", "DDDD", "EEEE"};
  ListNode *ls;

  ls = list_node_new (txt[0]);
  for (int i = 1; i < 5; i++)
    ls = list_append (ls, txt[i]);

  list_foreach (ls, out_string); printf ("\n");

  ls = list_remove_nth (ls, 1);
  ls = list_remove_nth (ls, 2);

  list_foreach (ls, out_string); printf ("\n");
  list_free (ls);
}

编译运行,达到预期,效果如下:

bash 复制代码
songvm@ubuntu:~/works/xdn/loo$ gcc list.c -o list
songvm@ubuntu:~/works/xdn/loo$ ./list
AAAA BBBB CCCC DDDD EEEE 
AAAA CCCC EEEE 
songvm@ubuntu:~/works/xdn/loo$ 

判断链表是否为循环链表

判断链表是否为循环链表is_round

代码如下:

c 复制代码
/* if list is a round return 1 else return 0 */
int
list_isround (ListNode *ls)
{
  ListNode *tmp = ls;
  while (tmp != NULL)
    {
      ListNode *node = tmp->next;
      if (ls == node) return 1;
      tmp = node;
    }
  return 0;
}
  • 测试函数,创建链表,取尾节点,尾节点next指针指向头节点,头节点的prev指针指向尾节点,形成循环链表

代码如下:

c 复制代码
/**/
void
test_list_round (void)
{
  char *txt[5] = {"AAAA", "BBBB", "CCCC", "DDDD", "EEEE"};
  ListNode *head, *tail;
  head = list_node_new (txt[0]);
  for (int i = 1; i < 5; i++)
    head = list_append (head, txt[i]);

  tail = list_last (head);
  tail->next = head; //link round
  head->prev = tail; //link round

  if (list_isround (head))
    printf ("Double list is round!\n");
  else
    printf ("Double list not round!\n");

  tail->next = NULL; //cut round
  head->prev = NULL; //cut round

  if (list_isround (head))
    printf ("Double list is round!\n");
  else
    printf ("Double list not round!\n");

  list_free (head);
}

编译运行,达到预期效果,输出如下:

bash 复制代码
songvm@ubuntu:~/works/xdn/loo$ gcc list.c -o list
songvm@ubuntu:~/works/xdn/loo$ ./list
Double list is round!
Double list not round!
songvm@ubuntu:~/works/xdn/loo$ 

完整代码如下:

c 复制代码
/* filename : list.c */
#include <stdio.h>
#include <stdlib.h>

/* compile : gcc list.c -o list */
/*     run : ./list             */

/* define function pointer for list foreach */
typedef void (*LSFunc) (void *data);

/* define ListNode datatype */
typedef struct _ListNode ListNode;
struct _ListNode {
  void *data;
  ListNode *prev, *next;
};

/* create a ListNode with data */
ListNode *
list_node_new (void *data)
{
  ListNode *node = (ListNode*) malloc (sizeof(ListNode));
  node->data = data;
  node->prev = NULL;
  node->next = NULL;
  return node;
}

/* free a list, from head to tail every node */
void
list_free (ListNode *node)
{
  ListNode *tmp = node;
  while (tmp->prev != NULL)
    tmp = tmp->prev;
  while (tmp != NULL)
    {
      ListNode *pnode = tmp->next;
      free (tmp);
      tmp = pnode;
    }
}

/* append a ListNode with data to head */
ListNode *
list_append (ListNode *head, void *data)
{
  ListNode *tmp = head, *node;
  while (tmp->next != NULL)
    tmp = tmp->next;
  node = list_node_new (data);
  node->prev = tmp;
  tmp->next = node;
  return head;
}

/* prev append a ListNode with data to head */
ListNode *
list_prepend (ListNode *head, void *data)
{
  ListNode *tmp = head, *node;
  while (tmp->prev != NULL)
    tmp = tmp->prev;
  node = list_node_new (data);
  node->next = tmp;
  tmp->prev = node;
  return node;
}

/* foreach listnode run lsfunc for data */
void
list_foreach (ListNode *node, LSFunc lsfunc)
{
  ListNode *tmp = node;
  while (tmp->prev != NULL)
    tmp = tmp->prev;
  while (tmp != NULL)
    {
      lsfunc (tmp->data);
      tmp = tmp->next;
    }
}

/* get list length */
int
list_length (ListNode *head)
{
  int len = 0;
  ListNode *tmp = head;
  while (tmp->prev != NULL)
    tmp = tmp->prev;
  while (tmp != NULL)
    {
      tmp = tmp->next;
      len++;
    }
  return len;
}

/* insert a ListNode with data at nth in head */
ListNode *
list_insert (ListNode *head, int nth, void *data)
{
  int idx = 0;
  ListNode *tmp = head;//, *node;
  while (tmp->prev != NULL)
    tmp = tmp->prev;
  while (tmp != NULL)
    {
      idx = idx + 1;
      if (idx == nth)
	{
	  ListNode *node = list_node_new (data);
	  node->next = tmp->next;
	  node->prev = tmp;
	  tmp->next = node;
	  break;
	}
      tmp = tmp->next; 
    }
  return head;
}

/* concat lsa and lsb and return a new ListNode pointer */
ListNode*
list_concat (ListNode *lsa, ListNode *lsb)
{
  ListNode *tmp = lsa, *node = lsb;
  while (tmp->next != NULL)
    tmp = tmp->next;
  while (node->prev != NULL)
    node = node->prev;
  tmp->next = node;
  node->prev = tmp;
  while (tmp->prev != NULL)
    tmp = tmp->prev;
  return tmp;
}

/* list reverse tail to head */
ListNode*
list_reverse (ListNode *ls)
{
  ListNode *tmp = ls, *node = NULL;
  while (tmp->prev != NULL)
    tmp = tmp->prev;
  while (tmp != NULL)
    {
      ListNode *pn = tmp;
      tmp = tmp->next;
      pn->next = node;
      pn->prev = NULL;
      if (node != NULL)
	node->prev = pn;
      node = pn;
    }
  return node;
}

/* get list first node */
ListNode*
list_first (ListNode *ls)
{
  ListNode *tmp = ls;
  while (tmp->prev != NULL)
    tmp = tmp->prev;
  return tmp;
}

/* get list last node */
ListNode*
list_last (ListNode *ls)
{
  ListNode *tmp = ls;
  while (tmp->next != NULL)
    tmp = tmp->next;
  return tmp;
}

/**/
ListNode*
list_remove_nth (ListNode *ls, int nth)
{
  int idx = 0;
  ListNode *tmp = ls, *pn = ls;
  while (tmp->prev != NULL)
    tmp = tmp->prev;
  while (tmp != NULL)
    {
      if (idx == nth)
	{
	  if (idx == 0)
	    {
	      ls = tmp->next;
	      ls->prev = NULL;
	      free (tmp);
	      break;
	    }
	  pn->next = tmp->next;
	  tmp->next->prev = pn;
	  free (tmp);
	  break;
	}
      idx = idx + 1;
      pn = tmp;
      tmp = tmp->next;
    }
  return ls;
}

/* if list is a round return 1 else return 0 */
int
list_isround (ListNode *ls)
{
  ListNode *tmp = ls;
  while (tmp != NULL)
    {
      ListNode *node = tmp->next;
      if (ls == node) return 1;
      tmp = node;
    }
  return 0;
}

/* ---------------------------------------- */

/**/
void
out_string (void *data)
{
  printf ("%s ", (char*)data);
}

/**/
void
test_list_append (void)
{
  ListNode *ls;
  char *buf[5] = {"AAA", "BBB", "CCC", "DDD", "EEE"};

  ls = list_node_new (buf[0]);

  for (int i = 1; i < 5; i++)
    ls = list_append (ls, buf[i]);

  printf ("[ ");
  list_foreach (ls, out_string);
  printf ("]\n");

  list_free (ls);
}

/**/
void
test_list_prepend (void)
{
  ListNode *ls;
  char *buf[5] = {"AAA", "BBB", "CCC", "DDD", "EEE"};

  ls = list_node_new (buf[0]);

  for (int i = 1; i < 5; i++)
    ls = list_prepend (ls, buf[i]);

  printf ("[ ");
  list_foreach (ls, out_string);
  printf ("]\n");

  list_free (ls);
}

/**/
void
test_list_insert (void)
{
  ListNode *ls;
  char *buf[6] = {"AAA", "BBB", "CCC", "DDD", "EEE", "XXXX"};

  ls = list_node_new (buf[0]);

  for (int i = 1; i < 5; i++)
    ls = list_append (ls, buf[i]);

  printf ("[ ");
  list_foreach (ls, out_string);
  printf ("]\n");

  printf ("List length is %d\n", list_length (ls));

  ls = list_insert (ls, 3, buf[5]);

  printf ("[ ");
  list_foreach (ls, out_string);
  printf ("]\n");

  printf ("List length is %d\n", list_length (ls));

  list_free (ls);
}

/**/
void
test_list_concat (void)
{
  char *bufa[4] = {"AAA", "BBB", "CCC", "DDD"};
  char *bufb[4] = {"XXX", "YYY", "ZZZ", "KKK"};
  ListNode *lna, *lnb, *lnx;

  lna = list_node_new (bufa[0]);
  for (int i = 1; i < 4; i++)
    lna = list_append (lna, bufa[i]);

  printf ("[ ");
  list_foreach (lna, out_string);
  printf ("]\n");

  lnb = list_node_new (bufb[0]);
  for (int i = 1; i < 4; i++)
    lnb = list_append (lnb, bufb[i]);

  printf ("[ ");
  list_foreach (lnb, out_string);
  printf ("]\n");

  lnx = list_concat (lna, lnb);

  printf ("[ ");
  list_foreach (lnx, out_string);
  printf ("]\n");

  list_free (lnx);
}

/**/
void
test_list_reverse (void)
{
  char *buf[8] = {"AAA", "BBB", "CCC", "DDD", "EEE", "FFF", "GGG", "HHH"};
  ListNode *ls;

  ls = list_node_new (buf[0]);
  for (int i = 1; i < 8; i++)
    ls = list_append (ls, buf[i]);

  printf ("[ ");
  list_foreach (ls, out_string);
  printf ("]\n");

  ls = list_reverse (ls);

  printf ("[ ");
  list_foreach (ls, out_string);
  printf ("]\n");

  {
    ListNode *tmp = ls;
    while (tmp->next != NULL)
      tmp = tmp->next;
    printf ("[ ");
    while (tmp != NULL)
      {
	printf ("%s ", (char*)(tmp->data));
	tmp = tmp->prev;
      }
    printf ("]\n");
  }
  list_free (ls);
}

/**/
void
test_list_remove (void)
{
  char *txt[5] = {"AAAA", "BBBB", "CCCC", "DDDD", "EEEE"};
  ListNode *ls;

  ls = list_node_new (txt[0]);
  for (int i = 1; i < 5; i++)
    ls = list_append (ls, txt[i]);

  list_foreach (ls, out_string); printf ("\n");

  ls = list_remove_nth (ls, 1);
  ls = list_remove_nth (ls, 2);

  list_foreach (ls, out_string); printf ("\n");
  list_free (ls);
}

/**/
void
test_list_round (void)
{
  char *txt[5] = {"AAAA", "BBBB", "CCCC", "DDDD", "EEEE"};
  ListNode *head, *tail;
  head = list_node_new (txt[0]);
  for (int i = 1; i < 5; i++)
    head = list_append (head, txt[i]);

  tail = list_last (head);
  tail->next = head; //link round
  head->prev = tail; //link round

  if (list_isround (head))
    printf ("Double list is round!\n");
  else
    printf ("Double list not round!\n");

  tail->next = NULL; //cut round
  head->prev = NULL; //cut round

  if (list_isround (head))
    printf ("Double list is round!\n");
  else
    printf ("Double list not round!\n");

  list_free (head);
}

/**/
int
main (int argc, char *argv[])
{
  //test_list_append ();
  //test_list_prepend ();
  //test_list_insert ();
  //test_list_concat ();
  //test_list_reverse ();
  //test_list_remove ();
  test_list_round ();
  return 0;
}
/* --[<\|/>]-- */

下一步研究栈(Stack)数据结构!!!

相关推荐
canyuemanyue4 分钟前
C++单例模式
开发语言·c++·单例模式
Renas_TJOvO9 分钟前
排序算法汇总
java·数据结构·算法
Stardep10 分钟前
算法2—八大常用排序算法(下)
c语言·数据结构·笔记·算法·排序算法·1024程序员节
秋恬意19 分钟前
Java 反射机制详解
java·开发语言
我就说好玩21 分钟前
使用C语言实现经典贪吃蛇游戏
c语言·vscode·游戏
黑不溜秋的22 分钟前
C++ 模板专题 - 标签分派(Tag Dispatching)
开发语言·c++·算法
爱上语文27 分钟前
LeetCode每日一题
java·算法·leetcode
skywind32 分钟前
为什么 C 语言数组是从 0 开始计数的?
c语言·开发语言·网络·c++
ProcedureStone38 分钟前
【算法】排序算法总结
c++·算法·排序算法