您的当前位置:首页正文

python数据结构——利用列表实现栈和队列

2024-11-08 来源:个人技术集锦

前言

栈和队列的内容,这里就不多说了,还有不清楚的看一下。
其实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]

Top