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
相关产品推荐
相关产品推荐

