一,Python实现栈
1,栈
栈(stack)又名堆栈,它是一种特殊的线性表,这种线性表只能在尾部(栈顶)插入、删除元素。它按照先进后出(FILO)的原则存储数据,先进入的数据被压入栈底,最后的数据在栈顶,所以后进的元素最先被弹出栈,先进的元素后弹出。
2,List 实现栈
使用Python 中基本的数据结构——List就可以实现栈,使用List是因为
1,List也可以看出一种线性表;
2,List方法中的append、pop已经实现了尾部插入、删除,可直接调用;
关于List可看看之前的博文:【数据结构】Python中的顺序表——List
class SQStack(object):
def __init__(self): # 初始化,用list实现栈
self.stack = list()
def is_empty(self): #栈是否为空
return len(self.stack) == 0
def size(self): #返回栈中的 item 数量
return len(self.stack)
def travel(self): # 遍历,从栈顶遍历到栈底
return ''.join([str(self.pop()) for i in range(1, self.size() + 1)])
def push(self, val): #将一个新项添加到栈的顶部
self.stack.append(val)
def pop(self): #从栈中删除顶部项。并返回 item
if self.is_empty():
return None
else:
return self.stack.pop()
二,经典算法题实现
1,二进制与十进制互转
bSQStack = SQStack()
# 十进制转二进制
num = 250
while num:
res = num % 2
bSQStack.push(res)
num = num // 2
print(bSQStack.travel()) # 11111010
# 二进制转十进制
bSQStack = SQStack()
bnum = 11111010
sum = 0
b_str = str(bnum)
for b in b_str: # 将二进制数压入栈
bSQStack.push(b)
for i in range(0, bSQStack.size()):
res = int(bSQStack.pop()) * pow(2, i) # 对每位二进制弹栈计算
sum += res
print(bnum, '十进制:', sum) # 250
2,二进制转八进制,十六进制
bSQStack = SQStack()
oSQStack = SQStack()
# 二进制转八进制
bnum = 11111010
b_str = str(bnum)
for b in b_str: # 将二进制数压入栈
bSQStack.push(b)
while not bSQStack.is_empty():
sum = 0
for i in range(0, 3):
val = bSQStack.pop() # 每三位计算一个八进制位
if val:
res = int(val) * pow(2, i)
else:
res = 0
sum += res
oSQStack.push(sum) # 将八进制数压入栈
print(oSQStack.travel()) # 372
bSQStack = SQStack()
hexSQStack = SQStack()
# 二进制转十六进制
hexdict = {
0: '0', 1: '1', 2: '2', 3: '3', 4: '4', 5: '5', 6: '6', 7: '7', 8: '8',
9: '9', 10: 'A', 11: 'B', 12: 'C', 13: 'D', 14: 'E', 15: 'F'
}
bnum = 111011101
b_str = str(bnum)
for b in b_str:
bSQStack.push(b) # 将二进制数压入栈
while not bSQStack.is_empty():
sum = 0
for i in range(0, 4): # 每三位计算一个十六进制位
val = bSQStack.pop()
if val:
res = int(val) * pow(2, i)
else:
res = 0
sum += res
hexSQStack.push(hexdict.get(sum)) # 将十六进制数压入栈
print(hexSQStack.travel()) #10D
3,中缀表达式转后缀表达式
hSQStack = SQStack()
opstr = '1+(((2.5-4)+8/2)+8)+1*(4+10)/2'
houzui = []
res = list(filter(None, re.split(r'(\+|-|\*|/|\(|\))', opstr)))
# print(res)
for c in res:
if is_num(c): # 数值 则直接打印
houzui.append(c)
elif ')' == c: # 若是')' 弹出打印 '(' 之前的所有运算符
e = hSQStack.pop()
while '(' != e:
houzui.append(e)
e = hSQStack.pop()
elif '+' == c or '-' == c:
if hSQStack.is_empty(): # 空栈 直接压入
hSQStack.push(c)
else:
while True:
e = hSQStack.pop() # 取 栈顶元素
if '(' == e:
hSQStack.push(e) # 若为 '(' 则压入 只有遇到')' 才会将 '('
else:
# * / 以及 先入的 + - 弹出
houzui.append(e)
if hSQStack.is_empty() or '(' == e: # 只有遇到')' 才会将 '('
break
hSQStack.push(c)
elif '*' == c or '/' == c or '(' == c: # * / ( 直接压入
hSQStack.push(c)
else:
print(c, '非法!!')
break
while not hSQStack.is_empty():
e = hSQStack.pop()
houzui.append(e)
# print(e, end=' ')
print(' '.join(houzui)) # 1 2.5 4 - 8 2 / + 8 + + 1 4 10 + 2 / * +
4,后缀表达式计算
cSQStack = SQStack()
for i in houzui:
if is_num(i): # 数值 则直接压入
cSQStack.push(float(i))
elif '+' == i:
b = cSQStack.pop()
d = cSQStack.pop()
cSQStack.push(d + b)
elif '-' == i:
b = cSQStack.pop()
d = cSQStack.pop()
cSQStack.push(d - b)
elif '/' == i:
b = cSQStack.pop()
d = cSQStack.pop()
if 0 == b:
print('除数为0')
break
else:
cSQStack.push(d / b)
else:
b = cSQStack.pop()
d = cSQStack.pop()
cSQStack.push(d * b)
print(cSQStack.pop()) # 1+(((2.5-4)+8/2)+8)+1*(4+10)/2 = 18.5