第十八题,(第二道题目),题目如下: 3.14(a):1->2->3->3->4->4->5 3.14(b):1->2->5
思路分析:需要三个指针分别指向当前节点,当前节点的前一个节点,当前节点的后一个节点,初始时当前节点为链表第一个节点,判断当前节点与当前节点的后一个节点是否相等,以此寻找要删除的节点位置。找到后进行删除,若第一个节点就开始重复需要把头结点更改故用指向指针的指针。若不是则把当前节点的前一个节点最终指向当前节点的下一个节点完成链表删除。
#include <stdio.h> #include <iostream> #include <stdlib.h> using namespace std; struct ListNode { int m_nValue; ListNode* m_pNext; }; ListNode* create(int n) { ListNode* tail, * head, * q; tail = head = (ListNode*)malloc(sizeof(ListNode)); head ->m_pNext=nullptr; for (int i = 0; i < n; i++) { q = (ListNode*)malloc(sizeof(ListNode)); scanf("%d", &q->m_nValue); q->m_pNext = tail->m_pNext; tail->m_pNext = q; tail = q; } return head->m_pNext; } void Delete(ListNode** listHead) { if (listHead == nullptr || *listHead == nullptr) return; ListNode * preNode = nullptr; ListNode * Node = *listHead; while (Node != nullptr) { ListNode* pNext = Node->m_pNext; bool needDelete = false; if (pNext != nullptr && pNext->m_nValue == Node->m_nValue) needDelete = true; if (!needDelete) { preNode = Node; Node = Node->m_pNext; } else { int value = Node->m_nValue; ListNode* ToBeDel = Node; while (ToBeDel != nullptr &&ToBeDel->m_nValue == value ) {//此处两个判断条件不能换前后顺序 pNext = ToBeDel->m_pNext;//对其所分配的空间进行释放 delete ToBeDel; ToBeDel = pNext; } if (preNode == nullptr)//首节点为重复节点的情况 * listHead = pNext; else preNode->m_pNext = pNext; Node = pNext; } } } void Print(ListNode * p) { if (p == nullptr) return; ListNode * q = p; while (q != nullptr) { printf("%d", q->m_nValue); q = q->m_pNext; } } int main() { ListNode* p; p = create(5); printf("原始链表为:"); Print(p); printf("\n"); Delete(&p); printf("删除之后为:"); Print(p); printf("\n"); }运行结果如图: