两个有序链表序列的合并

ゞ 浴缸里的玫瑰 2022-03-01 16:36 333阅读 0赞

PTA 01:两个有序链表序列的合并

一、题目

本题要求实现一个函数,将两个链表表示的递增整数序列合并为一个非递减的整数序列。

函数接口定义:

  1. List Merge( List L1, List L2 );

其中List结构定义如下:

  1. typedef struct Node *PtrToNode;
  2. struct Node {
  3. ElementType Data; /* 存储结点数据 */
  4. PtrToNode Next; /* 指向下一个结点的指针 */
  5. };
  6. typedef PtrToNode List; /* 定义单链表类型 */






L1和L2是给定的带头结点的单链表,其结点存储的数据是递增有序的;函数Merge要将L1和L2合并为一个非递减的整数序列。应直接使用原序列中的结点,返回归并后的带头结点的链表头指针。

裁判测试程序样例:

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. typedef int ElementType;
  4. typedef struct Node *PtrToNode;
  5. struct Node {
  6. ElementType Data;
  7. PtrToNode Next;
  8. };
  9. typedef PtrToNode List;
  10. List Read(); /* 细节在此不表 */
  11. void Print( List L ); /* 细节在此不表;空链表将输出NULL */
  12. List Merge( List L1, List L2 );
  13. int main()
  14. {
  15. List L1, L2, L;
  16. L1 = Read();
  17. L2 = Read();
  18. L = Merge(L1, L2);
  19. Print(L);
  20. Print(L1);
  21. Print(L2);
  22. return 0;
  23. }
  24. /* 你的代码将被嵌在这里 */

输入样例:

  1. 3
  2. 1 3 5
  3. 5
  4. 2 4 6 8 10

输出样例:

  1. 1 2 3 4 5 6 8 10
  2. NULL
  3. NULL

二、代码

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. typedef int ElementType;
  4. typedef struct Node *PtrToNode;
  5. struct Node {
  6. ElementType Data;
  7. PtrToNode Next;
  8. };
  9. typedef PtrToNode List;
  10. /* 你的代码将被嵌在这里 */
  11. List Read(){
  12. // 此函数的作用:创建链表并插入数据
  13. int n;
  14. scanf("%d",&n);
  15. // 输入该链表中元素的个数
  16. List L=(List)malloc(sizeof(PtrToNode));
  17. // 申请一个头节点
  18. L->Next=NULL;
  19. // 先建立一个以L为头结点的空链表
  20. if(n!=0){
  21. List r=L;
  22. // 尾指针指向头结点
  23. for(int i=0;i<n;i++){
  24. List p=(List)malloc(sizeof(struct Node));
  25. scanf("%d",&(p->Data));
  26. p->Next=NULL;
  27. r->Next=p;
  28. r=p;
  29. }
  30. r->Next=NULL;
  31. }
  32. return L;
  33. };
  34. void Print(List L){
  35. // 此函数的作用:打印链表中的元素
  36. List P=L->Next;
  37. if(P!=NULL)
  38. {
  39. List r;
  40. r = L;
  41. while(r->Next)
  42. {
  43. r = r->Next;
  44. printf("%d ",r->Data);
  45. }
  46. }
  47. else
  48. {
  49. printf("NULL");
  50. }
  51. printf("\n");
  52. };
  53. List Merge( List L1, List L2){
  54. // 此函数的作用:实现将两链表融合
  55. List p1,p2,p,L;
  56. L = (List)malloc(sizeof(struct Node));
  57. p1=L1->Next;
  58. p2=L2->Next;
  59. // p1 p2指针分别指向两个表的第一个结点
  60. p=L;
  61. // p指向L的头结点
  62. while(p1!=NULL&&p2!=NULL){
  63. if(p1->Data<=p2->Data){
  64. p->Next=p1;
  65. p=p1;
  66. p1=p1->Next;
  67. }
  68. else{
  69. p->Next=p2;
  70. p=p2;
  71. p2=p2->Next;
  72. }
  73. // 当L1 L2 均未到达表尾 依次摘取两表中值较小的结点插入到L最后
  74. }
  75. p->Next=p1?p1:p2;
  76. L1->Next=NULL;
  77. L2->Next=NULL;
  78. return L;
  79. };
  80. int main()
  81. {
  82. List L1, L2, L;
  83. L1 = Read();
  84. L2 = Read();
  85. L = Merge(L1, L2);
  86. Print(L);
  87. Print(L1);
  88. Print(L2);
  89. return 0;
  90. }

三、经验总结

刚开始经历过几次失败,其中一次这里写的是List L ;L=new LNode(按书上打的)但是跑一下 马上就报错了。程序在我输入完之后就崩溃了,说明read这边没毛病,到print这一步就出错了。

我然后把L=new LNode这句删了(其实好蠢啊我)可是到read这一步程序就崩了 分析原因应该是我没有给我的指针在内存中分配一个首地址。

现在问题来了,这种情况该如何建立一个带头结点的空链表呢?
由于不知道到底这段地址有多长,可以存什么变量,所以它的类型是空的,
我们可以利用







L = (List)malloc(sizeof(struct Node));

作强制类型转换,使其变成确定长度,固定存放一种数据类型的地址。

所以我们要做的是:获取PtrToNode的字段长度,然后强转为List类型。
L变量就代表地址长度和PtrToNode一样所占内存空间同样大小的List。注意用malloc函数之前一定记得包含头文件 #include 哦!

可是当我兴高采烈地拿着dev上已经通过的程序放到PTA上面跑,却发现系统提示编译错误。这让人很费解。后来发现是惯性思维作怪,我们每次把代码一粘上去就完事了,但是这一题只要求我们提交merge部分。

发表评论

表情:
评论列表 (有 0 条评论,333人围观)

还没有评论,来说两句吧...

相关阅读

    相关 合并有序

    合并两个有序链表 1、题目 题目要求:将两个升序链表合并为一个新的升序链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。 示例: 输