栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

python:实现双端队列算法(附完整源码)

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

python:实现双端队列算法(附完整源码)

python:实现双端队列算法

from __future__ import annotations
from collections.abc import Iterable
from dataclasses import dataclass
from typing import Any


class Deque:
    """
    Deque data structure.
    Operations
    ----------
    append(val: Any) -> None
    appendleft(val: Any) -> None
    extend(iter: Iterable) -> None
    extendleft(iter: Iterable) -> None
    pop() -> Any
    popleft() -> Any
    Observers
    ---------
    is_empty() -> bool
    Attributes
    ----------
    _front: _Node
        front of the deque a.k.a. the first element
    _back: _Node
        back of the element a.k.a. the last element
    _len: int
        the number of nodes
    """

    __slots__ = ["_front", "_back", "_len"]

    @dataclass
    class _Node:
        """
        Representation of a node.
        Contains a value and a pointer to the next node as well as to the previous one.
        """

        val: Any = None
        next: Deque._Node | None = None
        prev: Deque._Node | None = None

    class _Iterator:
        """
        Helper class for iteration. Will be used to implement iteration.
        Attributes
        ----------
        _cur: _Node
            the current node of the iteration.
        """

        __slots__ = ["_cur"]

        def __init__(self, cur: Deque._Node | None) -> None:
            self._cur = cur

        def __iter__(self) -> Deque._Iterator:
            """
            >>> our_deque = Deque([1, 2, 3])
            >>> iterator = iter(our_deque)
            """
            return self

        def __next__(self) -> Any:
            """
            >>> our_deque = Deque([1, 2, 3])
            >>> iterator = iter(our_deque)
            >>> next(iterator)
            1
            >>> next(iterator)
            2
            >>> next(iterator)
            3
            """
            if self._cur is None:
                # finished iterating
                raise StopIteration
            val = self._cur.val
            self._cur = self._cur.next

            return val

    def __init__(self, iterable: Iterable[Any] | None = None) -> None:
        self._front: Any = None
        self._back: Any = None
        self._len: int = 0

        if iterable is not None:
            # append every value to the deque
            for val in iterable:
                self.append(val)

    def append(self, val: Any) -> None:
        """
        Adds val to the end of the deque.
        Time complexity: O(1)
        >>> our_deque_1 = Deque([1, 2, 3])
        >>> our_deque_1.append(4)
        >>> our_deque_1
        [1, 2, 3, 4]
        >>> our_deque_2 = Deque('ab')
        >>> our_deque_2.append('c')
        >>> our_deque_2
        ['a', 'b', 'c']
        >>> from collections import deque
        >>> deque_collections_1 = deque([1, 2, 3])
        >>> deque_collections_1.append(4)
        >>> deque_collections_1
        deque([1, 2, 3, 4])
        >>> deque_collections_2 = deque('ab')
        >>> deque_collections_2.append('c')
        >>> deque_collections_2
        deque(['a', 'b', 'c'])
        >>> list(our_deque_1) == list(deque_collections_1)
        True
        >>> list(our_deque_2) == list(deque_collections_2)
        True
        """
        node = self._Node(val, None, None)
        if self.is_empty():
            # front = back
            self._front = self._back = node
            self._len = 1
        else:
            # connect nodes
            self._back.next = node
            node.prev = self._back
            self._back = node  # assign new back to the new node

            self._len += 1

            # make sure there were no errors
            assert not self.is_empty(), "Error on appending value."

    def appendleft(self, val: Any) -> None:
        """
        Adds val to the beginning of the deque.
        Time complexity: O(1)
        >>> our_deque_1 = Deque([2, 3])
        >>> our_deque_1.appendleft(1)
        >>> our_deque_1
        [1, 2, 3]
        >>> our_deque_2 = Deque('bc')
        >>> our_deque_2.appendleft('a')
        >>> our_deque_2
        ['a', 'b', 'c']
        >>> from collections import deque
        >>> deque_collections_1 = deque([2, 3])
        >>> deque_collections_1.appendleft(1)
        >>> deque_collections_1
        deque([1, 2, 3])
        >>> deque_collections_2 = deque('bc')
        >>> deque_collections_2.appendleft('a')
        >>> deque_collections_2
        deque(['a', 'b', 'c'])
        >>> list(our_deque_1) == list(deque_collections_1)
        True
        >>> list(our_deque_2) == list(deque_collections_2)
        True
        """
        node = self._Node(val, None, None)
        if self.is_empty():
            # front = back
            self._front = self._back = node
            self._len = 1
        else:
            # connect nodes
            node.next = self._front
            self._front.prev = node
            self._front = node  # assign new front to the new node

            self._len += 1

            # make sure there were no errors
            assert not self.is_empty(), "Error on appending value."

    def extend(self, iter: Iterable[Any]) -> None:
        """
        Appends every value of iter to the end of the deque.
        Time complexity: O(n)
        >>> our_deque_1 = Deque([1, 2, 3])
        >>> our_deque_1.extend([4, 5])
        >>> our_deque_1
        [1, 2, 3, 4, 5]
        >>> our_deque_2 = Deque('ab')
        >>> our_deque_2.extend('cd')
        >>> our_deque_2
        ['a', 'b', 'c', 'd']
        >>> from collections import deque
        >>> deque_collections_1 = deque([1, 2, 3])
        >>> deque_collections_1.extend([4, 5])
        >>> deque_collections_1
        deque([1, 2, 3, 4, 5])
        >>> deque_collections_2 = deque('ab')
        >>> deque_collections_2.extend('cd')
        >>> deque_collections_2
        deque(['a', 'b', 'c', 'd'])
        >>> list(our_deque_1) == list(deque_collections_1)
        True
        >>> list(our_deque_2) == list(deque_collections_2)
        True
        """
        for val in iter:
            self.append(val)

    def extendleft(self, iter: Iterable[Any]) -> None:
        """
        Appends every value of iter to the beginning of the deque.
        Time complexity: O(n)
        >>> our_deque_1 = Deque([1, 2, 3])
        >>> our_deque_1.extendleft([0, -1])
        >>> our_deque_1
        [-1, 0, 1, 2, 3]
        >>> our_deque_2 = Deque('cd')
        >>> our_deque_2.extendleft('ba')
        >>> our_deque_2
        ['a', 'b', 'c', 'd']
        >>> from collections import deque
        >>> deque_collections_1 = deque([1, 2, 3])
        >>> deque_collections_1.extendleft([0, -1])
        >>> deque_collections_1
        deque([-1, 0, 1, 2, 3])
        >>> deque_collections_2 = deque('cd')
        >>> deque_collections_2.extendleft('ba')
        >>> deque_collections_2
        deque(['a', 'b', 'c', 'd'])
        >>> list(our_deque_1) == list(deque_collections_1)
        True
        >>> list(our_deque_2) == list(deque_collections_2)
        True
        """
        for val in iter:
            self.appendleft(val)

    def pop(self) -> Any:
        """
        Removes the last element of the deque and returns it.
        Time complexity: O(1)
        @returns topop.val: the value of the node to pop.
        >>> our_deque = Deque([1, 2, 3, 15182])
        >>> our_popped = our_deque.pop()
        >>> our_popped
        15182
        >>> our_deque
        [1, 2, 3]
        >>> from collections import deque
        >>> deque_collections = deque([1, 2, 3, 15182])
        >>> collections_popped = deque_collections.pop()
        >>> collections_popped
        15182
        >>> deque_collections
        deque([1, 2, 3])
        >>> list(our_deque) == list(deque_collections)
        True
        >>> our_popped == collections_popped
        True
        """
        # make sure the deque has elements to pop
        assert not self.is_empty(), "Deque is empty."

        topop = self._back
        self._back = self._back.prev  # set new back
        self._back.next = (
            None  # drop the last node - python will deallocate memory automatically
        )

        self._len -= 1

        return topop.val

    def popleft(self) -> Any:
        """
        Removes the first element of the deque and returns it.
        Time complexity: O(1)
        @returns topop.val: the value of the node to pop.
        >>> our_deque = Deque([15182, 1, 2, 3])
        >>> our_popped = our_deque.popleft()
        >>> our_popped
        15182
        >>> our_deque
        [1, 2, 3]
        >>> from collections import deque
        >>> deque_collections = deque([15182, 1, 2, 3])
        >>> collections_popped = deque_collections.popleft()
        >>> collections_popped
        15182
        >>> deque_collections
        deque([1, 2, 3])
        >>> list(our_deque) == list(deque_collections)
        True
        >>> our_popped == collections_popped
        True
        """
        # make sure the deque has elements to pop
        assert not self.is_empty(), "Deque is empty."

        topop = self._front
        self._front = self._front.next  # set new front and drop the first node
        self._front.prev = None

        self._len -= 1

        return topop.val

    def is_empty(self) -> bool:

        return self._front is None

    def __len__(self) -> int:

        return self._len

    def __eq__(self, other: object) -> bool:


        if not isinstance(other, Deque):
            return NotImplemented

        me = self._front
        oth = other._front

        # if the length of the deques are not the same, they are not equal
        if len(self) != len(other):
            return False

        while me is not None and oth is not None:
            # compare every value
            if me.val != oth.val:
                return False
            me = me.next
            oth = oth.next

        return True

    def __iter__(self) -> Deque._Iterator:

        return Deque._Iterator(self._front)

    def __repr__(self) -> str:

        values_list = []
        aux = self._front
        while aux is not None:
            # append the values in a list to display
            values_list.append(aux.val)
            aux = aux.next

        return "[" + ", ".join(repr(val) for val in values_list) + "]"


if __name__ == "__main__":
    import doctest

    doctest.testmod()

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/1021044.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号