Python程序员面试算法宝典---解题总结: 第2章 栈、队列与哈希 2.3 如何翻转栈的所有元素

#!/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()

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值