📜  门| GATE CS 2021 |设置 2 |问题 5(1)

📅  最后修改于: 2023-12-03 15:42:12.961000             🧑  作者: Mango

门| GATE CS 2021 |设置 2 |问题 5

本题是GATE计算机科学考试的一个问题,要求编写一个Python程序来实现一个双向链表的初始化、插入和删除操作。

双向链表

首先我们来了解一下什么是双向链表。双向链表是一种链式数据结构,每个节点包含了两个指针,一个指向前一个节点,一个指向后一个节点,因此可以从头到尾或者从尾到头遍历整个链表。

问题描述

在 GATE CS 2021 |设置 2 |问题 5 中,问题要求实现一个双向链表类,支持双向链表的初始化、插入和删除操作。具体的要求如下:

  1. 链表初始化函数为:
def __init__(self):
    """
    Initialize your data structure here.
    """
  1. 向链表中插入一个元素的函数为:
def insert(self, val: int) -> None:
    """
    Inserts a value to the front of the doubly linked list.
    """
  1. 从链表中删除给定值的元素的函数为:
def delete(self, val: int) -> None:
    """
    Deletes all occurrences of the given value in the doubly linked list.
    """
解题思路

要实现双向链表的初始化、插入和删除操作,我们可以首先创建一个双向链表的节点类:

class ListNode:
    def __init__(self, val=0, prev=None, next=None):
        self.val = val
        self.prev = prev
        self.next = next

在链表初始化函数中,我们新建一个指向头节点和尾节点的指针,并将它们都指向None,表示双向链表为空:

class MyLinkedList:

    def __init__(self):
        """
        Initialize your data structure here.
        """
        self.head = None
        self.tail = None

在插入元素的操作中,我们可以通过新建一个双向链表节点,并设置节点的前向指针和后向指针,将其插入到链表的头部:

def insert(self, val: int) -> None:
    """
    Inserts a value to the front of the doubly linked list.
    """
    new_node = ListNode(val)
    if not self.head:
        self.head = self.tail = new_node
    else:
        new_node.next = self.head
        self.head.prev = new_node
        self.head = new_node

在删除元素的操作中,我们需要遍历整个链表,查找给定值的节点,并分别更新指向该节点的前向指针和后向指针,最后将该节点删除:

def delete(self, val: int) -> None:
    """
    Deletes all occurrences of the given value in the doubly linked list.
    """
    node = self.head
    while node:
        if node.val == val:
            if node.prev:
                node.prev.next = node.next
            else:
                self.head = node.next
            if node.next:
                node.next.prev = node.prev
            else:
                self.tail = node.prev
        node = node.next
完整代码
class ListNode:
    def __init__(self, val=0, prev=None, next=None):
        self.val = val
        self.prev = prev
        self.next = next


class MyLinkedList:

    def __init__(self):
        """
        Initialize your data structure here.
        """
        self.head = None
        self.tail = None

    def get(self, index: int) -> int:
        """
        Get the value of the index-th node in the linked list. If the index is invalid, return -1.
        """
        node = self.head
        for i in range(index):
            if not node:
                return -1
            node = node.next
        return node.val if node else -1

    def addAtHead(self, val: int) -> None:
        """
        Add a node of value val before the first element of the linked list. After the insertion,
        the new node will be the first node of the linked list.
        """
        new_node = ListNode(val)
        if not self.head:
            self.head = self.tail = new_node
        else:
            new_node.next = self.head
            self.head.prev = new_node
            self.head = new_node

    def addAtTail(self, val: int) -> None:
        """
        Append a node of value val to the last element of the linked list.
        """
        new_node = ListNode(val)
        if not self.tail:
            self.head = self.tail = new_node
        else:
            new_node.prev = self.tail
            self.tail.next = new_node
            self.tail = new_node

    def addAtIndex(self, index: int, val: int) -> None:
        """
        Add a node of value val before the index-th node in the linked list.
        If index equals to the length of linked list,
        the node will be appended to the end of linked list. If index is greater than the length,
        the node will not be inserted.
        """
        if index < 0:
            self.addAtHead(val)
        else:
            new_node, node = ListNode(val), self.head
            for i in range(index):
                if not node:
                    return
                node = node.next
            if not node:
                self.tail.next = new_node
                new_node.prev = self.tail
                self.tail = new_node
            else:
                new_node.prev = node.prev
                new_node.next = node
                if node.prev:
                    node.prev.next = new_node
                else:
                    self.head = new_node
                node.prev = new_node

    def deleteAtIndex(self, index: int) -> None:
        """
        Delete the index-th node in the linked list, if the index is valid.
        """
        node = self.head
        for i in range(index):
            if not node:
                return
            node = node.next
        if not node:
            return
        if node.prev:
            node.prev.next = node.next
        else:
            self.head = node.next
        if node.next:
            node.next.prev = node.prev
        else:
            self.tail = node.prev
总结

本题要求实现一个双向链表的类,并支持双向链表的初始化、插入和删除操作,是比较经典的链表操作之一。在实现时,我们需要首先设计一个双向链表节点的类,然后在双向链表类中实现初始化函数和插入/删除元素的操作函数。