栈与队列

栈的是一种线性结构,栈存储数据类似于乒乓球筒中放入或取出乒乓球的过程,遵从先进后出的原则。
在这里插入图片描述
栈相比于同样是线性结构的顺序表,关闭了部分接口,提高程序的稳定性。

用Python实现栈

  1. Stack()创建一个新的空栈
  2. push(item)添加一个新的元素item到栈顶
  3. pop()弹出栈顶元素
  4. peek()返回栈顶元素
  5. is_empty()判断栈是否为空
  6. size()返回栈的元素个数
  7. tracel()输出栈中所以元素
class Stack:
    def __init__(self):
        self.__data = []

    def is_empty(self):
        """判断栈是否为空"""
        return self.__data == []

    def push(self, data):
        """在栈顶添加元素"""
        self.__data.append(data)

    def pop(self):
        """弹出顶部元素"""
        return self.__data.pop()

    def peek(self):
        """返回栈顶元素"""
        # 先判断是否为空
        if self.is_empty():
            return
        else:
            return self.__data[-1]

    def size(self):
        """判断长度"""
        return len(self.__data)

    def travel(self):
        """遍历所有元素"""
        self.__data = self.__data[::-1]
        for i in self.__data:
            print(i)


if __name__ == '__main__':
    a = Stack()
    print(a.is_empty())
    a.push(0)
    a.push(1)
    a.push(2)
    a.push(3)
    a.travel()

使用Python中的列表,我们可以轻松的创建一个栈,栈在程序中用处是较多的一种结构,我们浏览器的前进后推中就用到了栈

浏览器中用到的栈

当我们没次访问一个新页面,浏览器就会已栈的结构记下一条我们的浏览记录。之后如果我们需要返回,浏览器就会输出栈顶数据,也就是我们最后访问的那个页面。并同时将栈顶元素存档在另一个栈中,一共后续前进使用。
在这里插入图片描述
在这里插入图片描述

if __name__ == '__main__':
    prev = Stack()
    next = Stack()
    i = 1
    while True:
        print('按1为点击新页面,2为返回,3为前进')
        a = int(input('请输入数字: '))
        if a == 1:
            prev.push(f'第{i}个页面')
            print(f'当前在{prev.peek()}')
            i += 1
        elif a == 2:
            if prev.is_empty():
                print('不存在上个页面')
            elif prev.size() == 1:
                print('首页无法返回')
            else:
                next.push(prev.pop())
                print(f'当前在{prev.peek()}')
        elif a == 3:
            if next.is_empty():
                print('不存在下个页面')
            else:
                prev.push(next.pop())
                print(f'当前在{prev.peek()}')

队列

队列遵循的是后出原则,队列和栈都是受限制的线性表结构,队列相较于栈更好理解,因为平时我们都或多或少经历过排队。而且队列的使用也相当多,比如说并发队列,循环队列,阻塞队列,在系统底层、框架、中间件的开发中,起着关键性作用。

在这里插入图片描述## 用Python实现队列

class Queue:
    def __init__(self):
        self.__data = []

    def enqueue(self, data):
        """往队列头中添加一个新元素"""
        self.__data.insert(0, data)

    def travel(self):
        """遍历所有元素"""
        for i in self.__data:
            print(i, end='')
        print('')

    def dequeue(self):
        """从队列尾删除一个元素"""
        self.__data.pop()

    def is_empty(self):
        """判断队列是否为空"""
        return self.__data == []

    def size(self):
        """返回队列的元素个数"""
        return len(self.__data)

队列和栈在代码是现实上非常相似,都可以算是一种受到限制的顺序表

双端队列

双端队列可在队列任意一侧出队入队。

在这里插入图片描述
双端队列只需加入对头的出队和队尾入队的方式即可

    def appqueue(self, data):
        """在队尾添加新元素"""
        self.__data.append(data)

    def delqueue(self):
        """删除对头元素"""
        self.__data.pop(0)

扩展

我们发现栈和队列中有大量相同的方法,我们可以使用继承和封装来优化代码

# 利用继承写栈与队列
class Repeat:
    def __init__(self):
        self.__data = []

    def is_empty(self):
        """判断是否为空"""
        return self.__data == []

    def push(self, data):
        """头部添加元素"""
        self.__data.insert(0, data)

    def travel(self):
        """遍历所有元素"""
        for i in self.__data:
            print(i)
        print('')

    def size(self):
        """返回队列的元素个数"""
        return len(self.__data)

    @property
    def data(self):
        return self.__data

    @data.setter
    def data(self, n):
        self.__data = n


class Stack(Repeat):
    def pop(self):
        """弹出顶部元素"""
        return self.data.pop(0)

    def peek(self):
        """返回栈顶元素"""
        # 先判断是否为空
        if self.is_empty():
            return False
        else:
            return self.data[0]


class Queue(Repeat):
    def pop(self):
        """队尾元素出队"""
        return self.data.pop()