#!/usr/bin/env python
# encoding: utf-8
'''
Python程序员面试算法宝典---解题总结: 第2章 栈、队列与哈希 2.3 如何翻转栈的所有元素
题目:
翻转(也叫颠倒)栈的所有元素,例如输入栈{1,2,3,4,5},其中,1处在栈顶,翻转之后的栈为{5,4,3,2,1},其中
5处在栈顶。
分析:
栈的特点就是后进先出,本质上是一个链表。
栈可以通过对链表的头插法实现,即每次插入的节点都放在链表的头节点head之后,
取栈顶元素就是取出head.nextNode。
那么翻转栈元素,实际上就是逆置整个链表。
书上的解法:
用递归来做。
算法步骤:
步骤1: 对于栈{1,2,3,4,5},把栈底元素移动到栈顶得到栈{5,1,2,3,4},
然后对不包含栈顶元素的子栈进行递归调用(对子栈元素进行翻转),子栈{1,2,3,4}
翻转的结果为{4,3,2,1},因此德奥最后翻转后的栈{5,4,3,2,1}
步骤2: 要把栈底的元素移动到栈顶也需要递归。
把不包含该栈顶元素的子栈的栈顶元素移动到子栈的栈顶,然后把栈顶元素与子栈栈顶元素进行交换。
递归调用------------------------------------------->
栈顶 1
2 -> 2
3 3 -> 3
4 4 4 -> 4
栈底 5 5 5 5 -> 5
<-----------------------返回子栈的调用结果并交换子栈的栈顶元素与栈顶元素
5
1 <- 5
2 2 <- 5
3 3 3 <- 5
4 4 4 4 <- 5
关键:
1 用数组实现栈,栈顶就认为是数组的最后一个元素
2 算法步骤:
步骤1: 对于栈{1,2,3,4,5},把栈底元素移动到栈顶得到栈{5,1,2,3,4},
然后对不包含栈顶元素的子栈进行递归调用(对子栈元素进行翻转),子栈{1,2,3,4}
翻转的结果为{4,3,2,1},因此德奥最后翻转后的栈{5,4,3,2,1}
步骤2: 要把栈底的元素移动到栈顶也需要递归。
把不包含该栈顶元素的子栈的栈顶元素移动到子栈的栈顶,然后把栈顶元素与子栈栈顶元素进行交换。
# 将栈底元素移动到栈顶
def moveBottomToTop(s):
if s.isEmpty():
return
top1 = s.getTop()
# 弹出栈顶元素
s.pop()
# 递归处理不包含栈顶元素的子栈
if not s.isEmpty():
moveBottomToTop(s)
# 获取处理后的子栈的栈顶元素
top2 = s.getTop()
s.pop()
# 交换栈顶元素与子栈栈顶元素
s.push(top1)
s.push(top2)
# 如果子栈为空,直接存入top1
else:
s.push(top1)
def reverseStack(s):
# 如果栈空了,直接返回
if s.isEmpty():
return
# 将栈底元素移动到栈顶
moveBottomToTop(s)
# 弹出栈顶元素,这样对子栈进行处理
top = s.getTop()
s.pop()
# 递归处理子栈
reverseStack(s)
# 再把元素插回到栈中
s.push(top)
参考:
Python程序员面试算法宝典
'''
class Stack(object):
def __init__(self):
self.list = list()
def isEmpty(self):
if self.list:
return False
else:
return True
# 将元素放在数组的最后面
def push(self, data):
self.list.append(data)
def pop(self):
if self.isEmpty():
print "stack is empty, it can not pop"
return
else:
self.list.pop()
def getTop(self):
if self.isEmpty():
print "stack is empty, it can not get top"
return
else:
return self.list[-1]
# 将栈底元素移动到栈顶
def moveBottomToTop(s):
if s.isEmpty():
return
top1 = s.getTop()
# 弹出栈顶元素
s.pop()
# 递归处理不包含栈顶元素的子栈
if not s.isEmpty():
moveBottomToTop(s)
# 获取处理后的子栈的栈顶元素
top2 = s.getTop()
s.pop()
# 交换栈顶元素与子栈栈顶元素
s.push(top1)
s.push(top2)
# 如果子栈为空,直接存入top1
else:
s.push(top1)
def reverseStack(s):
# 如果栈空了,直接返回
if s.isEmpty():
return
# 将栈底元素移动到栈顶
moveBottomToTop(s)
# 弹出栈顶元素,这样对子栈进行处理
top = s.getTop()
s.pop()
# 递归处理子栈
reverseStack(s)
# 再把元素插回到栈中
s.push(top)
def process():
s = Stack()
[s.push(i) for i in range(5, 0, -1)]
reverseStack(s)
print "翻转后的出栈顺序"
while not s.isEmpty():
print s.getTop()
s.pop()
if __name__ == "__main__":
process()