Python 数据结构 —— Stack

1. list

Python 内置的 list 类对象的使用很灵活,可以方便地访问修改列表元素:

methoddescription
L.append(x)在 L 尾部添加元素 x
L.pop(i)删除位置 i 处的元素并返回,相当于 del L[i],i 默认为 i=len(L)-1
L.insert(i, x)在位置 i 处插入元素 x
L.remove(x)删除第一个值为 x 的元素,不存在则报错
L.count(x)返回元素 x 出现的次数
L.sort()就地排序
L.reverse()就地逆序
L.clear()清空列表,相当与 del list[:]

通过 del 可以方便的删除元素,如 del L[2]del L[1: 5],如果要删除整个列表,可以:

del L[:]

但不能 del L 因为这样只是删除了列表的引用,而列表对应的内存空间仍然存在,只是无法访问了:

a = [0, 1, 2, 3, 4]
c = a
del a
print(c)	# [0, 1, 2, 3, 4]


2. Stack

2.1 Stack 类方法

Stack 类具有以下方法:

  • push()
  • pop()
  • peek()
  • size()
  • isEmpty()

其中,pop() 是弹栈操作,返回栈顶元素,peek() 只是返回栈顶元素值,不弹栈!


2.2 利用 list 构建 Stack

创建一个文件夹 DataStructures, 在其中创建文件 DataStructures.py,在其中定义类:

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

	def push(self, item):
		self.items.append(item)

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

	def peek(self):
		return self.items[len(self.items)-1]

	def size(self):
		return len(self.items)

	def isEmpty(self):
		return self.items == []

if __name__ == '__main__':
	s = Stack()
	for i in range(5):
		s.push(i)
	while not s.isEmpty():
		print(s.pop())

打印结果为:

4
3
2
1
0

在外部调用 Stack 可以通过下面的命令引入:

from DataStructures.Stack imort Stack


3. 使用 Stack

2.1 括号匹配问题

问题描述:判断一组括号是否匹配,如 (()((())())) 是匹配的,而 (()() 是不匹配的:

from DataStructures.Stack import Stack

def parChecker(symbolString):
	s = Stack()
	for symbol in symbolString:
		if symbol == '(':
			s.push(symbol)
		else:
			if s.isEmpty():
				return False
			if s.pop() == '(':
				continue
			else:
				return False
	if s.isEmpty():
		return True
	else:
		return False

print(parChecker('(()((())()))'))

3.2 进制转换问题

问题描述:利用程序实现将一个十进制数转换为二进制数的函数
解题思路:对十进制数反复对 2 取余和整除 2 的操作,将结果压栈,最后全部弹栈:

from DataStructures.Stack import Stack

def DecimalToBinary(number):
	s = Stack()
	while number:
		res = number % 2
		number = (number - res) // 2
		s.push(res)
	ans = ''
	while not s.isEmpty():
		ans = ans + str(s.pop())
	return ans

print(DecimalToBinary(13))

打印结果为 1101 ,正确


3.3 中序表达式转换

问题描述
中序表达式是我们日常所见表达式的顺序,如
a * b + c * d
a * (b + c) * d
但是这种表达式需要用括号用来辅助计算顺序,而前序表达式和后序表达式不需要括号,后序表达式的定义为运算符在两个操作数之后的表达式,如上面两个表达式对应的后序表达式为:

a * b + c * d     =>    a b * c d * +
a * (b + c) * d   =>    a b c + * d *

解题思路:

  • 首先去掉输入表达式中所有空格
  • 创建一个栈,用来存储运算符
  • 对表达式中每一个字符进行处理
  • 如果当前字符为数字,则打印字符
  • 如果当前字符为运算符
    若栈顶操作符优先级比当前运算符高或相同,则弹栈并打印
    将当前字符压栈
  • 如果当前字符为括号,左括号入栈,若为右括号,则将栈内括号元素后的所有元素弹栈
from DataStructure.Stack import Stack

def midToPostCalculate(expression):
	res = ''
	s = Stack()
	expression = ''.join(expression.split(' '))
	for item in expression:
		# number
		if item not in list('+-*/()'):
			res += item

		# operator
		elif item in list('+-*/'):
			priority = {'*': 2, '/': 2, '+': 1, '-': 1, '(': 0}
			if not s.isEmpty() and priority[s.peek()] >= priority[item]:
				res += s.pop()
			s.push(item)

		# embraces
		elif item in list('()'):
			if item == '(':
				s.push(item)
			elif item == ')':
				while s.peek() != '(':
					res += s.pop()
				s.pop()

	while not s.isEmpty():
		res += s.pop()
	return res

测试结果:

expression = '(A + B) * C - (D - E) * (F + G)'
print(midToPostCalculate(expression))	# AB+C*DE-FG+*-


完结 🍻

  • 3
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值