📜  使用双指针删除链表中多次出现的键

📅  最后修改于: 2022-05-13 01:57:43.417000             🧑  作者: Mango

使用双指针删除链表中多次出现的键

给定一个单向链表,删除其中所有出现的给定键。例如,请考虑以下列表。

Input: 2 -> 2 -> 4 -> 3 -> 2
       Key to delete = 2
Output:  4 -> 3 

这主要是这篇文章的替代方案,它使用单独的条件循环来删除给定键的多个出现的头节点和剩余节点。这里我们使用双指针方法来使用单个循环,而不管元素的位置(头、尾或之间)。 Linus Torvalds 在他的“Linux 25 周年”TED 演讲中解释了从链表中删除节点而不需要额外检查头部的原始方法。本文使用该逻辑删除多次重复出现的键,而无需额外检查头部。

解释:
1. 将 head 的地址存储在一个双指针中,直到我们找到一个非“关键”节点。这负责处理头部的特殊情况的第一个 while 循环。
2. 如果节点不是“关键”节点,则将节点->next 的地址存储在 pp 中。
3.如果我们稍后找到“关键”节点,则将pp(最终节点->下一个)更改为指向当前节点->下一个。

以下是相同的 C++ 实现。

// CPP program to delete multiple
// occurrences of a key using single
// loop.
#include 
using namespace std;
  
// A linked list node
struct Node {
    int data;
    struct Node* next;
};
  
struct Node* head = NULL;
  
void printList(struct Node* node)
{
    while (node != NULL) {
        printf(" %d ", node->data);
        node = node->next;
    }
}
  
void push(int new_data)
{
    struct Node* new_node = new Node;
    new_node->data = new_data;
    new_node->next = (head);
    (head) = new_node;
}
  
void deleteEntry(int key)
{
    // Start from head
    struct Node** pp = &head;
    while (*pp) {
  
        struct Node* entry = *pp;
  
        // If key found, then put
        // next at the address of pp
        // delete entry.
        if (entry->data == key) {
            *pp = entry->next;
            delete (entry);
        }
  
        // Else move to next
        else
            pp = &(entry->next);
    }
}
  
int main()
{
    push(2);
    push(2);
    push(4);
    push(3);
    push(2);
  
    int key = 2; // key to delete
  
    puts("Created Linked List: ");
    printList(head);
    printf("\n");
    deleteEntry(key);
    printf("\nLinked List after Deletion of 2: \n");
    printList(head);
    return 0;
}
输出:
Created Linked List: 
 2  3  4  2  2 

Linked List after Deletion of 2: 
 3  4

如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程学生竞争性编程现场课程。