C++基础(⑤删除链表中的重复节点(链表 + 遍历))

题目描述

给定一个排序好的链表(升序),删除所有重复的元素,使每个元素只出现一次。

示例:

输入:1 → 1 → 2 → 3 → 3

输出:1 → 2 → 3

解题思路

核心观察:链表已排序,重复节点一定「相邻」(无需考虑非相邻重复)。

遍历逻辑:用一个指针 current 从表头开始遍历:

若 current 的值 == current->next 的值(发现重复),则跳过 current->next(让 current->next 指向 current->next->next);

若不重复,current 移动到下一个节点(current = current->next)。

边界处理:链表为空或只有 1 个节点时,直接返回原链表(无重复可删)。

C++ 代码实现

cpp 复制代码
#include <iostream>
using namespace std;

// 先定义链表节点(复用你熟悉的结构)
struct ListNode {
    int val;
    ListNode* next;
    ListNode(int v = 0, ListNode* n = nullptr) : val(v), next(n) {}
};

// 打印链表(辅助函数)
void printList(ListNode* head) {
    ListNode* curr = head;
    while (curr != nullptr) {
        cout << curr->val << " → ";
        curr = curr->next;
    }
    cout << "nullptr" << endl;
}

// 核心函数:删除重复节点
ListNode* deleteDuplicates(ListNode* head) {
    // 边界:空链表或只有1个节点,直接返回
    if (head == nullptr || head->next == nullptr) {
        return head;
    }

    ListNode* current = head;  // 遍历指针
    while (current != nullptr && current->next != nullptr) {
        if (current->val == current->next->val) {
            // 发现重复:跳过 current->next(先存临时指针避免内存泄漏)
            ListNode* temp = current->next;
            current->next = current->next->next;
            delete temp;  // 释放重复节点的内存
        } else {
            // 不重复:移动到下一个节点
            current = current->next;
        }
    }
    return head;
}

// 测试代码
int main() {
    // 构造示例链表:1 → 1 → 2 → 3 → 3
    ListNode* head = new ListNode(1);
    head->next = new ListNode(1);
    head->next->next = new ListNode(2);
    head->next->next->next = new ListNode(3);
    head->next->next->next->next = new ListNode(3);

    cout << "原链表:";
    printList(head);

    head = deleteDuplicates(head);
    cout << "删除重复后:";
    printList(head);

    // 释放链表内存(避免泄漏)
    ListNode* curr = head;
    while (curr != nullptr) {
        ListNode* temp = curr;
        curr = curr->next;
        delete temp;
    }
    return 0;
}

123