zoukankan      html  css  js  c++  java
  • Title

    Python实现队列

    单链表实现队列

    class Node(object):
        def __init__(self, value=None, next=None):
            self.value, self.next = value, next
    
    
    class LinkedList(object):
        def __init__(self, msxsize=None):
            # msxsize=None代表无限大
            self.maxsize = msxsize
            # self.root 是根节点,根节点的next一般指向头节点head节点
            self.root = Node()
            self.length = 0
            # self.tailnode表示最后一个节点
            self.tailnode = None
    
        def __len__(self):
            return self.length
    
        def append(self, value):
            # 判断当前最大值是否超过了允许的最大值
            if self.maxsize is not None and len(self) > self.maxsize:
                raise Exception("Full")
            node = Node(value)
            tailnode = self.tailnode
            if tailnode is None:
                # 表明现在只有一个root节点, 然后指向当前的node节点即可
                self.root.next = node
            else:
                # 否则把最后一个节点的next指向当前的node节点
                self.tailnode.next = node
            # 更新最后一个节点为node,因为我们把node放到了最后,而self.tailnode代表最后一个节点,所以要更新
            self.tailnode = node
            # 链表长度加一
            self.length += 1
    
        def appendleft(self, value):
            # 定义头节点
            headnode = self.root.next
            node = Node(value)
            # 根节点指向新的head节点: node节点
            self.root.next = node
            # node节点指向之前的head节点
            node.next = headnode
            self.length += 1
    
        def iter_node(self):
            # 第一个节点
            curnode = self.root.next
            # 当前节点不是最后一个节点时
            while curnode is not self.tailnode:
                yield curnode
                # 当前节点更新为下一个节点
                curnode = curnode.next
            # 寻找到最后节点时,也需要把最后一个节点yield出来
            yield curnode
    
        def __iter__(self):
            for node in self.iter_node():
                yield node.value
    
        def remove(self, value):
            """
            删除包含值的一个节点,将其前一个节点的next指向下一个节点即可  O(n)
            :param value:
            :return:
            """
            # 根节点
            prevnode = self.root
            for curnode in self.iter_node():
                if curnode.value == value:
                    prevnode.next = curnode.next
                    if curnode is self.tailnode:
                        # 注意更新 tailnode
                        self.tailnode = prevnode
                    del curnode
                    self.length -= 1
                    # 返回1代表成功
                    return 1
                else:
                    # 更新 prevnode
                    prevnode = curnode
            # 返回-1表示删除失败
            return -1
    
        def find(self, value):
            # O(n)
            index = 0
            for node in self.iter_node():
                if node.value == value:
                    return index
                index += 1
            # 返回-1表示没找到
            return -1
    
        def popleft(self):
            # O(1)
            if self.root.next is None:
                raise Exception("pop from empty LinkedList")
            headnode = self.root.next
            # 根节点指向头节点的下一个节点
            self.root.next = headnode.next
            value = headnode.value
            self.length -= 1
            del headnode
            return value
    
        def clear(self):
            for node in self.iter_node():
                del node
            self.root.next = None
            self.length = 0
    
    
    class FullError(Exception):
        pass
    
    
    class EmptyError(Exception):
        pass
    
    
    class Queue(object):
        def __init__(self, maxsize):
            self.maxsize = maxsize
            self._item_linked_list = LinkedList()
    
        def __len__(self):
            return len(self._item_linked_list)
    
        def push(self, value):
            if self.maxsize is not Node and len(self) >= self.maxsize:
                raise FullError("queue full")
            return self._item_linked_list.append(value)
    
        def pop(self):
            if len(self) == 0:
                raise EmptyError("queue empty")
            return self._item_linked_list.popleft()
    

    循环双端链表实现队列

    class Node(object):
        def __init__(self, value=None, prev=None, next=None):
            self.value, self.prev, self.next = value, prev, next
    
    
    class CirculaDoubleLinkedList(object):
        def __init__(self, msxsize=None):
            # msxsize=None代表无限大
            self.maxsize = msxsize
            node = Node()
            node.next, node.prev = node, node
            self.root = node
            self.length = 0
    
        def __len__(self):
            return self.length
    
        def headnode(self):
            return self.root.next
    
        def tailnode(self):
            # 根节点的prev指向尾节点
            return self.root.prev
    
        def append(self, value):
            # 判断当前最大值是否超过了允许的最大值
            if self.maxsize is not None and len(self) > self.maxsize:
                raise Exception("Full")
            node = Node(value=value)
            tailnode = self.tailnode()
            # 最后一个节点指向新的最后节点
            tailnode.next = node
            # 新的最后节点指向前节点
            node.prev = tailnode
            # node的下一个节点指向root
            node.next = self.root
            # 根节点的上一个节点指向新的最后节点,形成闭环
            self.root.prev = node
            self.length += 1
    
        def appendleft(self, value):
            # 判断当前最大值是否超过了允许的最大值
            if self.maxsize is not None and len(self) > self.maxsize:
                raise Exception("Full")
            node = Node(value=value)
            # 如果根节点的下一个节点是自己,则证明是空的
            if self.root.next is self.root:
                # 新节点的下一个指向根节点
                node.next = self.root
                # 新节点的上一个指向根节点
                node.prev = self.root
                # 根节点的下一个指向新节点
                self.root.next = node
                # 根节点的上一个指向新节点
                self.root.prev = node
            else:
                # 新节点的上一个节点指向根节点
                node.prev = self.root
                # 获取头节点
                headnode = self.headnode()
                # 新节点的下一个指向头节点
                node.next = headnode
                # 头节点的上一个指向新节点
                headnode.prev = node
                # 根节点的下一个指向新节点
                self.root.next = node
                self.length+=1
    
        def remove(self, node):
            # O(1)  node is not value
            if node is self.root:
                return
            else:
                # 被删除节点的上一个节点的next指向被删除节点的下一个节点
                node.prev.next = node.next
                # 被删除节点的下一个节点的prev指向被删除节点的上一个节点
                node.next.prev = node.prev
            self.length -= 1
            return node
    
        def iter_node(self):
            if self.root.next is self.root:
                return
            curnode = self.root.next
            while curnode is not self.root:
                yield curnode
                curnode = curnode.next
            yield curnode
    
        def __iter__(self):
            for node in self.iter_node():
                yield node.value
    
        def iter_node_reverse(self):
            if self.root.next is self.root:
                return
            curnode = self.root.prev
            while curnode is not self.root:
                yield curnode
                curnode = curnode.prev
            yield curnode
    
    
    class Deque(CirculaDoubleLinkedList):
        def pop(self):
            if len(self) == 0:
                raise Exception("empty")
            tailnade = self.tailnode()
            value = tailnade.value
            self.remove(tailnade)
            return value
    
        def popleft(self):
            if len(self) == 0:
                raise Exception("empty")
            headnode = self.headnode()
            value = headnode.value
            self.remove(headnode)
            return value
    

    数组实现队列

    class Array(object):
        def __init__(self, size=32):
            self._size = size
            self._items = [None] * self._size
    
        def __getitem__(self, index):
            return self._items[index]
    
        def __setitem__(self, index, value):
            self._items[index] = value
    
        def __len__(self):
            return self._size
    
        def clear(self, value=None):
            for i in range(len(self._items)):
                self._items[i] = value
    
        def __iter__(self):
            for item in self._items:
                yield item
    
    
    class FullError(Exception):
        pass
    
    
    class EmptyError(Exception):
        pass
    
    
    class ArrayQueue(object):
        def __init__(self, maxsize):
            self.maxsize = maxsize
            self.array = Array(maxsize)
            self.head = 0
            self.tail = 0
    
        def push(self, value):
            if len(self) > self.maxsize:
                raise FullError("queue full")
            # 对数组长度取模,保证下标能到尾部后又从头开始
            self.array[self.head % self.maxsize] = value
            self.head += 1
    
        def pop(self):
            value = self.array[self.tail % self.maxsize]
            self.tail += 1
            return value
    
        def __len__(self):
            return self.head - self.tail
    
  • 相关阅读:
    k8s安装
    jinja +grains 取变量
    项目跨域问题
    Node.js做Web后端优势为什么这么大?
    Chrome使用技巧
    看完这篇操作系统吊打面试官
    几款国产操作系统的区别
    如果红军是一家公司,依然是最后的大赢家
    RPA AI .NET Core 与未来--学习笔记
    Oracle中MERGE INTO用法解析
  • 原文地址:https://www.cnblogs.com/guotianbao/p/12728925.html
Copyright © 2011-2022 走看看