单链表算法实战:解锁数据结构核心谜题——移除链表元素 ...

打印 上一主题 下一主题

主题 1019|帖子 1019|积分 3057

标题如下:
  

   解题过程如下:
  给了链表的头结点head就相称于知道了整个链表。
思绪1:查找值为val的结点并返回结点位置,删除pos位置的结点。
涉及循环的嵌套,时间复杂度为O(n^2):

思考时间复杂度可不可以降为O(n)呢?
思绪2:创建新链表,将原链表中值不为val的结点拿下来尾插。
在原链表中修改,涉及到遍历、删除,时间复杂度不太好,那就创建一个新链表,这里并没有申请一个新链表、新结点,而是创建了一个空链表,该链表里有两个指针newHead、newTail,这两个指针还是指向原链表中的结点,通过修改两个新指针的指向来变成一个新的链表。

  1. /**
  2. * Definition for singly-linked list.
  3. * struct ListNode {
  4. *     int val;
  5. *     struct ListNode *next;
  6. * };
  7. */
  8. typedef struct ListNode ListNode;
  9. struct ListNode* removeElements(struct ListNode* head, int val) {
  10.     //创建空链表
  11.     ListNode* newHead, *newTail;
  12.     newHead = newTail = NULL;
  13.     //查找值不为val的结点并拿下来尾插
  14.     ListNode* pcur = head;
  15.     while (pcur)
  16.     {
  17.         if (pcur->val != val)
  18.         {
  19.             //链表为空
  20.             if (newHead == NULL)
  21.             {
  22.                 newHead = newTail = pcur;
  23.             }
  24.             //链表不为空
  25.             else
  26.             {
  27.                 newTail->next = pcur;
  28.                 newTail = newTail->next;
  29.             }
  30.         }
  31.         pcur = pcur->next;
  32.     }
  33.     return newHead;
  34. }
复制代码
点击运行发现Case1“解答错误”:

OJ代码有bug怎么办?VS调试技能用起来:
  1. //test.c
  2. struct ListNode{
  3.      int val;
  4.      struct ListNode *next;
  5. };
  6. typedef struct ListNode ListNode;
  7. struct ListNode* removeElements(struct ListNode* head, int val) {
  8.         //创建空链表
  9.         ListNode* newHead, * newTail;
  10.         newHead = newTail = NULL;
  11.         //查找值不为val的结点并拿下来尾插
  12.         ListNode* pcur = head;
  13.         while (pcur)
  14.         {
  15.                 if (pcur->val != val)
  16.                 {
  17.                         //链表为空
  18.                         if (newHead == NULL)
  19.                         {
  20.                                 newHead = newTail = pcur;
  21.                         }
  22.                         //链表不为空
  23.                         else
  24.                         {
  25.                                 newTail->next = pcur;
  26.                                 newTail = newTail->next;
  27.                         }
  28.                 }
  29.                 pcur = pcur->next;
  30.         }
  31.         return newHead;
  32. }
  33. int main()
  34. {
  35.         //手动构造一个链表
  36.         SLTNode* node1 = (SLTNode*)malloc(sizeof(SLTNode));
  37.         SLTNode* node2 = (SLTNode*)malloc(sizeof(SLTNode));
  38.         SLTNode* node3 = (SLTNode*)malloc(sizeof(SLTNode));
  39.         SLTNode* node4 = (SLTNode*)malloc(sizeof(SLTNode));
  40.         SLTNode* node5 = (SLTNode*)malloc(sizeof(SLTNode));
  41.         SLTNode* node6 = (SLTNode*)malloc(sizeof(SLTNode));
  42.         SLTNode* node7 = (SLTNode*)malloc(sizeof(SLTNode));
  43.         node1->data = 1;
  44.         node2->data = 2;
  45.         node3->data = 6;
  46.         node4->data = 3;
  47.         node5->data = 4;
  48.         node6->data = 5;
  49.         node7->data = 6;
  50.         node1->next = node2;
  51.         node2->next = node3;
  52.         node3->next = node4;
  53.         node4->next = node5;
  54.         node5->next = node6;
  55.         node6->next = node7;
  56.         node7->next = NULL;
  57.         SLTNode* plist = node1;
  58.         int val = 6;
  59.         ListNode* newHead = removeElements(plist, val);
  60.         return 0;
  61. }
复制代码

最后发现问题所在:存储数据5的尾结点的指针域指向存储6的结点,应该把链表的尾结点的next指针置为空。

我们发现修改后点击运行还是会出现错误,是因为当这个链表是空链表时,不进入循环,newTail是空指针,newTail->next就是对空指针的解引用操纵,这不符合语法规则,所以会报错:

   完整代码如下:
  1. /**
  2. * Definition for singly-linked list.
  3. * struct ListNode {
  4. *     int val;
  5. *     struct ListNode *next;
  6. * };
  7. */
  8. typedef struct ListNode ListNode;
  9. struct ListNode* removeElements(struct ListNode* head, int val) {
  10.     //创建空链表
  11.     ListNode* newHead, *newTail;
  12.     newHead = newTail = NULL;
  13.     //查找值不为val的结点并拿下来尾插
  14.     ListNode* pcur = head;
  15.     while (pcur)
  16.     {
  17.         if (pcur->val != val)
  18.         {
  19.             //链表为空
  20.             if (newHead == NULL)
  21.             {
  22.                 newHead = newTail = pcur;
  23.             }
  24.             //链表不为空
  25.             else
  26.             {
  27.                 newTail->next = pcur;
  28.                 newTail = newTail->next;
  29.             }
  30.         }
  31.         pcur = pcur->next;
  32.     }
  33.     if (newTail)
  34.         newTail->next = NULL;
  35.     return newHead;
  36. }
复制代码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

天空闲话

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表