如何在没有递归的情况下删除链表?

时间:2014-02-05 07:44:09

标签: c++ recursion stack-overflow destructor

我正试图找到一种删除链接列表而不递归的方法,因为堆栈溢出并不是真正的好东西。

我有一个结构如下:

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;导致递归删除列表的“尾部”(这是没有第一个元素的整个列表)。现在由于列表很长,我有时会看到堆栈溢出。

有解决这个问题的好方法吗?

4 个答案:

答案 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;
}