python算法与数据结构(6)队列,单链表实现队列

队列:先进先出。 FIFO结构。5,4,3,2,1
如何FIFO呢?
已经学了array(数组) ,list(列表), linkedlist(单链表), DLL(双链表)
队列实现需要push(入队)和从队首pop(出队)
list 插入时间复杂度较高,
单链表:popleft和append都是O(1)。可以使用。
双链表:也可以用,但是实现相对复杂。
这里使用单链表实现队列:
方便查看直接把04章的单链表代码拷贝过来。

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


class LinkedList(object):
    def __init__(self, maxsize=None):
        self.maxsize = maxsize
        self.root = Node()
        self.length = 0
        self.tailnode = None

    def __len__(self):
        return self.length

    def append(self, value):
        if self.maxsize is not None and len(self) > self.maxsize:
            return Exception("Full")
        node = Node(value)
        tailnode = self.tailnode
        if tailnode is None:  # 第一个插入的值作为root入口的下一个节点。
            self.root.next = node
        else:
            tailnode.next = node  # 后面每加一个值就作为尾节点。
        self.tailnode = node
        self.length += 1

    def appendLeft(self, value):
        headnode = self.root.next
        node = Node(value)
        self.root.next = node
        node.next = headnode
        self.length += 1

    def iter_node(self):
        # 遍历节点,每次返回当前节点的下一个节点
        currnode = self.root.next
        while currnode is not self.tailnode:
            yield currnode
            currnode = currnode.next
        yield currnode  # 返回最后的尾节点

    def __iter__(self):  # 需要和上面函数配合完成遍历节点
        for node in self.iter_node():
            yield node.value

    def remove(self, value):  # O(n)
        prenode = self.root
        currnode = self.root.next
        while currnode.next is not None:
            if currnode.value == value:
                prenode.next = currnode.next
                del currnode
                self.length -= 1
                return

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

    def popleft(self):  # O(1)
        if self.root.next is None:
            raise Exception("pop from empty.")
        headnode = self.root.next
        self.root.next = headnode.next
        self.length -= 1
        value = headnode.value
        del headnode
        return value

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


def test_linked_list():
    ll = LinkedList()

    ll.append(0)
    ll.append(1)
    ll.append(2)

    assert len(ll) == 3
    assert ll.find(2) == 2
    assert ll.find(3) == -1

    ll.remove(0)
    assert len(ll) == 2
    assert ll.find(0) == -1

    assert list(ll) == [1, 2]

    ll.appendLeft(0)
    assert list(ll) == [0, 1, 2]
    assert len(ll) == 3

    headvalue = ll.popleft()
    assert headvalue == 0
    assert len(ll) == 2
    assert list(ll) == [1, 2]

    ll.clear()
    assert len(ll) == 0


"""下面实现队列"""


class FullError(Exception):
    pass


class EmptyError(Exception):
    pass


class Queue(object):
    def __init__(self, maxsize=None):
        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 None 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()


def test_queue():
    q = Queue()
    q.push(0)
    q.push(1)
    q.push(2)
    assert len(q) == 3
    assert q.pop() == 0
    assert q.pop() == 1
    assert q.pop() == 2


发布了48 篇原创文章 · 获赞 0 · 访问量 755

猜你喜欢

转载自blog.csdn.net/qq_36710311/article/details/104635420