我正试图找到一种删除链接列表而不递归的方法,因为堆栈溢出并不是真正的好东西。
我有一个结构如下:
typedef struct _my_Item
{
_my_Item(const std::string& name)
{
m_name = name;
}
~my_Item()
{
delete next; // this recursively deletes the "tail" of the list
next = NULL;
}
struct _my_Item *next;
std::string m_name;
// ... More members here...
}
在某些代码中(这里不相关)我正在使用上述结构从数据文件构建一个列表。我将指针保存在变量列表的头部,可以使用它。一切都很好。
当我最终在列表的头部调用析构函数时,析构函数被调用,delete next;
导致递归删除列表的“尾部”(这是没有第一个元素的整个列表)。现在由于列表很长,我有时会看到堆栈溢出。
有解决这个问题的好方法吗?
答案 0 :(得分:3)
~my_Item()
{
while (next)
{
_my_Item* item = next;
next = item->next;
item->next = NULL; // this prevents the recursion
delete item;
}
}
答案 1 :(得分:3)
创建一个表示列表本身的类,它将通过for/while
循环在其析构函数中封装节点删除。按照您的方式进行操作可以删除部分列表并留下悬空指针。
答案 2 :(得分:1)
一个建议是从析构函数中删除删除代码并使用指针删除列表。
struct _my_Item * nodeToDelete = NULL;
while(firstNode != NULL)
{
nodeToDelete = firstNode;
firstNode = firstNode->next;
delete nodeToDelete;
}
答案 3 :(得分:0)
// I wrote this java code to delete a node from BST
// I only used one recursion call to remove successor
public Boolean delete(int data){
if(isEmpty() || !search(data))
return false;
return delete(null,root,data);
}
public Boolean delete(Node parent,Node temp,int data) {
while(true){
if(data == temp.getData()) {
break;
} else if(data < temp.getData()) {
parent = temp;
temp = temp.getLeft();
} else {
parent = temp;
temp = temp.getRight();
}
}
if(parent == null && (temp.getLeft() == null || temp.getRight() == null)){
if(temp.getLeft() == null)
root = temp.getRight();
else
root = temp.getLeft();
} else if(temp.getLeft() == null || temp.getRight() == null) {
if (parent.getLeft() == temp) {
if (temp.getLeft() == null)
parent.setLeft(temp.getRight());
else
parent.setLeft(temp.getLeft());
} else if (parent.getRight() == temp) {
if (temp.getLeft() == null)
parent.setRight(temp.getRight());
else
parent.setRight(temp.getLeft());
}
}else{
int min = findMin(temp.getRight());
temp.setData(min);
delete(temp,temp.getRight(),min);
}
return true;
}