python用链表实现队列的操作细节

python用链表实现队列的操作细节

弹出队首元素也就是链表的第一个结点

当链表中只有一个元素的时候,head属性和rear属性指向的都是第一节点,那么这个时候执行pop方法的时候头节点指向下一个结点(self.head = self.head.next)显然等于None,但是尾结点呢?我们并没有用代码改rear的指向,是不是rear还是指向原来的头结点(也就是被我们删掉的那个结点)?是不是我们是使用self.rear.data能够直接访问到被删除结点的值?

代码如下:

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

class Queue:
    '''
    链表的第一个元素是队列的头部,链表的最后一个元素是对列的尾部
    '''
    def __init__(self):
        self.head = None   #  队首
        self.rear = None  #  指向队尾
        self.lenth = 0

    def is_empty(self):
        return  self.lenth == 0

    def push(self, data):
        node = Node(data)  # 创建一个新的结点
        if self.is_empty():  # 特殊情况
            self.head = node
            self.rear = node
        else:
            self.rear.next = node  # 将原来的尾结点的next属性指向新的结点
            self.rear = node  # 将队列的rear(原来的尾结点)属性指向新的结点
        self.lenth += 1

    def pop(self):
        if self.is_empty():
            raise ValueError('队列为空')
        value = self.head.data
        self.head = self.head.next
        # print(f'队列的头部结点是{self.rear.data}')
        self.lenth -= 1
        return value

到那时好像经过我的实验:
加上一行print()

img


主函数如下:

if __name__ == '__main__':
    queue = Queue()
    queue.push(1)
    print(queue.pop())          # 在内部打印
    print(f'队列的头部结点是{queue.rear.data}')  # 在外部访问

执行结果如图

img

这就意味着rear属性并没有跟着head属性的变化而变化,但是这是为什么?
因为当只有一个结点的时候,head属性和rear属性都是同一个id值,理应来讲,当一个值变化的时候,另一个值也会跟着变化吖

你的头节点可以一直保持none,新增的节点都在节点后增加。判断尾的标准,就是你的next为none。
你的pop操作就是把头后面一个节点返回。如果next为空,则表示没有值了。
可以考虑维护一个尾,这样可以直接在尾添加,不用去找尾