C++;删除双链表中的元素函数 我对C++是相当新的,它是数据结构。我已经为我的双链表类创建了一些函数,但是我在删除函数方面遇到了问题。我制作了一个deleteHead()函数,它删除列表中的第一个节点,一个deleteTail()函数删除列表中的最后一个节点,最后一个deleteElement(Item)函数遍历列表并删除其中包含该项的节点

C++;删除双链表中的元素函数 我对C++是相当新的,它是数据结构。我已经为我的双链表类创建了一些函数,但是我在删除函数方面遇到了问题。我制作了一个deleteHead()函数,它删除列表中的第一个节点,一个deleteTail()函数删除列表中的最后一个节点,最后一个deleteElement(Item)函数遍历列表并删除其中包含该项的节点,c++,doubly-linked-list,C++,Doubly Linked List,问题是,每当我试图从列表中删除唯一剩余的节点时,程序就会崩溃。i、 e如果我插入一个节点,然后在同一个节点上调用deleteElement函数(如果我插入的节点是列表中唯一的节点),程序就会崩溃 这是我的密码 template <class T> void LinkedList<T>::deleteElement(T item) { ListItem<T>* current = head; ListItem<T>* temp;

问题是,每当我试图从列表中删除唯一剩余的节点时,程序就会崩溃。i、 e如果我插入一个节点,然后在同一个节点上调用deleteElement函数(如果我插入的节点是列表中唯一的节点),程序就会崩溃

这是我的密码

template <class T>
void LinkedList<T>::deleteElement(T item)
{
    ListItem<T>* current = head;
    ListItem<T>* temp;
    if (head == NULL) {                         // if list is empty end the function
        return;
    }
    while (current) {
        if (current->value == item) {
            if (current == head) {              // if item is in the head
                deleteHead();
            }
            else if (current == getTail()) {    // if item is in the tail
                deleteTail();
            }
            // if item is between two nodes
            else if (current != head && current != getTail()) { 
                temp = current;
                temp->prev->next = temp->next;
                temp->next->prev = temp->prev;
                current->next = NULL;
                current->prev = NULL;
                if (current->next == NULL) {
                    deleteTail();
                }
            }
        }
        current = current->next;
    }
}

// Delete the Head Node
template <class T>
void LinkedList<T>::deleteHead()
{
    if (head != NULL) { // as long as head is not null, delete head
        ListItem<T> *current = head;
        head = head->next;
        current->next = NULL;
        head->prev = NULL;
    } else {return;} // if head is null, end the function without doing anything
}

// Delete Tail Node
template <class T>
void LinkedList<T>::deleteTail()
{
    ListItem<T> *tail = getTail();
    tail = tail->prev;
    tail->next->prev = NULL;
    tail->next = NULL;
}
模板
void LinkedList::deleteElement(T项)
{
ListItem*当前=头;
列表项*温度;
如果(head==NULL){//如果列表为空,则结束函数
返回;
}
while(当前){
如果(当前->值==项目){
if(current==head){//if项目在head中
deleteHead();
}
else if(current==getTail()){//if项在尾部
deleteTail();
}
//如果项目位于两个节点之间
如果(当前!=head&¤t!=getTail()){
温度=电流;
临时->上一个->下一个=临时->下一个;
临时->下一步->上一步=临时->上一步;
当前->下一步=空;
当前->上一个=空;
如果(当前->下一步==NULL){
deleteTail();
}
}
}
当前=当前->下一步;
}
}
//删除头部节点
模板
void LinkedList::deleteHead()
{
如果(head!=NULL){//只要head不为NULL,就删除head
ListItem*当前=头;
头部=头部->下一步;
当前->下一步=空;
head->prev=NULL;
}else{return;}//如果head为null,则结束函数而不执行任何操作
}
//删除尾部节点
模板
void LinkedList::deleteTail()
{
ListItem*tail=getTail();
tail=tail->prev;
tail->next->prev=NULL;
tail->next=NULL;
}

您的代码中有几个问题。首先,在访问指针之前,您不会检查任何指针。例如,这里:

temp = current;
temp->prev->next = temp->next;
temp->next->prev = temp->prev;
如果列表中只有一个元素,则其
next
prev
成员可能为空。这意味着试图将某些内容分配给
temp->prev->next
temp->next->prev
将是访问冲突

这同样适用于其他地方,包括
while
循环末尾的这一行:

current = current->next;
在那个阶段,
current
可能会被删除,这意味着尝试访问其
下一个
成员将失败。但由于另一个问题,目前它可能不会失败

非常重要的是,您实际上没有删除任何内容。C++没有垃圾回收器,所以不能只设置一个原始指针为null并忘记它。您必须对其调用
delete
,以销毁和取消分配对象,否则会导致内存泄漏。您需要在整个代码中解决这个问题,然后可能需要修改所有函数。您需要非常小心,不要在对象被删除后访问它

话虽如此,您应该真正使用智能指针(即
std::shared_ptr
),而不是使用原始指针。当没有其他对象具有指向该对象的指针时,它们会为您删除该对象。您仍然需要避免访问已删除的对象,但这会使编码更简单,希望更现代/更健壮。

建议: 步骤1-将成员变量
ListItem*tail
添加到类
ListItem

步骤2-将对
getTail()
的所有调用替换为
tail

步骤3-在功能
删除元素
中,您可以替换:

else if (current != head && current != tail)
current->next = NULL;
current->prev = NULL;
if (current->next == NULL)
    deleteTail();
与:

步骤4-在功能
删除元素
中,您应该替换:

else if (current != head && current != tail)
current->next = NULL;
current->prev = NULL;
if (current->next == NULL)
    deleteTail();
与:

步骤#5-重写函数
deleteHead
,如下所示:

ListItem<T>* current = head;
if (head == tail)
    head = tail = NULL;
else
    head = head->next;
delete current;
ListItem<T>* current = tail;
if (tail == head)
    tail = head = NULL;
else
    tail = tail->prev;
delete current;

我答对了。这是我的数据结构作业中的一个问题。下面是我实现的代码。是的,我知道它有冗余和低效,但我必须在任务框架内工作

这是我的deleteElement()函数:

template <class T>
void LinkedList<T>::deleteElement(T item)
{
    ListItem<T>* current = head;
    ListItem<T>* temp;
    if (head == NULL) {                // if list is empty end the function
        return;
    }
    while (current) {
        if (current->value == item) {
            if (current == head) {              // if item is in the head
                deleteHead();
            }
            else if (current == getTail()) {    // if item is in the tail
                deleteTail();
            }
            else if (current != head && current != getTail()) { 
            // if item is between two nodes
                temp = current;
                temp->prev->next = temp->next;
                temp->next->prev = temp->prev;
                current->next = NULL;
                current->prev = NULL;
                if (current->next == NULL) {
                    deleteTail();
                }
            }
        }
        current = current->next;
    }
}
模板
void LinkedList::deleteElement(T项)
{
ListItem*当前=头;
列表项*温度;
如果(head==NULL){//如果列表为空,则结束函数
返回;
}
while(当前){
如果(当前->值==项目){
if(current==head){//if项目在head中
deleteHead();
}
else if(current==getTail()){//if项在尾部
deleteTail();
}
如果(当前!=head&¤t!=getTail()){
//如果项目位于两个节点之间
温度=电流;
临时->上一个->下一个=临时->下一个;
临时->下一步->上一步=临时->上一步;
当前->下一步=空;
当前->上一个=空;
如果(当前->下一步==NULL){
deleteTail();
}
}
}
当前=当前->下一步;
}
}

您是否尝试调试代码?可能在
deleteHead()
中使用
head=head->next
如果列表只包含一个元素,则必须为
NULL
,在本例中为
head->prev=NULL将崩溃。