当前位置:   article > 正文

单链表交叉分离,运用头插法,尾插法(算法库应用)

单链表交叉分离,运用头插法,尾插法(算法库应用)

原文博客链接:单链表分离(头插法和尾插法的结合,理解指针变换)_3.对任务1或者2中创建的某一个单链表{a1,b1,a2,b2,...,an,bn},编写一个算法将-CSDN博客

函数实现:

  1. /**************************************************
  2. 函数名:separate_LinkList
  3. 功 能: 把一个链表,交叉新建成两个表,一个尾插法,一个头插法(尾插法在原表之上)
  4. 注意:① 等构建完再置空
  5. 参 数: (1)LinkList *&L:原表
  6. (2)LinkList *&List_tail:原表之上尾插法建立的新表
  7. (3)LinkList*&List_head: 另外新建的单链表(头插法)
  8. 原文链接:https://blog.csdn.net/qq_57484399/article/details/127132144
  9. 返回值: 无
  10. **************************************************/
  11. void separate_LinkList(LinkList *&L,LinkList *&List_tail,LinkList*&List_head)
  12. {
  13. LinkList *newNode; //新节点
  14. LinkList *rearNode; //新节点后继信息存储
  15. LinkList *Tail_pointer; //List_tail尾指针
  16. newNode = L->next; //新节点从L->next开始
  17. List_tail = L; //List_tail从L开始
  18. Tail_pointer = List_tail;
  19. List_head = (LinkList*)malloc(sizeof(LinkList)); //List_head构建新节点
  20. List_head->next = NULL;
  21. while(newNode != NULL)
  22. {
  23. Tail_pointer->next = newNode; //List_tail尾指针指向新节点
  24. Tail_pointer = newNode; //①尾指针Tail_pointer后移,构建完成
  25. newNode = newNode->next; //新节点后移
  26. rearNode = newNode->next; //新节点后继信息存储
  27. newNode->next = List_head->next; //新节点头插法插入
  28. List_head->next = newNode;
  29. newNode = rearNode; //书接上回
  30. }
  31. Tail_pointer->next = NULL;
  32. }

完整代码:

main.cpp

  1. #include <stdio.h>
  2. #include <malloc.h>
  3. #include "singlelist.h"
  4. void split(LinkList *&L,LinkList *&L1,LinkList*&L2);//分离链表
  5. /**************************************************
  6. 函数名:separate_LinkList
  7. 功 能: 把一个链表,交叉新建成两个表,一个尾插法,一个头插法(尾插法在原表之上)
  8. 注意:① 等构建完再置空
  9. 参 数: (1)LinkList *&L:原表
  10. (2)LinkList *&List_tail:原表之上尾插法建立的新表
  11. (3)LinkList*&List_head: 另外新建的单链表(头插法)
  12. 原文链接:https://blog.csdn.net/qq_57484399/article/details/127132144
  13. 返回值: 无
  14. **************************************************/
  15. void separate_LinkList(LinkList *&L,LinkList *&List_tail,LinkList*&List_head)
  16. {
  17. LinkList *newNode; //新节点
  18. LinkList *rearNode; //新节点后继信息存储
  19. LinkList *Tail_pointer; //List_tail尾指针
  20. newNode = L->next; //新节点从L->next开始
  21. List_tail = L; //List_tail从L开始
  22. Tail_pointer = List_tail;
  23. List_head = (LinkList*)malloc(sizeof(LinkList)); //List_head构建新节点
  24. List_head->next = NULL;
  25. while(newNode != NULL)
  26. {
  27. Tail_pointer->next = newNode; //List_tail尾指针指向新节点
  28. Tail_pointer = newNode; //①尾指针Tail_pointer后移,构建完成
  29. newNode = newNode->next; //新节点后移
  30. rearNode = newNode->next; //新节点后继信息存储
  31. newNode->next = List_head->next; //新节点头插法插入
  32. List_head->next = newNode;
  33. newNode = rearNode; //书接上回
  34. }
  35. Tail_pointer->next = NULL;
  36. }
  37. int main()
  38. {
  39. LinkList *L1, *L2,*L;
  40. ElemType a[10]= {1,10,2,9,3,8,4,7,5,6};
  41. CreatList_Tail(L, a, 10);
  42. printf("输出L表结果:");
  43. DisplayLinkList(L);
  44. separate_LinkList(L,L1,L2);
  45. printf("L1表结果:");
  46. DisplayLinkList(L1);
  47. printf("L2结果:");
  48. DisplayLinkList(L2);
  49. return 0;
  50. }

singlelist.cpp  单链表函数库

  1. #include "singlelist.h"
  2. /**************************************************
  3. ①函数名: CreatList_Head
  4. 功 能: 头插法建立单链表
  5. 参 数: (1)LinkList *&L: 传入的单链表指针地址
  6. (2)ElemType Array_used[]:要用来建表的数组
  7. (3)int Array_number: 数组的长度
  8. 返回值: 无
  9. **************************************************/
  10. void CreatList_Head(LinkList *&L, ElemType Array_used[], int Array_number)
  11. {
  12. int counter;
  13. LinkList *newnode;
  14. L = (LinkList *)malloc(sizeof(LinkList)); //创建头结点
  15. L->next = NULL;
  16. for(counter = 0; counter < Array_number; counter++)
  17. {
  18. newnode = (LinkList *)malloc(sizeof(LinkList)); //创建新节点
  19. newnode->data = Array_used[counter];
  20. newnode->next = L->next; //将newnode插在原开始结点之前,头结点之后
  21. L->next = newnode;
  22. }
  23. }
  24. /**************************************************
  25. ②函数名: CreatList_Tail
  26. 功 能: 尾插法建立单链表
  27. 参 数: (1)LinkList *&L: 传入的单链表指针地址
  28. (2)ElemType Array_used[]:要用来建表的数组
  29. (3)int Array_number:数组的长度
  30. 返回值: 无
  31. **************************************************/
  32. void CreatList_Tail(LinkList *&L, ElemType Array_used[], int Array_number)
  33. {
  34. int counter;
  35. LinkList *newnode,*tailnode;
  36. L = (LinkList *)malloc(sizeof(LinkList));//创建头结点
  37. L->next = NULL;
  38. tailnode = L; //尾结点tailnode始终指向终端结点,开始指向头结点
  39. for(counter = 0; counter < Array_number; counter++)
  40. {
  41. newnode = (LinkList *)malloc(sizeof(LinkList)); //创建新节点
  42. newnode->data = Array_used[counter];
  43. tailnode->next = newnode; //将新节点插入到尾结点之后
  44. tailnode = newnode; //更新尾结点
  45. }
  46. tailnode->next = NULL; //终端结点next域置空
  47. }
  48. /**************************************************
  49. ③函数名: DisplayLinkList
  50. 功 能: 输出单链表
  51. 参 数: (1)LinkList *L:将要输出的单链表
  52. 返回值: 无
  53. **************************************************/
  54. void DisplayLinkList(LinkList *L)
  55. {
  56. LinkList *shownode;
  57. shownode = L->next;
  58. while(shownode != NULL)
  59. {
  60. printf("%d ",shownode->data);
  61. shownode = shownode->next; //一直遍历,直到指向尾->newt = NULL
  62. }
  63. printf("\n");
  64. }
  65. /**************************************************
  66. ④函数名: DestroyLinkList
  67. 功 能: 销毁单链表
  68. 参 数: (1)LinkList *&L:要销毁的单链表
  69. 注意:① 等到指引下一个节点的指针为Null时就跳出,避免出现野指针,此时再销毁destroyNode
  70. ② 避免断开联系,记录 销毁节点的下一个节点
  71. 返回值: 无
  72. **************************************************/
  73. void DestroyLinkList(LinkList *&L)
  74. {
  75. LinkList *destoryNode,*nextNode;
  76. destoryNode = L;
  77. nextNode = destoryNode->next;
  78. while(nextNode != NULL) //①
  79. {
  80. free(destoryNode);
  81. destoryNode = nextNode;
  82. nextNode = destoryNode->next; //②
  83. }
  84. free(destoryNode);
  85. }
  86. /**************************************************
  87. ⑤函数名: InitLinkList
  88. 功 能: 初始化单链表
  89. 参 数: LinkList *&L:要被初始化的链表指针地址
  90. 返回值: 无
  91. **************************************************/
  92. void InitLinkList(LinkList *&L)
  93. {
  94. L = (LinkList *)malloc(sizeof(LinkList));//创建头结点
  95. L->next = NULL;
  96. }
  97. /**************************************************
  98. ⑥函数名: LinkListEmpty
  99. 功 能: 判断单链表是否为空
  100. 参 数: (1)LinkList *L:要判断的单链表
  101. 返回值: bool: 是否为空? treu:false
  102. **************************************************/
  103. bool LinkListEmpty(LinkList *L)
  104. {
  105. return (L->next == NULL);
  106. }
  107. /**************************************************
  108. ⑦函数名: LinkListLength
  109. 功 能: 返回单链表L中数据节点的个数
  110. 参 数: LinkList *L:要计算的数据节点
  111. 返回值: int: 线性表数据节点个数值
  112. **************************************************/
  113. int LinkListLength(LinkList *L)
  114. {
  115. int counter = 0;
  116. LinkList *nowNode = L;
  117. while(nowNode->next != NULL)
  118. {
  119. counter++;
  120. nowNode = nowNode->next;
  121. }
  122. return counter;
  123. }
  124. /**************************************************
  125. ⑧函数名: GetLocateValue
  126. 功 能: 求特定位置的数据元素值
  127. 参 数: (1)LinkList *L:要找的单链表
  128. (2)int location:所要找的位置
  129. (3)ElemType &value: 传递回所要找的值
  130. 注意: ① 判断跳出的时候, 是查找成功, 还是抵达末尾
  131. ② counter == 要找到序号,则跳出,所以counter < location ,
  132. nowNode指向的节点为空,则到末尾,则跳出
  133. ③④ 这两条语句, 所指向的序号和节点, 是同步的, 位置到或者此节点为空,则跳出
  134. 返回值: bool: 是否查找成功? true:false
  135. **************************************************/
  136. bool SpecificLocate_Value(LinkList *L,int location, ElemType &value)
  137. {
  138. int counter = 0;
  139. LinkList *nowNode = L;
  140. while(counter < location && nowNode != NULL)//②
  141. {
  142. counter++; //③ 当前计数的节点
  143. nowNode = nowNode->next;//④当前遍历到的节点
  144. }
  145. if(nowNode == NULL) //①
  146. {
  147. return false;
  148. }
  149. else
  150. {
  151. value = nowNode->data;
  152. return true;
  153. }
  154. }
  155. /**************************************************
  156. ⑨函数名:SpecificValue_Location
  157. 功 能: 查找特定数据值的节点,并返回其位置
  158. 参 数: (1)LinkList *L: 被查找的单链表(2)ElemType e:
  159. 注 意: ①从头结点后的第一个节点开始找
  160. ②while循环内的两条语句是同步指向的
  161. ③当nowNode为空时(到达末尾仍未找到), counter作废
  162. ④当nowNode不为空时,跳出时, counter表示所指向节点存在,并符合所需
  163. 返回值:
  164. **************************************************/
  165. int SpecificValue_Location(LinkList *L, ElemType value)
  166. {
  167. int counter = 1;
  168. LinkList *nowNode = L->next; //①
  169. while(nowNode != NULL && nowNode->data != value)
  170. {
  171. nowNode = nowNode->next;
  172. counter++; //②
  173. }
  174. if(nowNode == NULL) //③
  175. {
  176. return 0;
  177. }
  178. else //④
  179. {
  180. return counter;
  181. }
  182. }
  183. /**************************************************
  184. ⑩函数名: LinkList_InsertElement
  185. 功 能: 在单链表特定位置插入节点
  186. 参 数: (1)LinkList *&L:要插入的单链表
  187. (2)int location:要插入的位置
  188. (3) ElemType &value:插入的数据
  189. 思路: 先在单链表L中,找到第 i-1个节点(不算头结点),若存在这样的节点,
  190. 将值为value的节点 插入到其后面
  191. 注意: ① 计数器和 nowNode是同步往后移动(从L->next开始算第一个节点),
  192. 直到 找到counter = location-1,
  193. ②此时 nowNode不为空,则此时nowNode指向
  194. 要插入位置的 前一个节点
  195. ③ 覆盖指针前, 牢记 nowNode->next里面存放的是后继节点信息,所以要先处理
  196. newNode->next = nowNode->next;
  197. 然后我们才能再把 nowNode->next指向新节点 newNode
  198. 返回值: bool: 是否存在第i-1个节点,并插入成功? true : false
  199. **************************************************/
  200. bool LinkList_InsertElement(LinkList *&L, int location, ElemType &value)
  201. {
  202. int counter = 0;
  203. LinkList *nowNode = L;
  204. LinkList *newNode;
  205. while((counter < (location-1)) && (nowNode != NULL)) //①
  206. {
  207. counter++;
  208. nowNode = nowNode->next;
  209. }
  210. if(nowNode == NULL)//②
  211. {
  212. return false;
  213. }
  214. else
  215. {
  216. newNode = (LinkList *)malloc(sizeof(LinkList));
  217. newNode->data = value;
  218. newNode->next = nowNode->next;//③
  219. nowNode->next = newNode;
  220. return true;
  221. }
  222. }
  223. /**************************************************
  224. (11)函数名: LinkList_Delete_Location
  225. 功 能: 删除特定位置的节点元素
  226. 参 数: (1)LinkList *&L:被删除的单链表 (2)int location:特定位置
  227. (3) ElemType &value:被删除的元素值
  228. 思路: 找到第location-1个元素, 存储第locataion个元素值(判断null),然后free
  229. 链接 location-1 和 location+1
  230. 注意: ① counter和指针节点是同步的,要么找到location-1个节点,要么到末尾
  231. ② 虽然可能找到location-1个元素,其可能是最后一个元素,从而导致删除失败
  232. 需要判断一下,deleteNode是否为空,才能得出是否任务成功
  233. ③ 指针覆盖还是老生常谈,先存储一下deleteNode(方便free),
  234. 然后指针交替,然后free
  235. 返回值: bool: 是否删除成功? true:false
  236. **************************************************/
  237. bool LinkList_Delete_Location(LinkList *&L,int location, ElemType &value)
  238. {
  239. int counter = 0;
  240. LinkList *nowNode = L;
  241. LinkList *deleteNode;
  242. while(counter < (location-1) && nowNode != NULL) //①
  243. {
  244. counter++;
  245. nowNode = nowNode->next;
  246. }
  247. if(nowNode == NULL)
  248. {
  249. return false;
  250. }
  251. else
  252. {
  253. deleteNode = nowNode->next;
  254. if(deleteNode == NULL) //②
  255. {
  256. return false;
  257. }
  258. value = deleteNode->data;
  259. nowNode->next = deleteNode->next; //③
  260. free(deleteNode);
  261. return true;
  262. }
  263. }
  264. /**************************************************
  265. (12)函数名: DeleteMaxNode
  266. 功 能: 删除单链表中最大的一个节点
  267. 参 数: (1)LinkList *&L:要删除节点的单链表
  268. 思路: 四个指针, 最大指针,最大指针前一个节点
  269. 目前遍历的指针,遍历指针的前一个节点, 边比较,边替换,边遍历
  270. 注意:①避免只有一个头结点,造成空指针替换异常
  271. ②③ 顺序不能变,因为③跳出的时候, 会利用到while的非空条件,
  272. 避免对比的时候, 出现野指针,直到为空时,即可直接跳出,非空则比较替换
  273. 返回值:是否删除成功 ? true:false
  274. **************************************************/
  275. bool DeleteMaxNode(LinkList *&L)
  276. {
  277. LinkList *nowNode,*preNode;
  278. LinkList *maxNode,*preMaxNode;
  279. nowNode = L->next;
  280. preNode = L;
  281. maxNode = nowNode;
  282. preMaxNode = preNode;
  283. if(nowNode == NULL) //①
  284. {
  285. return false;
  286. }
  287. while(nowNode != NULL) //直到末尾
  288. {
  289. if(nowNode->data > maxNode->data) //②
  290. {
  291. maxNode = nowNode;
  292. preMaxNode = preNode;
  293. }
  294. preNode = nowNode; //接着走下一个节点
  295. nowNode = nowNode->next; //③
  296. }
  297. preMaxNode->next = maxNode->next;
  298. free(maxNode);
  299. return true;
  300. }
  301. /**************************************************
  302. (13)函数名:LinkList_sorting
  303. 功 能:对单链表中元素进行排序(至少有2个数据节点)
  304. 参 数:LinkList *&L:要进行排序的单链表
  305. 注意: ① 空表,或者只有一个数据节点,则不需要排序,返回false
  306. ② 开始节点必须是头结点,因为我们会用到start_compare->next,
  307. ③ 把数据节点(第二个数据节点及以后)和原始链表(头结点+一个数据节点)
  308. ④ 在有序表中,一直找到比前一个节点大,比后一个节点小的空挡,
  309. 所以时刻对比start_compare->next->data, 并且start_compare->next不能为空
  310. (为空代表到达末尾,交替空指针)
  311. ⑤ 顺序不能变, 避免丢失有序表后续信息(指针覆盖的一句话)
  312. 详细链接:https://blog.csdn.net/qq_57484399/article/details/127141307
  313. 返回值:bool: 是否符合排序标准,并排序成功 ? true: false
  314. **************************************************/
  315. bool LinkList_sorting(LinkList *&L)
  316. {
  317. LinkList *compare,*start_compare,*Remaining_node;
  318. if(L->next == NULL || L->next->next == NULL)//①保证至少有2个数据节点
  319. {
  320. return false;
  321. }
  322. compare = L->next->next;
  323. start_compare = L; //②开始节点必须是头结点
  324. Remaining_node = compare->next;
  325. L->next->next = NULL; //③把数据节点(第二个数据节点及以后)和原始链表(头结点+一个数据节点)
  326. while(compare != NULL)
  327. {
  328. Remaining_node = compare->next;
  329. start_compare = L;
  330. while((start_compare->next != NULL) && (compare->data > start_compare->next->data))
  331. {
  332. start_compare = start_compare->next;
  333. } //④
  334. compare->next = start_compare->next;
  335. start_compare->next = compare; //⑤
  336. compare = Remaining_node;
  337. }
  338. return true;
  339. }

singlelist.h  单链表函数库头文件

  1. #ifndef SINGLELIST_H_INCLUDE
  2. #define SINGLELIST_H_INCLUDE
  3. #include <stdio.h>
  4. #include <malloc.h>
  5. typedef int ElemType; //定义单链表节点类型
  6. typedef struct LNode
  7. {
  8. ElemType data;
  9. struct LNode *next; //指向后继节点
  10. }LinkList;
  11. //①头插法建立单链表
  12. void CreatList_Head(LinkList *&L, ElemType Array_used[], int Array_number);
  13. //②尾插法建立单链表
  14. void CreatList_Tail(LinkList *&L, ElemType Array_used[], int Array_number);
  15. //③输出单链表
  16. void DisplayLinkList(LinkList *L);
  17. //④销毁单链表
  18. void DestroyLinkList(LinkList *&L);
  19. //⑤ 初始化线性表
  20. void InitLinkList(LinkList *&L);
  21. //⑥ 判断线性表是否为空表
  22. bool LinkListEmpty(LinkList *L);
  23. //⑦ 返回单链表L中数据节点的个数
  24. int LinkListLength(LinkList *L);
  25. //⑧ 求线性表L中指定位置的某个数据元素
  26. bool SpecificLocate_Value(LinkList *L,int location, ElemType &value);
  27. //⑨ 按元素值查找特定元素的位置
  28. int SpecificValue_Location(LinkList *L, ElemType value);
  29. //⑩ 把元素插入到特定位置
  30. bool LinkList_InsertElement(LinkList *&L, int location, ElemType &value);
  31. //(11) 删除特定位置的节点元素
  32. bool LinkList_Delete_Location(LinkList *&L,int location, ElemType &value);
  33. //(12)单链表删除其中其最大节点元素
  34. bool DeleteMaxNode(LinkList *&L);
  35. //(13)对单链表中元素进行排序(至少有2个数据节点)
  36. bool LinkList_sorting(LinkList *&L);
  37. #endif // SINGLELIST_H_INCLUDE

代码运行结果:

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/凡人多烦事01/article/detail/346210
推荐阅读
相关标签
  

闽ICP备14008679号