算法学习day10----单链表习题

刚把单链表的内容更新完,马不停蹄来了习题

前面我们说道,单链表是一个非常结构化的开发数据类型,当我们对链表进行操作时,基于在操作开始前的链表创建、增删查改操作函数的调用,至于调用顺序、调用次数,则取决于题目要求。

算法学习day10----单链表习题_第1张图片

前排部分结构化开发没毛病,但是有几个需要注意的点,对于第k个插入与删除的数,是按照输入的时间顺序发生的:

例如:

操作1:H 1 -> 链表:1,nodes[1]=节点1

操作2:I 1 2 -> 在节点1后面插入2 -> 链表:1->2,nodes[2]=节点2

操作3:H 3 -> 链表:3->1->2,nodes[3]=节点3

然后,删除操作:

操作4:D 1 -> 删除第1个插入的节点(节点1)后面的节点(节点2),链表变为:3->1

操作5:D 0 -> 删除头结点(节点3),链表变为:1

对此,需要一个变量idx,记录当前插入的节点是第几个(从1开始),还需要一个数组nodes,用于存储第i个插入的节点(i从1开始,但注意:删除节点后,这个节点在数组中仍然存在,但是我们不会在链表中有这个节点了,不过我们后续操作不会使用到被删除的节点,因为k的取值是之前插入操作的序号,不会重复使用同一个k,所以我们可以存储)

例如:

操作1:H 1 -> 插入头节点1,idx=1,nodes[1] = 节点1。

操作2:H 2 -> 插入头节点2,idx=2,nodes[2] = 节点2。此时链表:2->1

操作3:I 1 3 -> 在第1个插入的节点(即节点1)后面插入3,idx=3,nodes[3]=节点3。此时链表:2->1->3

操作4:D 1 -> 删除第1个插入的节点后面的节点(即节点1后面的节点3),链表变为:2->1

操作5:D 0 -> 删除头结点(即节点2),链表变为:1(画个图就容易理解)

算法学习day10----单链表习题_第2张图片

对此,进行这些改动后,即可进行结构化编写代码:

class LNode:
    def __init__(self, elem, next_=None):
        self.elem = elem
        self.next_ = next_

class LList:
    def __init__(self, max_ops):
        self.head = None
       
        self.nodes = [None] * (max_ops + 1)// 在初始化链表时,传入max_ops(最大操作次数)。因为最多有M次操作,而每次插入操作(头插或指定位置插入)都会创建一个新节点。
预先分配一个长度为max_ops+1的数组(索引0不使用,因为题目中k从1开始,但注意k=0有特殊含义)。
这样,我们就可以按照插入的顺序(从1到M)把节点存储在数组中。
        self.idx = 0  //计数器
    
    def insert_head(self, x):
       
        self.idx += 1
        node = LNode(x)
        if self.head is None:
            self.head = node
        else:
            node.next_ = self.head
            self.head = node
      
        self.nodes[self.idx] = node
    
    def insert_after(self, k, x):
        
        self.idx += 1
        node = LNode(x)
        
        prev_node = self.nodes[k]
        node.next_ = prev_node.next_
        prev_node.next_ = node
     
        self.nodes[self.idx] = node
    
    def remove_after(self, k):
      
        if k == 0:
           
            if self.head is not None:
                self.head = self.head.next_
        else:
            
            prev_node = self.nodes[k]
            if prev_node.next_ is not None:
                prev_node.next_ = prev_node.next_.next_
    
    def traverse(self):
        
        cur = self.head
        res = []
        while cur is not None:
            res.append(str(cur.elem))
            cur = cur.next_
        return res //遍历链表并返回所有元素的字符串列表

def main():
    import sys
    input = sys.stdin.readline
    
    M = int(input().strip())
    llist = LList(M) 
    
    for _ in range(M):
        data = input().split()
        
        op = data[0]//二、三元数据头列是操作判断符,依据不同判断符进行不同输入操作
        if op == 'H':
            x = int(data[1])
            llist.insert_head(x)
        elif op == 'D':
            k = int(data[1])
            llist.remove_after(k)
        elif op == 'I':
            k, x = int(data[1]), int(data[2])
            llist.insert_after(k, x)
    
   
    print(' '.join(llist.traverse()))

if __name__ == "__main__":
    main()

此处有一个快读代码:
 

import sys
    input = sys.stdin.readline

是赛事环境常用,可以码住

你可能感兴趣的:(算法,学习)