2.1python实现栈

题目描述:

实现一个栈的数据结构 (Last In First Out,LIFO),使其具有以下方法:;压栈,弹栈,取栈顶元素,判断栈是否为空以及获取栈内元素个数。

方法:

  1. 数组实现
  2. 链表实现

1.数组实现

在采用数组来实现栈的时候,栈空间是一段连续的空间。实现思路如下图所示:
在这里插入图片描述

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

代码实现:

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# @Time    : 2020/1/20 15:02
# @Author  : buu
# @Software: PyCharm
# @Blog    :https://blog.csdn.net/weixin_44321080
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('stack is empty!')
            return None

    def push(self, item):  # 入栈
        self.items.append(item)


if __name__ == '__main__':
    s = Mystack()
    s.push(4)
    print('top of the stack is ' + str(s.top()))
    print('size of the stack is ' + str(s.size()))
    if s.pop():
        print('successfully pop!')
    s.pop()

结果:
在这里插入图片描述
2.链表实现

在创建链表的时候经常采用一种从头结点插入新结点的方法,可以采用这种方法来实现栈,最好使用带头结点的链表,这样可以保证对每个结点的操作都是相同的,实现思路如下图所示:
在这里插入图片描述
在上图中,在进行压栈操作的时候,先需要创建新的结点,把待压栈的元素放到新结点的数据域中,然后只需要 (1) 和 (2) 两步就实现了压栈操作 (把新结点压到了链表首部);同理,在弹栈的时候,只需要进行 (3) 的操作就可以删除链表的第一个元素,从而实现弹栈操作。(都是在链表头实现的)

代码实现:

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# @Time    : 2020/1/20 15:20
# @Author  : buu
# @Software: PyCharm
# @Blog    :https://blog.csdn.net/weixin_44321080
class LNode():
    def __init__(self, data=None, next=None):
        self.data = data
        self.next = next


class myStack(): # self 指向头结点
    def __init__(self, data=None, next=None):
        self.data = data
        self.next = next

    def isEmpty(self):  # 判断是否为空
        if self.next == None:  # 若为空,返回True
            return True
        else:
            return False

    def size(self):  # 栈的大小
        size = 0
        p = self.next
        while p != None:
            p = p.next
            size += 1
        return size

    def push(self, e):  # 入栈
        p = LNode(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('the stack is already empty!')
        return None

    def top(self):  # 取栈顶元素
        if self.next != None:
            return self.next.data
        else:
            print('the stack is alreay empty!')
            return None


if __name__ == '__main__':
    stack = myStack()
    stack.push(3)
    print('top of the stack is ' + str(stack.top()))
    print('size of the stack is ' + str(stack.size()))
    if stack.pop():
        print('pop successfully!')
    if not stack.pop():
        print('unable to pop!')

结果:
在这里插入图片描述

两种方法的对比:

采用数组实现栈的优点是:一个元素值占一个存储空间;缺点是:如果初始化申请的存储空间比较大,容易造成空间的浪费,如果申请存储的空间太小,后期会经常需要扩充存储空间,比较费时间,会造成性能的下降。
采用链表实现的优点是:使用灵活方便,只有在需要的时候才会申请空间,缺点是除了要存储元素外,还需要额外的存储空间存储指针信息。

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

end

发布了76 篇原创文章 · 获赞 2 · 访问量 2571

猜你喜欢

转载自blog.csdn.net/weixin_44321080/article/details/104051873