栈和队列的内容,这里就不多说了,还有不清楚的看一下。
其实list能实现的要比我们定义的栈和队列多很多功能,但是我们还是要实现一个。
这里采用的duck typing,也就是
先上代码吧。
事先说明:这里有一个empty异常,但是我并没有定义这个类,这个需要继承Exception,这里就不实现了,感兴趣的自己看一下吧
栈:
"""list实现的栈"""
class ArrayStack():
def __init__(self):
"""Create an empty stack"""
self._data = []
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)
def pop(self):
"""remove and return the element from the top of the stack"""
# 这里的Empty类要自己定义一下
if self.is_empty():
raise Empty('stack is empty')
return self._data.pop()
def top(self):
"""return but not remove the element at the top of the stack"""
if self.is_empty():
raise Empty('stack is empty')
return self._data[-1]
重载了len方法,并且给出了判空函数、压栈出栈函数以及得到栈顶的函数。
队列:
"""自己定义的queue"""
class ArrayQueue():
DEFAULT_CAPACITY = 10
def __init__(self):
"""create an empty queue"""
self._data = [None] * ArrayQueue.DEFAULT_CAPACITY
# the length of the queue, len(data) is the length of the list
self._size = 0
# the index of the head
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 dequeue(self):
"""remove and return the first element of the queue"""
if self.size == len():
# undefined empty
raise Empty('Queue is empty')
answer = self._data[self._front] = None
# head -> new head, index++
self._front = (self._front+1)%len(self._data)
self._size -= 1
if 0<self._size<len(self._data)//4:
self._resize(len(len(self._data)//2))
return answer
def enqueue(self,e):
"""add e to the back of the queue"""
if self._size == len(self._data):
self._resize(2*self._size)
avail = (self._front+self._size)%len(self._data)
self._data[avail] = e
self._size += 1
def _resize(self,cap):
"""resize to a new list of capacity >= len(self)"""
old = self._data
self._data = [None]*cap
walk = self._front
# index reset to 0, data[0]=old[front]
for k in range(self._size):
self._data[k] = old[walk]
walk = (1 + walk)%len(old)
self._front = 0
这里的队列只是最简单的类型,没有涉及双向这些。
另外我们的队列是自己做的动态数组,而不是使用列表自带的动态数组方式。
动态数组的内容看这里,接下来主要是实现。
判空、计算长度还是很基础的,这里主要的是进出队列。
首先,我们用一个变量存储了队首位置,所以在每一次入队,当列表满了,我们需要重新申请空间,并进行内容的移动(在函数中完成),同时计算出新队尾的位置(队首下标+长度),并进行赋值,同时改变数组中元素的个数;
每一次出队,我们需要先判断队列是否为空。删除元素的过程就是将这个内容设置为none(因为最开始也是none),然后因为是第二位变成队首,所以需要重新计算队首下标。同时记得处理队列大小即可。
调整数组大小这里,我们采用了比较简单的list方式,没用之前的ctype。
不过有一点还是要注意,移动的过程中我们需要调整位置
比如下边这个:
[d,e,f,a,b,c]
我们如果直接赋值,很明显是不对的,正确的应该是这样的:[a,b,c,d,e,f,none*6]