队列

单链表实现队列

"""
队列:
    先进先出, 左出右进, first in first out, FIFO
实现:
    单链表, 双链表, 数组
方法:
    入队 push
    出队 pop
"""


# ######################################################
#  先实现单链表
# ######################################################
class Node(object):
    def __init__(self, value=None,  q_next=None):
        self.value, self.q_next = value, q_next


class LinkList(object):
    def __init__(self, max_size=None):
        self.max_size = max_size
        self.root = Node()
        self.tail_node = None
        self.length = 0

    def __len__(self):
        return self.length

    def append(self, value):
        if self.max_size is not None and len(self) > self.max_size:
            raise Exception('超出链表长度')

        node = Node(value=value)
        if self.tail_node is None:
            self.root.q_next = node
        else:
            self.tail_node.q_next = node

        self.tail_node = node
        self.length += 1

    def append_left(self, value):
        if self.max_size is not None and len(self) > self.max_size:
            raise Exception('超出链表长度')

        node = Node(value=value)
        node.q_next = self.root.q_next
        self.root.q_next = node

        self.length += 1

    def iter_node(self):
        cur_node = self.root.q_next
        while cur_node is not self.tail_node:
            yield cur_node
            cur_node = cur_node.q_next
        yield cur_node

    def __iter__(self):
        for node in self.iter_node():
            yield node.value

    def remove(self, value):
        pre_node = self.root
        cur_node = self.root.q_next

        for node in self.iter_node():
            if node.value == value:
                pre_node.q_next = node.q_next
                if node is self.tail_node:
                    self.tail_node = pre_node
                del node
                self.length -= 1
                return 1
            else:
                pre_node = node
        return -1

    def find(self, value):
        index = 0
        for node in self.iter_node():
            if node.value == value:
                return index
            index += 1
        return -1

    def pop_left(self):
        if self.root.q_next is None:
            raise Exception('空列表')
        headnode = self.root.q_next
        self.root.q_next = headnode.q_next
        value = headnode.value
        del headnode
        self.length -= 1

        return value

    def clear(self):
        for node in self.iter_node():
            del node
        self.root.q_next = None
        self.length = 0


# ######################################################
#  直接调用单链表实现队列
# ######################################################
class FullError(Exception):
    pass


class EmptyError(Exception):
    pass


class Queue(object):
    def __init__(self, max_size=None):
        self.max_size = max_size
        self._items_link_list = LinkList(max_size)

    def __len__(self):
        return len(self._items_link_list)

    def push(self, value):
        if self.max_size is not None and len(self) >= self.max_size:
            raise FullError('queue full')
        self._items_link_list.append(value)

    def pop(self):
        if len(self) <= 0:
            raise EmptyError('queue empty')
        return self._items_link_list.pop_left()

数组实现队列

"""
队列:
    先进先出, 左出右进, first in first out, FIFO
实现:
    单链表, 双链表, 数组
方法:
    入队 push
    出队 pop
"""


# ######################################################
#  先实现数组
# ######################################################
class MyArray(object):
    def __init__(self, size=32):
        self.size = size
        self._items = [None]*self.size

    def __getitem__(self, item):
        return self._items[item]

    def __setitem__(self, item, value=None):
        self._items[item] = 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


# def test_array():
#     a = MyArray(10)
#     a[0] = 99
#     a[1] = 33
#     assert a[0] == 99
#     assert a[1] == 33.
#     assert 0


# ######################################################
#  数组实现队列
# ######################################################
class FullQueueError(Exception):
    pass


class EmptyQueueError(Exception):
    pass


class ArrayQueue(object):
    def __init__(self, size=32):
        self.size = size
        self._array = MyArray(self.size)
        self.head = 0  # 用于屁股后面追加的指针
        self.tail = 0  # 用于头部删除的指针

    def __len__(self):
        return self.head-self.tail

    def push(self, value=None):
        if len(self) >= self.size:
            raise FullQueueError('队列满了')

        self._array[self.head % self.size] = value
        self.head += 1

    def pop(self):
        if len(self) <= 0:
            raise EmptyQueueError('队列为空')
        value = self._array[self.tail % self.size]
        self.tail += 1
        return value

双端队列

"""
双端队列 python 其实已经实现了,在 collections.deque()
几个重要的操作:append(), appendleft(), clear(), pop(), popleft()
最高效,O(1)实现
"""


# ##############################
# 先实现循环双链表
# #############################
class Node(object):
    def __init__(self, value=None, prev=None, next=None):
        self.prev = prev
        self.next = next
        self.value = value


class CircularDoublyLinkedList(object):

    def __init__(self, max_size=None):
        self.max_size = max_size  # None 表示无限长度
        node = Node()
        node.next, node.prev = node, node  # 根节点自己实现闭环
        self.root = node
        self.length = 0  # root节点不计算在链表的长度中

    def __len__(self):
        return self.length

    def head_node(self):
        return self.root.next

    def tail_node(self):
        return self.root.prev

    def append(self, value):
        if self.max_size is not None and len(self) > self.max_size:
            raise Exception('full')

        node = Node()
        tailnode = self.tail_node()

        tailnode.next = node
        node.prev = tailnode
        node.next = self.root
        self.root.prev = node
        node.value = value

        self.length += 1

    def append_left(self, value):
        if self.max_size is not None and len(self) > self.max_size:
            raise Exception('full')
        node = Node(value=value)

        if self.root.next is self.root:  # 链表为空
            self.root.next = node
            self.root.prev = node
            node.next = self.root
            node.prev = self.root
        else:
            headnode = self.root.next
            self.root.next = node
            node.next = headnode
            headnode.prev = node
            node.prev = self.root

        self.length += 1

    def remove(self, node):  # 入参 node 而不是 value
        if node is self.root:
            return
        else:
            node.prev.next = node.next
            node.next.prev = node.prev
        self.length -= 1
        return node

    def iter_node(self):
        if self.root.next is self.root:
            return

        cur_node = self.root.next
        while cur_node is not self.root:
            yield cur_node
            cur_node = cur_node.next
        # yield cur_node

    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

        cur_node = self.root.prev
        while cur_node.prev is not self.root:
            yield cur_node
            cur_node = cur_node.prev
        yield cur_node

    def insert(self, value, new_value):
        for node in self.iter_node():
            if node.value == value:
                new_node = Node(value=new_value)
                new_node.next = node
                new_node.prev = node.prev
                node.prev.next = new_node

                node.prev = new_node
                break


# ##############################
# 实现双端队列
# #############################
class FullError(Exception):
    pass


class EmptyError(Exception):
    pass


class DoubleQueue(object):
    def __init__(self, max_size=50):
        self.max_size = max_size
        self._double_link_list = CircularDoublyLinkedList(self.max_size)

    def __len__(self):
        return len(self._double_link_list)

    def append(self, value):
        if self.max_size is not None and len(self) >= self.max_size:
            raise FullError('queue full')
        self._double_link_list.append(value)

    def append_left(self, value):
        if self.max_size is not None and len(self) >= self.max_size:
            raise FullError('queue full')
        self._double_link_list.append_left(value)

    # TODO 实现做删除和有删除

 

posted @ 2020-05-05 02:38  SBJBA  阅读(79)  评论(0)    收藏  举报