当前位置:   article > 正文

【海贼王的数据航海:利用数据结构成为数据海洋的霸主】链表—单链表

【海贼王的数据航海:利用数据结构成为数据海洋的霸主】链表—单链表

目录

1 -> 链表

1.1 -> 链表的概念及结构

1.2 -> 链表的分类

2 -> 无头+单向+非循环链表(单链表)

2.1 -> 接口声明

2.2 -> 接口实现

2.2.1 -> 动态申请一个结点

2.2.2 -> 单链表的打印

2.2.3 -> 单链表的尾插

2.2.4 -> 单链表的头插

2.2.5 -> 单链表的尾删

2.2.6 -> 单链表的头删

2.2.7 -> 单链表的查找

2.2.8 -> 单链表在pos位置之前插入x

2.2.9 -> 单链表在pos位置之后插入x

2.2.10 -> 单链表删除pos位置的值

2.2.11 -> 单链表删除pos位置之后的值

2.3 -> 完整代码

2.3.1 -> SList.h

2.3.2 -> SList.c

2.3.3 -> Test.c


1 -> 链表

1.1 -> 链表的概念及结构

概念:链表是一种物理存储结构上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的。

现实中 数据结构中

 注意:

  1. 上图可看出,链式结构在逻辑上是连续的,但是在物理上不一定连续;
  2. 现实中的结点一般都是从堆上申请出来的;
  3. 从堆上申请的空间,是按照一定策略分配的,两次申请的空间可能连续,也可能不连续。

假设在32位系统上,结点中值域为int类型,则一个节点的大小为8个字节,则也可能有以下链表:

1.2 -> 链表的分类

实际中链表的结构非常多样,以下情况组合起来就有八种链表结构:

1. 单向或双向

2. 带头或不带头

3. 循环或非循环

虽然有很多链表结构,但最常用的还是这两种:

1. 无头单向非循环链表

2. 带头双向循环链表

1. 无头单向非循环链表:结构简单,一般不会单独用来存储数据。实际中更多是作为其他数据结构的子结构,如哈希桶、图的邻接表等。

2. 带头双向循环链表:结构最复杂,一般用在单独存储数据。实际中使用的链表数据结构,都是带头双向循环链表。另外这个结构虽然复杂,但是使用代码实现以后会发现结构会带来很多优势,实现反而简单了。

2 -> 无头+单向+非循环链表(单链表)

2.1 -> 接口声明

  1. #pragma once
  2. #define _CRT_SECURE_NO_WARNINGS 1
  3. #include <stdio.h>
  4. #include <stdlib.h>
  5. #include <assert.h>
  6. // 无头+单向+非循环链表增删查改实现
  7. typedef int SLTDateType;
  8. typedef struct SLTNode
  9. {
  10. SLTDateType data;
  11. struct SLTNode* next;
  12. }SLTNode;
  13. // 动态申请一个结点
  14. SLTNode* BuySLTNode(SLTDateType x);
  15. // 单链表打印
  16. void SLTPrint(SLTNode* phead);
  17. // 单链表尾插
  18. void SLTPushBack(SLTNode** pphead, SLTDateType x);
  19. // 单链表的头插
  20. void SLTPushFront(SLTNode** pphead, SLTDateType x);
  21. // 单链表的尾删
  22. void SLTPopBack(SLTNode** pphead);
  23. // 单链表头删
  24. void SLTPopFront(SLTNode** pphead);
  25. // 单链表查找
  26. SLTNode* SLTFind(SLTNode* phead, SLTDateType x);
  27. // 单链表在pos位置之前插入x
  28. void SLTInsert(SLTNode** pphead, SLTNode* pos, SLTDateType x);
  29. // 单链表在pos位置之后插入x
  30. void SLTInsertAfter(SLTNode* pos, SLTDateType x);
  31. // 单链表删除pos位置的值
  32. void SLTErase(SLTNode** pphead, SLTNode* pos);
  33. // 单链表删除pos位置之后的值
  34. void SLTEraseAfter(SLTNode* pos);

2.2 -> 接口实现

2.2.1 -> 动态申请一个结点

  1. // 动态申请一个结点
  2. SLTNode* BuySLTNode(SLTDateType x)
  3. {
  4. SLTNode* newnode = (SLTNode*)malloc(sizeof(SLTNode));
  5. if (newnode == NULL)
  6. {
  7. perror("malloc fail");
  8. return NULL;
  9. }
  10. newnode->data = x;
  11. newnode->next = NULL;
  12. return newnode;
  13. }

2.2.2 -> 单链表的打印

  1. // 单链表的打印
  2. void SLTPrint(SLTNode* phead)
  3. {
  4. SLTNode* cur = phead;
  5. while (cur != NULL)
  6. {
  7. printf("%d->", cur->data);
  8. cur = cur->next;
  9. }
  10. printf("NULL\n");
  11. }

2.2.3 -> 单链表的尾插

  1. // 单链表的尾插
  2. void SLTPushBack(SLTNode** pphead, SLTDateType x)
  3. {
  4. assert(pphead);
  5. SLTNode* newnode = BuySLTNode(x);
  6. if (*pphead == NULL)
  7. {
  8. *pphead = newnode;
  9. }
  10. else
  11. {
  12. SLTNode* cur = *pphead;
  13. while (cur->next != NULL)
  14. {
  15. cur = cur->next;
  16. }
  17. cur->next = newnode;
  18. }
  19. }
  1. // 尾插测试
  2. void SLTTest1()
  3. {
  4. SLTNode* plist = NULL;
  5. SLTPushBack(&plist, 1);
  6. SLTPushBack(&plist, 2);
  7. SLTPushBack(&plist, 3);
  8. SLTPushBack(&plist, 4);
  9. SLTPrint(plist);
  10. }

2.2.4 -> 单链表的头插

  1. // 单链表的头插
  2. void SLTPushFront(SLTNode** pphead, SLTDateType x)
  3. {
  4. assert(pphead);
  5. SLTNode* newnode = BuySLTNode(x);
  6. newnode->next = *pphead;
  7. *pphead = newnode;
  8. }
  1. // 头插测试
  2. void SLTTest2()
  3. {
  4. SLTNode* plist = NULL;
  5. SLTPushFront(&plist, 1);
  6. SLTPushFront(&plist, 2);
  7. SLTPushFront(&plist, 3);
  8. SLTPushFront(&plist, 4);
  9. SLTPrint(plist);
  10. }

2.2.5 -> 单链表的尾删

  1. // 单链表的尾删
  2. void SLTPopBack(SLTNode** pphead)
  3. {
  4. assert(pphead);
  5. assert(*pphead); // 暴力检查
  6. 温柔的检查
  7. //if (*pphead == NULL)
  8. //{
  9. // return;
  10. //}
  11. // 只有一个节点
  12. if ((*pphead)->next == NULL)
  13. {
  14. free(*pphead);
  15. *pphead = NULL;
  16. }
  17. // 有多个节点
  18. else
  19. {
  20. SLTNode* prev = *pphead;
  21. SLTNode* tail = *pphead;
  22. while (tail->next != NULL)
  23. {
  24. prev = tail;
  25. tail = tail->next;
  26. }
  27. free(tail);
  28. tail = NULL;
  29. prev->next = NULL;
  30. }
  31. }
  1. // 尾删测试
  2. void SLTTest3()
  3. {
  4. SLTNode* plist = NULL;
  5. SLTPushBack(&plist, 1);
  6. SLTPushBack(&plist, 2);
  7. SLTPushBack(&plist, 3);
  8. SLTPushBack(&plist, 4);
  9. SLTPrint(plist);
  10. SLTPopBack(&plist);
  11. SLTPrint(plist);
  12. SLTPopBack(&plist);
  13. SLTPrint(plist);
  14. SLTPopBack(&plist);
  15. SLTPrint(plist);
  16. SLTPopBack(&plist);
  17. SLTPrint(plist);
  18. }

2.2.6 -> 单链表的头删

  1. // 单链表的头删
  2. void SLTPopFront(SLTNode** pphead)
  3. {
  4. assert(*pphead);
  5. SLTNode* tail = *pphead;
  6. *pphead = (*pphead)->next;
  7. free(tail);
  8. tail = NULL;
  9. }
  1. // 头删测试
  2. void SLTTest4()
  3. {
  4. SLTNode* plist = NULL;
  5. SLTPushBack(&plist, 1);
  6. SLTPushBack(&plist, 2);
  7. SLTPushBack(&plist, 3);
  8. SLTPushBack(&plist, 4);
  9. SLTPrint(plist);
  10. SLTPopFront(&plist);
  11. SLTPrint(plist);
  12. SLTPopFront(&plist);
  13. SLTPrint(plist);
  14. SLTPopFront(&plist);
  15. SLTPrint(plist);
  16. SLTPopFront(&plist);
  17. SLTPrint(plist);
  18. }

2.2.7 -> 单链表的查找

  1. // 单链表的查找
  2. SLTNode* SLTFind(SLTNode* phead, SLTDateType x)
  3. {
  4. SLTNode* ptr = phead;
  5. while (ptr->next != NULL)
  6. {
  7. if (ptr->data == x)
  8. {
  9. return ptr;
  10. }
  11. else
  12. {
  13. ptr = ptr->next;
  14. }
  15. }
  16. return NULL;
  17. }
  1. // 查找测试
  2. void SLTTest5()
  3. {
  4. SLTNode* plist = NULL;
  5. SLTPushBack(&plist, 1);
  6. SLTPushBack(&plist, 2);
  7. SLTPushBack(&plist, 3);
  8. SLTPushBack(&plist, 4);
  9. SLTPrint(plist);
  10. SLTNode* ans = SLTFind(plist, 1);
  11. if (ans)
  12. ans->data = 10;
  13. SLTPrint(plist);
  14. }

2.2.8 -> 单链表在pos位置之前插入x

  1. // 单链表在pos位置之前插入x
  2. void SLTInsert(SLTNode** pphead, SLTNode* pos, SLTDateType x)
  3. {
  4. assert(pphead);
  5. assert(pos);
  6. if (pos == *pphead)
  7. {
  8. SLTPushFront(pphead, x);
  9. }
  10. else
  11. {
  12. SLTNode* newnode = BuySLTNode(x);
  13. SLTNode* prev = *pphead;
  14. while (prev->next != pos)
  15. {
  16. prev = prev->next;
  17. }
  18. prev->next = newnode;
  19. newnode->next = pos;
  20. }
  21. }
  1. // 在pos位置之前插入x测试
  2. void SLTTest6()
  3. {
  4. SLTNode* plist = NULL;
  5. SLTPushBack(&plist, 1);
  6. SLTPushBack(&plist, 2);
  7. SLTPushBack(&plist, 3);
  8. SLTPushBack(&plist, 4);
  9. SLTPrint(plist);
  10. SLTNode* pos = SLTFind(plist, 2);
  11. if (pos)
  12. SLTInsert(&plist, pos, 99);
  13. SLTPrint(plist);
  14. }

2.2.9 -> 单链表在pos位置之后插入x

  1. // 单链表在pos位置之后插入x
  2. void SLTInsertAfter(SLTNode* pos, SLTDateType x)
  3. {
  4. assert(pos);
  5. SLTNode* newnode = BuySLTNode(x);
  6. SLTNode* tmp = pos->next;
  7. pos->next = newnode;
  8. newnode->next = tmp;
  9. }
  1. // 在pos位置之后插入x测试
  2. void SLTTest7()
  3. {
  4. SLTNode* plist = NULL;
  5. SLTPushBack(&plist, 1);
  6. SLTPushBack(&plist, 2);
  7. SLTPushBack(&plist, 3);
  8. SLTPushBack(&plist, 4);
  9. SLTPrint(plist);
  10. SLTNode* pos = SLTFind(plist, 2);
  11. if (pos)
  12. SLTInsertAfter(pos, 99);
  13. SLTPrint(plist);
  14. }

2.2.10 -> 单链表删除pos位置的值

  1. // 单链表删除pos位置的值
  2. void SLTErase(SLTNode** pphead, SLTNode* pos)
  3. {
  4. assert(pphead);
  5. assert(*pphead);
  6. assert(pos);
  7. if (pos == *pphead)
  8. {
  9. SLTPopFront(pphead);
  10. }
  11. else
  12. {
  13. SLTNode* prev = *pphead;
  14. if (prev->next != pos)
  15. {
  16. prev = prev->next;
  17. }
  18. prev->next = pos->next;
  19. free(pos);
  20. pos = NULL;
  21. }
  22. }
  1. // 删除pos位置的值测试
  2. void SLTTest8()
  3. {
  4. SLTNode* plist = NULL;
  5. SLTPushBack(&plist, 1);
  6. SLTPushBack(&plist, 2);
  7. SLTPushBack(&plist, 3);
  8. SLTPushBack(&plist, 4);
  9. SLTPrint(plist);
  10. SLTNode* pos = SLTFind(plist, 2);
  11. if (pos)
  12. SLTErase(&plist, pos);
  13. SLTPrint(plist);
  14. }

2.2.11 -> 单链表删除pos位置之后的值

  1. // 单链表删除pos位置之后的值
  2. void SLTEraseAfter(SLTNode* pos)
  3. {
  4. assert(pos);
  5. assert(pos->next);
  6. SLTNode* tmp = pos->next->next;
  7. free(pos->next);
  8. pos->next = tmp;
  9. }
  1. // 删除pos位置之后的值测试
  2. void SLTTest9()
  3. {
  4. SLTNode* plist = NULL;
  5. SLTPushBack(&plist, 1);
  6. SLTPushBack(&plist, 2);
  7. SLTPushBack(&plist, 3);
  8. SLTPushBack(&plist, 4);
  9. SLTPrint(plist);
  10. SLTNode* pos = SLTFind(plist, 2);
  11. if (pos)
  12. SLTEraseAfter(pos);
  13. SLTPrint(plist);
  14. }

2.3 -> 完整代码

2.3.1 -> SList.h

  1. #pragma once
  2. #define _CRT_SECURE_NO_WARNINGS 1
  3. #include <stdio.h>
  4. #include <stdlib.h>
  5. #include <assert.h>
  6. // 无头+单向+非循环链表增删查改实现
  7. typedef int SLTDateType;
  8. typedef struct SLTNode
  9. {
  10. SLTDateType data;
  11. struct SLTNode* next;
  12. }SLTNode;
  13. // 动态申请一个结点
  14. SLTNode* BuySLTNode(SLTDateType x);
  15. // 单链表打印
  16. void SLTPrint(SLTNode* phead);
  17. // 单链表尾插
  18. void SLTPushBack(SLTNode** pphead, SLTDateType x);
  19. // 单链表的头插
  20. void SLTPushFront(SLTNode** pphead, SLTDateType x);
  21. // 单链表的尾删
  22. void SLTPopBack(SLTNode** pphead);
  23. // 单链表头删
  24. void SLTPopFront(SLTNode** pphead);
  25. // 单链表查找
  26. SLTNode* SLTFind(SLTNode* phead, SLTDateType x);
  27. // 单链表在pos位置之前插入x
  28. void SLTInsert(SLTNode** pphead, SLTNode* pos, SLTDateType x);
  29. // 单链表在pos位置之后插入x
  30. void SLTInsertAfter(SLTNode* pos, SLTDateType x);
  31. // 单链表删除pos位置的值
  32. void SLTErase(SLTNode** pphead, SLTNode* pos);
  33. // 单链表删除pos位置之后的值
  34. void SLTEraseAfter(SLTNode* pos);

2.3.2 -> SList.c

  1. #include "SList.h"
  2. // 动态申请一个结点
  3. SLTNode* BuySLTNode(SLTDateType x)
  4. {
  5. SLTNode* newnode = (SLTNode*)malloc(sizeof(SLTNode));
  6. if (newnode == NULL)
  7. {
  8. perror("malloc fail");
  9. return NULL;
  10. }
  11. newnode->data = x;
  12. newnode->next = NULL;
  13. return newnode;
  14. }
  15. // 单链表的打印
  16. void SLTPrint(SLTNode* phead)
  17. {
  18. SLTNode* cur = phead;
  19. while (cur != NULL)
  20. {
  21. printf("%d->", cur->data);
  22. cur = cur->next;
  23. }
  24. printf("NULL\n");
  25. }
  26. // 单链表的尾插
  27. void SLTPushBack(SLTNode** pphead, SLTDateType x)
  28. {
  29. assert(pphead);
  30. SLTNode* newnode = BuySLTNode(x);
  31. if (*pphead == NULL)
  32. {
  33. *pphead = newnode;
  34. }
  35. else
  36. {
  37. SLTNode* cur = *pphead;
  38. while (cur->next != NULL)
  39. {
  40. cur = cur->next;
  41. }
  42. cur->next = newnode;
  43. }
  44. }
  45. // 单链表的头插
  46. void SLTPushFront(SLTNode** pphead, SLTDateType x)
  47. {
  48. assert(pphead);
  49. SLTNode* newnode = BuySLTNode(x);
  50. newnode->next = *pphead;
  51. *pphead = newnode;
  52. }
  53. // 单链表的尾删
  54. void SLTPopBack(SLTNode** pphead)
  55. {
  56. assert(pphead);
  57. assert(*pphead); // 暴力检查
  58. 温柔的检查
  59. //if (*pphead == NULL)
  60. //{
  61. // return;
  62. //}
  63. // 只有一个节点
  64. if ((*pphead)->next == NULL)
  65. {
  66. free(*pphead);
  67. *pphead = NULL;
  68. }
  69. // 有多个节点
  70. else
  71. {
  72. SLTNode* prev = *pphead;
  73. SLTNode* tail = *pphead;
  74. while (tail->next != NULL)
  75. {
  76. prev = tail;
  77. tail = tail->next;
  78. }
  79. free(tail);
  80. tail = NULL;
  81. prev->next = NULL;
  82. }
  83. }
  84. // 单链表的头删
  85. void SLTPopFront(SLTNode** pphead)
  86. {
  87. assert(*pphead);
  88. SLTNode* tail = *pphead;
  89. *pphead = (*pphead)->next;
  90. free(tail);
  91. tail = NULL;
  92. }
  93. // 单链表的查找
  94. SLTNode* SLTFind(SLTNode* phead, SLTDateType x)
  95. {
  96. SLTNode* ptr = phead;
  97. while (ptr->next != NULL)
  98. {
  99. if (ptr->data == x)
  100. {
  101. return ptr;
  102. }
  103. else
  104. {
  105. ptr = ptr->next;
  106. }
  107. }
  108. return NULL;
  109. }
  110. // 单链表在pos位置之前插入x
  111. void SLTInsert(SLTNode** pphead, SLTNode* pos, SLTDateType x)
  112. {
  113. assert(pphead);
  114. assert(pos);
  115. if (pos == *pphead)
  116. {
  117. SLTPushFront(pphead, x);
  118. }
  119. else
  120. {
  121. SLTNode* newnode = BuySLTNode(x);
  122. SLTNode* prev = *pphead;
  123. while (prev->next != pos)
  124. {
  125. prev = prev->next;
  126. }
  127. prev->next = newnode;
  128. newnode->next = pos;
  129. }
  130. }
  131. // 单链表在pos位置之后插入x
  132. void SLTInsertAfter(SLTNode* pos, SLTDateType x)
  133. {
  134. assert(pos);
  135. SLTNode* newnode = BuySLTNode(x);
  136. SLTNode* tmp = pos->next;
  137. pos->next = newnode;
  138. newnode->next = tmp;
  139. }
  140. // 单链表删除pos位置的值
  141. void SLTErase(SLTNode** pphead, SLTNode* pos)
  142. {
  143. assert(pphead);
  144. assert(*pphead);
  145. assert(pos);
  146. if (pos == *pphead)
  147. {
  148. SLTPopFront(pphead);
  149. }
  150. else
  151. {
  152. SLTNode* prev = *pphead;
  153. if (prev->next != pos)
  154. {
  155. prev = prev->next;
  156. }
  157. prev->next = pos->next;
  158. free(pos);
  159. pos = NULL;
  160. }
  161. }
  162. // 单链表删除pos位置之后的值
  163. void SLTEraseAfter(SLTNode* pos)
  164. {
  165. assert(pos);
  166. assert(pos->next);
  167. SLTNode* tmp = pos->next->next;
  168. free(pos->next);
  169. pos->next = tmp;
  170. }

2.3.3 -> Test.c

  1. #include "SList.h"
  2. // 尾插测试
  3. void SLTTest1()
  4. {
  5. SLTNode* plist = NULL;
  6. SLTPushBack(&plist, 1);
  7. SLTPushBack(&plist, 2);
  8. SLTPushBack(&plist, 3);
  9. SLTPushBack(&plist, 4);
  10. SLTPrint(plist);
  11. }
  12. // 头插测试
  13. void SLTTest2()
  14. {
  15. SLTNode* plist = NULL;
  16. SLTPushFront(&plist, 1);
  17. SLTPushFront(&plist, 2);
  18. SLTPushFront(&plist, 3);
  19. SLTPushFront(&plist, 4);
  20. SLTPrint(plist);
  21. }
  22. // 尾删测试
  23. void SLTTest3()
  24. {
  25. SLTNode* plist = NULL;
  26. SLTPushBack(&plist, 1);
  27. SLTPushBack(&plist, 2);
  28. SLTPushBack(&plist, 3);
  29. SLTPushBack(&plist, 4);
  30. SLTPrint(plist);
  31. SLTPopBack(&plist);
  32. SLTPrint(plist);
  33. SLTPopBack(&plist);
  34. SLTPrint(plist);
  35. SLTPopBack(&plist);
  36. SLTPrint(plist);
  37. SLTPopBack(&plist);
  38. SLTPrint(plist);
  39. }
  40. // 头删测试
  41. void SLTTest4()
  42. {
  43. SLTNode* plist = NULL;
  44. SLTPushBack(&plist, 1);
  45. SLTPushBack(&plist, 2);
  46. SLTPushBack(&plist, 3);
  47. SLTPushBack(&plist, 4);
  48. SLTPrint(plist);
  49. SLTPopFront(&plist);
  50. SLTPrint(plist);
  51. SLTPopFront(&plist);
  52. SLTPrint(plist);
  53. SLTPopFront(&plist);
  54. SLTPrint(plist);
  55. SLTPopFront(&plist);
  56. SLTPrint(plist);
  57. }
  58. // 查找测试
  59. void SLTTest5()
  60. {
  61. SLTNode* plist = NULL;
  62. SLTPushBack(&plist, 1);
  63. SLTPushBack(&plist, 2);
  64. SLTPushBack(&plist, 3);
  65. SLTPushBack(&plist, 4);
  66. SLTPrint(plist);
  67. SLTNode* ans = SLTFind(plist, 1);
  68. if (ans)
  69. ans->data = 10;
  70. SLTPrint(plist);
  71. }
  72. // 在pos位置之前插入x测试
  73. void SLTTest6()
  74. {
  75. SLTNode* plist = NULL;
  76. SLTPushBack(&plist, 1);
  77. SLTPushBack(&plist, 2);
  78. SLTPushBack(&plist, 3);
  79. SLTPushBack(&plist, 4);
  80. SLTPrint(plist);
  81. SLTNode* pos = SLTFind(plist, 2);
  82. if (pos)
  83. SLTInsert(&plist, pos, 99);
  84. SLTPrint(plist);
  85. }
  86. // 在pos位置之后插入x测试
  87. void SLTTest7()
  88. {
  89. SLTNode* plist = NULL;
  90. SLTPushBack(&plist, 1);
  91. SLTPushBack(&plist, 2);
  92. SLTPushBack(&plist, 3);
  93. SLTPushBack(&plist, 4);
  94. SLTPrint(plist);
  95. SLTNode* pos = SLTFind(plist, 2);
  96. if (pos)
  97. SLTInsertAfter(pos, 99);
  98. SLTPrint(plist);
  99. }
  100. // 删除pos位置的值测试
  101. void SLTTest8()
  102. {
  103. SLTNode* plist = NULL;
  104. SLTPushBack(&plist, 1);
  105. SLTPushBack(&plist, 2);
  106. SLTPushBack(&plist, 3);
  107. SLTPushBack(&plist, 4);
  108. SLTPrint(plist);
  109. SLTNode* pos = SLTFind(plist, 2);
  110. if (pos)
  111. SLTErase(&plist, pos);
  112. SLTPrint(plist);
  113. }
  114. // 删除pos位置之后的值测试
  115. void SLTTest9()
  116. {
  117. SLTNode* plist = NULL;
  118. SLTPushBack(&plist, 1);
  119. SLTPushBack(&plist, 2);
  120. SLTPushBack(&plist, 3);
  121. SLTPushBack(&plist, 4);
  122. SLTPrint(plist);
  123. SLTNode* pos = SLTFind(plist, 2);
  124. if (pos)
  125. SLTEraseAfter(pos);
  126. SLTPrint(plist);
  127. }
  128. int main()
  129. {
  130. return 0;
  131. }

感谢大佬们的支持!!!

互三啦!!!

声明:本文内容由网友自发贡献,转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号