判断栈是否为空_每日一道面试题系列 如何实现栈

2fcfec1492689a357769de8bf67ed219.gif

题目描述

130982b57da30ff4935c545bbc3e0d95.png

来源:阿里巴巴面试题                         难度系数:★★★☆☆                   考察频率:★★★★☆

题目描述:

实现一个栈的数据结构,使其具有以下方法:压栈、弹栈、取栈顶元素、判断栈是否为空以及获取栈中元素个数。

本题摘选自猿媛之家出版的《Python 程序员面试算法宝典》一书中。

分析解答

130982b57da30ff4935c545bbc3e0d95.png

分析

分析与解答:

栈的实现有两种方法,分别为采用数组来实现和采用链表来实现。下面分别详细介绍这两种方法。

方法一:数组实现

在采用数组来实现栈的时候,栈空间是一段连续的空间。实现思路如下图所示。

8471083254358aff58367fa4cff779c3.png

从上图中可以看出,可以把数组的首元素当做栈底,同时记录栈中元素的个数 size,假设数组首地址为 arr,从上图可以看出,压栈的操作其实是把待压栈的元素放到数组 arr[size]中,然后执行 size+操作;同理,弹栈操作其实是取数组 arr[size-1]元素,然后执行 size-操作。 根据这个原理可以非常容易实现栈。

方法二:链表实现

在创建链表的时候经常采用一种从头结点插入新结点的方法,可以采用这种方法来实现栈,最好使用带头结点的链表,这样可以保证对每个结点的操作都是相同的,实现思路如下图所示。

ecb59331c27bc9a27a38900d225e283a.png

在上图中,在进行压栈操作的时候,首先需要创建新的结点,把待压栈的元素放到新结点的数据域中,然后只需要(1)和(2)两步就实现了压栈操作(把新结点加到了链表首部)。同理,在弹栈的时候,只需要进行(3)的操作就可以删除链表的第一个元素,从而实现弹栈操作。

解答

方法一解答代码

# -*- coding: utf-8 -*-"""Created on Sat Nov 10 12:34:38 2018@author: Administrator"""class  MyStack:    # 模拟栈    def  __init__(self):         self.items= []            # 判断栈是否为空    def  isEmpty(self):         return  len(self.items) ==0      # 返回栈的大小    def  size(self):         return  len(self.items)     # 返回栈顶元素    def  top(self):         if  not self.isEmpty():             return  self.items[len(self.items)-1]         else:            return  None    # 弹栈    def  pop(self):        if  len(self.items)>0:            return  self.items.pop()          else:            print("栈已经为空")            return  None    # 压栈    def  push(self,item):         self.items.append(item) if  __name__=="__main__":       s=MyStack()     s.push(4)       print("栈顶元素为:" ,s.top())    print("栈大小为:" ,s.size())    s.pop()    print ("弹栈成功")    s.pop()

方法二解答代码

# -*- coding: utf-8 -*-"""Created on Sat Nov 10 12:35:22 2018@author: Administrator"""class  LNode:    def  __new__(self,x):         self.data=x        self.next=Noneclass  MyStack:    def  __init__(self):         # pHead=LNode()        self.data=None        self.next=None    # 判断stack是否为空,如果为空返回true,否则返回false     def  empty(self):         if  self.next == None:             return  True           else:             return  False       # 获取栈中元素的个数    def  size(self):        size=0          p = self.next          while  p != None:            p = p.next              size +=1         return  size             # 入栈:把e放到栈顶    def  push(self,e):        p =LNode           p.data = e          p.next = self.next          self.next = p              # 出栈,同时返回栈顶元素    def  pop(self):        tmp = self.next          if  tmp != None:            self.next = tmp.next              return  tmp.data          print ("栈已经为空")        return  None    # 取得栈顶元素    def  top(self):        if  self.next != None:            return  self.next.data          print ("栈已经为空")          return  None    if  __name__=="__main__":    stack = MyStack()    stack.push(1)      print("栈顶元素为:",stack.top())    print("栈大小为:", stack.size())    stack.pop()    print("弹栈成功")    stack.pop()

方法二程序的运行结果为:

栈顶元素为:1栈大小为:1弹栈成功栈已经为空

两种方法的对比:

采用数组实现栈的优点是:一个元素值占用一个存储空间;

它的缺点为:如果初始化申请的存储空间太大,会造成空间的浪费,如果申请的存储空间太小,后期会经常需要扩充存储空间,扩充存储空间是个费时的操作,这样会造成性能的下降。 

采用链表实现栈的优点是:使用灵活方便,只有在需要的时候才会申请空间。

它的缺点为:除了要存储元素外,还需要额外的存储空间存储指针信息。

算法性能分析:

这两种方法压栈与弹栈的时间复杂度都为 O(1)。

感谢您的阅读,有任何问题欢迎评论区留言。

· END ·

26a2a0a7d39efc248bf0fa4a389d240f.gif

99c988084ad18d5ead6ae88cd508b3c5.png

欢迎加入猿媛之家QQ群获取更多交流:496588733

本公众号拥有优而全的高效复习资料(导航栏做了统一整理目录,持续更新...),旨在为您的面试求职保驾护航,提高您的职场竞争力,感谢您的支持!

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值