python栈和队列

一、栈

1. 栈的基本介绍

特点:先进后出 (last-in, first-out)

入栈:push()
出栈:pop()
栈顶:get_top()
栈中元素个数:size()
判断栈是否为空:empty()

2. 代码

class Stack():
    def __init__(self):
        self.stack = []

    def push(self, element): # 入栈
        self.stack.append(element)

    def pop(self): # 出栈
        return self.stack.pop()

    def empty(self):  # 判断栈是否为空
        return self.stack == []

    def size(self):  # 返回栈中元素数量
        return len(self.stack)

    def get_top(self):# 取栈顶元素
        if len(self.stack) > 0:
            return self.stack[-1]
        else:
            return None

3. 基本操作

在这里插入图片描述

4. 括号匹配问题

class Stack():
    def __init__(self):
        self.stack = []

    def push(self, element):
        self.stack.append(element)

    def pop(self):
        return self.stack.pop()

    def get_top(self):
        if len(self.stack) > 0:
            return self.stack[-1]
        else:
            return None

    def empty(self):
        return len(self.stack) == 0


def bracket(s):
    stack = Stack()
    if len(s) % 2 != 0:  # 如果括号可以匹配,那么数量一定为偶数
        return False
    for i in s:
        if i == '(':
            stack.push(')')
        elif i == '[':
            stack.push(']')
        elif i == '{':
            stack.push('}')
        elif stack.get_top() == i:
            stack.pop()
        elif stack.empty() or stack.get_top() != i:
            return False
    if stack.empty():
        return True
    else:
        return False


s = input(':')
print(bracket(s))

5. 删除字符串所有相邻的重复项

样例:

输入:"abbaca"
输出:"ca"

例如:
在 "abbaca" 中,我们可以删除 "bb" 由于两字母相邻且相同,这是此时唯一可以执行删除操作的重复项。

之后我们得到字符串 "aaca",其中又只有 "aa" 可以执行重复项删除操作,所以最后的字符串为 "ca"
class Stack():
    def __init__(self):
        self.stack = []

    def push(self, element):
        self.stack.append(element)

    def pop(self):
        return self.stack.pop()

    def get_top(self):
        if len(self.stack) > 0:
            return self.stack[-1]
        else:
            return None

    def empty(self):
        return len(self.stack) == 0


def bracket(s):
    stack = Stack()
    for i in s:
        # 1. 如果栈为空 或者  前一个元素(栈顶)不等于当前元素i,则代表不是重复的,直接入栈即可
        if stack.empty() or stack.get_top() != i:
            stack.push(i)
        # 2. 如果前一个元素(栈顶) 等于 当前元素i,则需要出栈
        elif i == stack.get_top():
            stack.pop()
    # 3. 挨个遍历栈里面的元素,并加入到s中。注意:因为是从栈顶依次获取的,所有字符串s需要反转。
    s = ""
    while not stack.empty():
        s += stack.get_top()
        stack.pop()
    return s[::-1]


s = input(':')
print(bracket(s))

6. 出栈顺序是否合法

输入出栈的数字(数字不相同),判断这些数字是否可以合法入栈。

class Stack():
    def __init__(self):
        self.stack = []

    def push(self, element):
        self.stack.append(element)

    def pop(self):
        return self.stack.pop()

    def get_top(self):
        if len(self.stack) > 0:
            return self.stack[-1]
        else:
            return None

    def empty(self):
        return len(self.stack) == 0


# ① 创建栈,stack为栈中
stack = Stack()
# ② 创建数组a,为栈后数组
a = [0 for i in range(10)]
# ③ 输入数字
n = int(input('你要输入几个数字:'))
for i in range(1, n + 1):
    a[i] = int(input('请输入数字:'))
print(a)
# ④ 入栈、出栈
p = 1  # p表示栈前,p始终指向它即将入栈的那一位
flag = 1
for i in range(1, n + 1):
    while a[i] >= p:  # 将i之前的所有数字入栈
        stack.push(p)  # 入栈
        p += 1
    if stack.get_top() == a[i]:  # 如果栈顶 等于 列表第i为的元素,出栈
        stack.pop()  # 出栈
    else:
        flag = 0
        break
# ⑤ 判断是否合法
if flag:
    print(True)
else:
    print(False)

二、队列

1. 队列基本介绍

特点:先进先出 (First in,First out)

入队:push()。队尾(rear)指针加1。rear=(rear+1)%MaxSize
出队:pop()。  对头(front)指针加1。front=(front+1)%MaxSize
对头元素:get_front()
对尾元素:get_back()
队列中元素个数:length()(rear−front+MaxSize)%MaxSize
判断队是否为空:empty()。front==rear
判断队列是否满:filled()(rear+1)%MaxSize==front

2. 队列代码

class Queue:
    def __init__(self, size):
        self.queue = [0 for _ in range(size)]
        self.size = size  # 队列最大容量
        self.rear = 0  # 队尾,负责入队
        self.front = 0  # 队头,负责出队

    # 入队
    def push(self, element):
        if not self.filled():  # 如果队不满,则入队
            self.rear = (self.rear + 1) % self.size  # 将队尾指针重新赋值,队尾需要向后移动一位
            self.queue[self.rear] = element  # 队尾插入元素
        else:
            raise IndexError("队列已满!!!")

    # 出队
    def pop(self):
        if not self.empty():  # 如果队不空,则出队
            self.front = (self.front + 1) % self.size  # 将队头指针重新赋值,对头需要向后移动一位
            return self.queue[self.front]
        else:
            raise IndexError("队列为空!!!")

    # 判断队空(队头等于队尾则代表对空)
    def empty(self):
        return self.rear == self.front

    # 判断队满
    def filled(self):
        return (self.rear + 1) % self.size == self.front

    # 队列元素个数
    def length(self):
        return (self.rear - self.front + self.size) % self.size

    # 对头元素
    def get_front(self):
        if not self.empty():  # 如果队不空,则打印对头元素
            return self.queue[(self.front + 1) % self.size]

    # 对尾元素
    def get_back(self):
        if not self.empty():  # 如果队不空,则打印对尾元素
            return self.queue[self.rear]

3. 队列基本操作

# 1. 创建队列
q = Queue(5)
# 2. 依次添加数据
q.push(1)
q.push(2)
q.push(3)
q.push(4)
# 3. 出队列
print('出队:', q.pop())
print('出队:', q.pop())
# 4. 长度、对头、队尾
print('队列长度:', q.length())
print('对头元素:', q.get_front())
print('对尾元素:', q.get_back())

# ⑤ 遍历队列
# while not q.empty():
#     print(q.pop())

while not q.empty():
    print('对头元素:', q.get_front())
    q.pop()

4. 约瑟夫环-循环嵌套

一共有n个人,第m个人负责出圈,请依次打印出圈的数字。

a = [0 for i in range(101)]
n, m, i, cnt, k = 0, 0, 0, 0, 0  # cnt:出圈人数  i:位置,从1开始  k:数数,到k,就要出圈

n = int(input('一共有几个人?'))
m = int(input('第几个人出圈?'))

while cnt != n:
    i += 1
    if i > n:  # 走到了最后一个,再回头
        i = 1
    if a[i] == 0:  # 如果为0则代表这个数还没出圈
        k += 1
        if k == m:
            a[i] = 1  # 出圈
            cnt += 1  # 出圈人数增加1
            print(i, end=' ')
            k = 0  # 重新数数

5. 约瑟夫环-队列1

# 1. 创建队列
q = Queue(20)
n = int(input('一共有几个人?'))
m = int(input('第几个人出圈?'))
# 2. 将n个人的编号按顺序依次入队
for i in range(1, n + 1):
    q.push(i)
# 3. 从1开始报数10
cnt = 1
while not q.empty():  # 只要队列不为空则一直循环
    if cnt % m == 0:  # 代表找到了
        print(q.get_front(), end=' ')
        q.pop()
        cnt = 0
    else:  # 未找到
        q.push(q.get_front())  # 把队头元素调到队尾
        q.pop()
    cnt += 1

6. 约瑟夫环-队列2

# 1. 创建队列
q = Queue(20)
n = int(input('一共有几个人?'))
m = int(input('第几个人出圈?'))
# 2. 将n个人的编号按顺序依次入队
for i in range(1, n + 1):
    q.push(i)
# 3. 将第m个数字移到队首,第m-1个数字移到队尾
while q.length() > 0:      # 删除操作,并在当队列中没有数字时停止该操作
    for i in range(1, m):  # 将队列中第m个人移到队首,并将前面m-1个人按顺序排到队尾
        h = q.get_front()
        q.pop()
        q.push(h)
    x = q.pop()
    print(x, end=' ')
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

1024节

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值