📜  门|门 CS 1997 |第 65 题(1)

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

门|门 CS 1997 |第 65 题

本题目为2003年NOI题目,题目要求实现一个双向链表的功能。具体要求如下:

题目描述

给你一个长度为n的双向链表,由一个头指针和一个尾指针指向表头和表尾。你需要支持以下操作:

  1. move(): 将头指针往表尾移动。
  2. insert(k, x): 在第$k$个元素后插入$x$。
  3. print(): 从头到尾输出整个链表。
输入格式

输入共 $m+1$ 行。

第1行包含$2$个整数$n,m$,表示链表长度和操作数量。

接下来$m$行,每行一个操作,格式如下:

  • M: 执行move()操作
  • I k x: 执行insert(k, x)操作,其中$1 \leq k \leq n+1, |x| \leq 1000$
  • P: 执行print()操作
输出格式

对于每个P操作,输出一行代表当前链表从头到尾的元素。

样例

输入样例:

5 5
P
I 1 2
M
P
I 3 3
P

输出样例:

2 1 5 4 3
2 1 5 4 3
2 1 3 5 4
解题思路

使用链表(List)来存储数据,使用头指针和尾指针来支持双向链表的插入和移动操作,具体实现过程如下:

class Node:
    def __init__(self, data):
        self.data = data
        self.prev = None
        self.next = None

class List:
    def __init__(self):
        self.head = None
        self.tail = None

    def insert(self, k, x):
        node = Node(x)
        if k == 1:
            node.next = self.head
            self.head.prev = node
            self.head = node
        else:
            p = self.head
            for i in range(k-2):
                p = p.next
            node.next = p.next
            p.next.prev = node
            node.prev = p
            p.next = node
        return node

    def move(self):
        self.tail.next = self.head
        self.head.prev = self.tail
        self.tail = self.head
        self.head = self.head.next
        self.head.prev = None
        self.tail.next = None

    def print(self):
        p = self.head
        while p is not None:
            print(p.data, end=' ')
            p = p.next
        print()

其中,insert操作分为在链表头插入和在链表中间插入两种情况,需要分别处理。move操作则需要将链表的尾节点连接到头节点,再将头节点移到下一个位置,同时更新节点的前驱和后继指针。print操作则是简单地按顺序输出链表中存储的数据。

总结

本题目难度中等,考察了链表及指针的基本应用,是一道不错的算法练习题。