OOP作业四

队列ADT(抽象数据类型)如下所示:

Q.enqueue(e)
Add element e to the back of queue Q.
Q.dequeue()
Remove and return the first element from queue Q;
an error occurs if the queue is empty.
Q.first()
Return a reference to the element at the front of queue Q,
without removing it; an error occurs if the queue is empty.
Q.is_empty()
Return True if queue Q does not contain any elements.
len(Q)
Return the number of elements in queue Q;
in Python, we implement this with the special method __len__
使用一个Python列表来实现上面的队列ADT(抽象数据类型),也使用一个循环数组来实现相同的队列ADT
下面是array_stack.py
"""Basic example of an adapter class to provide a stack interface to Python's list."""

#from ..exceptions import Empty
class Empty(Exception):
  pass

class ArrayStack:
  """LIFO Stack implementation using a Python list as underlying storage."""

  def __init__(self):
    """Create an empty stack."""
    self._data = []                       # nonpublic list instance

  def __len__(self):
    """Return the number of elements in the stack."""
    return len(self._data)

  def is_empty(self):
    """Return True if the stack is empty."""
    return len(self._data) == 0

  def push(self, e):
    """Add element e to the top of the stack."""
    self._data.append(e)                  # new item stored at end of list

  def top(self):
    """Return (but do not remove) the element at the top of the stack.

    Raise Empty exception if the stack is empty.
    """
    if self.is_empty():
      raise Empty('Stack is empty')
    return self._data[-1]                 # the last item in the list

  def pop(self):
    """Remove and return the element from the top of the stack (i.e., LIFO).

    Raise Empty exception if the stack is empty.
    """
    if self.is_empty():
      raise Empty('Stack is empty')
    return self._data.pop()               # remove last item from list

if __name__ == '__main__':
  S = ArrayStack()                 # contents: [ ]
  S.push(5)                        # contents: [5]
  S.push(3)                        # contents: [5, 3]
  print(len(S))                    # contents: [5, 3];    outputs 2
  print(S.pop())                   # contents: [5];       outputs 3
  print(S.is_empty())              # contents: [5];       outputs False
  print(S.pop())                   # contents: [ ];       outputs 5
  print(S.is_empty())              # contents: [ ];       outputs True
  S.push(7)                        # contents: [7]
  S.push(9)                        # contents: [7, 9]
  print(S.top())                   # contents: [7, 9];    outputs 9
  S.push(4)                        # contents: [7, 9, 4]
  print(len(S))                    # contents: [7, 9, 4]; outputs 3
  print(S.pop())                   # contents: [7, 9];    outputs 4
  S.push(6)                        # contents: [7, 9, 6]
  S.push(8)                        # contents: [7, 9, 6, 8]
  print(S.pop())                   # contents: [7, 9, 6]; outputs 8

1.修改ArrayStack实现(array_stack.py),使堆栈的容量仅限于maxlen元素,其中maxlen是构造函数的可选参数(默认为无)。如果在堆栈处于满容量时调用push,则抛出完全异常(定义类似于空)。

from array_stack import ArrayStack
import unittest


class Full(Exception):
    pass


class MyStack(ArrayStack):
    def __init__(self, maxlen=None):
        super().__init__()
        self._maxlen = maxlen

    def push(self, e):
        """Add element e to the top of the stack."""
        if self._maxlen != None:
            if self.__len__() >= self._maxlen:

                raise Full("Stack is full!!!")

        self._data.append(e)




if __name__ == '__main__':

    S = MyStack(5)
    for i in range(5):
        try:
            S.push(i)
        except Exception as e:
            print(e)

    S.push(2)

2.在前面的练习中,我们假设底层列表最初是空的。重做这个练习,这次预先分配一个长度等于堆栈最大容量的底层列表。

from array_stack import ArrayStack


class Full(Exception):
  pass


class MyStack1(ArrayStack):
    def __init__(self, maxlen=None):
        self._maxlen = maxlen
        self._data = [] if maxlen is None else [None] * maxlen

    def push(self, e):
        """Add element e to the top of the stack."""
        if self._maxlen != None:
            if self.__len__() >= self._maxlen:

                raise Full("Stack is full!!!")

        self._data.append(e)

if __name__ == '__main__':
    S = MyStack1(5)
    S.pop()
    S.push(2)

3.给出讲座中提到的双端队列ADT的一个完整的ArrayDeque实现。如下图:

class Empty(Exception):
  pass


class ArrayQueue:
  """FIFO queue implementation using a Python list as underlying storage."""
  DEFAULT_CAPACITY = 10          # moderate capacity for all new queues

  def __init__(self):
    """Create an empty queue."""
    self._data = [None] * ArrayQueue.DEFAULT_CAPACITY  # Note we use a list to implement Array
    self._size = 0
    self._front = 0

  def __len__(self):
    """Return the number of elements in the queue."""
    return self._size

  def is_empty(self):
    """Return True if the queue is empty."""
    return self._size == 0

  def first(self):
    """Return (but do not remove) the element at the front of the queue.

    Raise Empty exception if the queue is empty.
    """
    if self.is_empty():
      raise Empty('Queue is empty')
    return self._data[self._front]

  def dequeue(self):
    """Remove and return the first element of the queue (i.e., FIFO).

    Raise Empty exception if the queue is empty.
    """
    if self.is_empty():
      raise Empty('Queue is empty')
    answer = self._data[self._front]
    self._data[self._front] = None         # help garbage collection
    self._front = (self._front + 1) % len(self._data)   # Circular Array  ---Wei Pang
    self._size -= 1
    return answer

  def enqueue(self, e):
    """Add an element to the back of queue."""
    if self._size == len(self._data):
      self._resize(2 * len(self.data))     # double the array size
    avail = (self._front + self._size) % len(self._data)   # Circular Array again ---Wei Pang
    self._data[avail] = e
    self._size += 1

  def _resize(self, cap):                  # we assume cap >= len(self)
    """Resize to a new list of capacity >= len(self)."""
    old = self._data                       # keep track of existing list
    self._data = [None] * cap              # allocate list with new capacity
    walk = self._front
    for k in range(self._size):            # only consider existing elements
      self._data[k] = old[walk]            # intentionally shift indices
      walk = (1 + walk) % len(old)         # use old size as modulus
    self._front = 0                        # front has been realigned


if __name__ == '__main__':
  Q= ArrayQueue()
                        # return value    first<-- Q <--Last
  Q.enqueue(5)          # –                 [5]
  Q.enqueue(3)          # –                 [5, 3]
  a=len(Q)           # 2                 [5, 3]
  a=Q.dequeue( )          # 5                 [3]
  a=Q.is_empty( )         # False             [3]
  a=Q.dequeue( )          # 3                 [ ]
  a=Q.is_empty( )         # True              [ ]
 # Q.dequeue( )          # “error”           [ ]
  a=Q.enqueue(7)          # –                 [7]
  a=Q.enqueue(9)          # –                 [7, 9]
  a=Q.first()             # 7                 [7, 9]
  a=Q.enqueue(4)          # –                 [7, 9, 4]
  a = Q.__len__()  # 3                 [7, 9, 4]
  a=Q.dequeue( )          # 7                  [9, 4]

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值