您好,欢迎来到五一七教育网。
搜索
您的当前位置:首页【C++】删除单链表中特定值的节点

【C++】删除单链表中特定值的节点

来源:五一七教育网

介绍

在编程中,处理链表是一个基本的技能,本位主要介绍如何删除特定的节点。这是一个非常常见的操作。

问题陈述

给定一个单链表,我们需要实现一个函数,该函数接受一个值作为输入,并在链表中删除具有该值的所有节点。最终,我们将返回修改后的链表。

解决方案

我们将通过遍历链表来找到并删除目标值的节点。具体来说,我们将保持两个指针:一个用于当前节点,另一个用于追踪前一个节点。当我们找到目标值时,我们将通过修改前一个节点的next指针来删除当前节点。

算法

  • 将前一个节点的next指针指向当前节点的下一个节点。
  • 释放当前节点的内存。
  • 将当前节点指针移动到下一个节点。
  1. 否则,更新prev指针为当前节点,将当前节点指针移动到下一个节点。
  2. 返回修改后的链表。

代码实现

#include <bits/stdc++.h>
using namespace std;

struct Node {
    int data;
    Node* next;
    Node(int val) : data(val), next(nullptr) {}
};

class LinkedList {
private:
    Node* head;

public:
    LinkedList() : head(nullptr) {}

    void append(int val) {
        if (!head) {
            head = new Node(val);
            return;
        }
        Node* temp = head;
        while (temp->next) {
            temp = temp->next;
        }
        temp->next = new Node(val);
    }

    void deleteNode(int key) {
        Node* current = head;
        Node* prev = nullptr;

        while (current) {
            if (current->data == key) {
                if (prev)
                    prev->next = current->next;
                else
                    head = current->next;
                
                Node* temp = current;
                current = current->next;
                delete temp;
            } else {
                prev = current;
                current = current->next;
            }
        }
    }

    void display() {
        Node* temp = head;
        while (temp) {
            cout << temp->data << " ";
            temp = temp->next;
        }
        cout << endl;
    }
};

int main() {
    LinkedList linkedList;
    linkedList.append(1);
    linkedList.append(2);
    linkedList.append(3);
    linkedList.append(4);

    cout << "原始链表:" << endl;
    linkedList.display();

    linkedList.deleteNode(3);

    cout << "删除节点后的链表:" << endl;
    linkedList.display();

    return 0;
}

示例与测试

int main() {
    LinkedList linkedList;
    linkedList.append(1);
    linkedList.append(2);
    linkedList.append(3);
    linkedList.append(4);

    cout << "原始链表:" << std::endl;
    linkedList.display();

    linkedList.deleteNode(3);

    cout << "删除节点后的链表:" << std::endl;
    linkedList.display();

    return 0;
}

注意点**

deleteNode()函数中有这么一串负责删除的代码:

            if (current->data == key) {
                if (prev)
                    prev->next = current->next;
                else
                    head = current->next;
                
                Node* temp = current;
                current = current->next;
                delete temp;
            }

删除之前为什么要进行 i f ( p r e v ) if(prev) if(prev)的判定呢,这是因为在删除单链表中的节点时,我们需要考虑两种情况:

  1. 如果要删除的节点是头节点。
  2. 如果要删除的节点不是头节点。

当要删除的节点是头节点时,我们需要更新链表的头指针,使其指向被删除节点的下一个节点。而如果要删除的节点不是头节点,我们需要将前一个节点的next指针指向被删除节点的下一个节点,以确保链表仍然保持连续性。

因此,在代码中的if (prev)判定的目的是检查是否存在前一个节点。如果前一个节点存在,我们可以安全地更新前一个节点的next指针,以删除当前节点。如果前一个节点不存在(即当前节点是头节点),我们需要特别处理,将链表的头指针指向当前节点的下一个节点。

其他写法对比

版本一:

void Delete LinkList(LNode * L,int key) 
{
	//删除以L为头结点的单链表中值为key的第一个节点
	LNode *p=L,*q=L->next;
	while(q!=NULL&&q->data!=key){p=q;q=q->next;}
	if(q->data==key){p->next=q->next;free();}
	else printf("NULL\n");
}

版本二:

	while(p->next!=NULL&&p->next->data!=key){p=p->next;}
	if(p->next->data==key)
	{
		q=p->next;
		p->next=q->next;
		free();
	}

这两个版本的区别是版本一是判断当前节点是否为空以及是否为目标值,而版本二则是针对下一个节点进行判断,版本一的好处就是能够保证最后停留的节点不是NULL,然后在进行是否是目标节点的判断,但是版本二无法保证最后停止的节点是否为NULL,所以上面的写法是错误的,需要在if语句前面加上一个是否是NULL的判断,否则p==NULL的情况下进行p->next->data操作会出现bug。

因篇幅问题不能全部显示,请点此查看更多更全内容

Copyright © 2019- 517ttc.cn 版权所有 赣ICP备2024042791号-8

违法及侵权请联系:TEL:199 18 7713 E-MAIL:2724546146@qq.com

本站由北京市万商天勤律师事务所王兴未律师提供法律服务