You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C++循环链表删除节点时无额外指针释放内存优化方案

问题规则

给定循环链表按如下规则删除节点,直到仅剩1个节点即为答案:

  • 第一步删除编号为1的首节点
  • 后续每轮依次跳过1个、2个、3个……节点后,删除下一个节点

示例:

  • 总节点数为5时,删除顺序为1、3、2、5,最终剩余节点为4
  • 总节点数为4时,删除顺序为1、3、4,最终剩余节点为2

代码改进要求:

  • 断链移除节点时必须通过delete释放对应内存,无内存泄漏
  • 不允许声明额外的新指针变量,尽可能降低内存开销
  • 基于原有可正确求解的C++代码修改
原有代码缺陷
  • 节点断链后未执行delete操作,存在明确的内存泄漏问题
  • 节点插入逻辑存在冗余:首节点初始化后,插入循环从i=1开始执行,多做了一次无意义的判断
  • 结果打印逻辑不可靠:固定遍历25次判断终止条件,节点数超过25时会返回错误结果
  • 首节点被删除后头指针成为野指针,后续访问存在未定义行为
改进实现

核心修改思路:复用函数内已存在的temp指针和形参head指针暂存待删除节点,全程不声明新的指针变量,在断链操作后直接释放待删节点内存,同时修复原有逻辑冗余和打印函数的bug。

改进后完整代码:

#include<iostream>
using namespace std;

class linked {
public:
    int x;
    linked* next;

    linked(int p);
    static void insert(linked*& head, int p);
    static int print(linked* head);
    static void del(linked*& head, int size);
};

int main() {
    int no_of_nodes;
    cout << "enter the number of nodes you want to have" << endl;
    cin >> no_of_nodes;
    linked* head = new linked(1);
    // 裁剪冗余循环,从2开始插入节点
    for (int i = 2; i <= no_of_nodes; i++) {
        linked::insert(head, i);
    }
    
    linked::del(head, no_of_nodes);
    cout << linked::print(head);
    // 释放最后剩余的节点,彻底消除内存泄漏
    delete head;
    return 0;
}

linked::linked(int p) {
    x = p;
    next = NULL;
}

void linked::insert(linked*& head, int p) {
    linked* temp = head;
    linked* n = new linked(p);
    // 适配首节点初始化后next为NULL的场景,移除冗余判断
    while (temp->next != head && temp->next != NULL) {
        temp = temp->next;
    }
    temp->next = n;
    n->next = head;
}

void linked::del(linked*& head, int size) {
    linked* temp = head;
    // 先走到尾节点,即首节点的前驱位置
    while (temp->next != head) {
        temp = temp->next;
    }
    for(int i = 1; i < size; i++) {
        // 沿用原有正确的步数遍历逻辑
        for (int k = 1; k < i; k++) {
            temp = temp->next;
        }
        // 复用已存在的head形参暂存待删节点,无额外新指针声明
        head = temp->next;
        temp->next = head->next;
        delete head; // 释放被移除节点的内存
    }
    // 更新头指针指向最后剩余的节点
    head = temp->next;
}

int linked::print(linked* head) {
    linked* temp = head;
    // 替换固定次数遍历,通过节点自指判断仅剩一个节点的终止条件
    while (temp->next != temp) {
        temp = temp->next;
    }
    return temp->x;
}
关键修改点说明
  • 内存释放:全程复用已有的head引用形参和temp指针暂存待删除节点,没有声明任何新的指针变量,完全符合低内存开销要求;每一次断链后立刻执行delete,程序退出前释放最后剩余的节点,全程无内存泄漏
  • 逻辑修复:保留原代码正确的遍历步数规则,修正插入逻辑的冗余判断,重写打印函数的终止条件,支持任意节点数的正确求解
  • 野指针修复:将del函数的head形参改为引用类型,删除首节点、遍历结束后同步更新头指针指向,避免野指针访问

内容的提问来源于stack exchange,提问作者AbdullahHabib

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 06:51:22