Smaller And Smarter Python数据结构:自己动手实现栈

简介: Smaller And Smarter Python数据结构:自己动手实现栈

简说Python,号主老表,Python终身学习者,数据分析爱好者,从18年开始分享Python知识,原创文章227篇,写过Python、SQL、Excel入门文章,也写过Web开发、数据分析文章,老表还总结整理了一份2022Python学习资料和电子书资源,关注后私信回复:2022 即可领取。

今天给大家分享的书籍《Python程序员面试算法宝典》第二章第一小节:如何实现栈。

如果你是第一次看,也许,你可以看看本系列下面的文章:  Python数据结构:链表合集(12+7),复现几遍,包你学会

今日问题

"""
目标:实现栈,使其具有方法:压栈(push)、弹栈(pop)、取栈顶元素(get_top)、
判断栈是否为空(is_empty)、获取栈中元素个数(size)
为后面操作打基础
Goal: to implement the stack with the following methods: push, pop, get top
Judge whether the stack is empty and get the number of elements in the stack (size)
Lay a foundation for later operations
"""

解题

方法一:数组(列表)实现栈

"""
Method One : 数组(列表)实现栈
核心思想:以数组(列表)作为存储栈数据的数据结构,Python里本身
对列表有着丰富的内置操作,比如pop,append,len等等,列表是顺序
存储,并且在Python初始化一个列表时,不一定非要指定列表长度,这
使得Python列表实现起来非常简单和方便。
注意:一般在C、Java中初始化数组(列表)时,是必须声明数组(列表)
长度的,而在Python中,可以不限定,但append添加的效率很明显要比
直接赋值(比如:list[1] = "Python")的低很多。
Method one: array (list) implementation stack
Core idea: Taking array (list) as the data structure of stack data storage,
 python itself has rich built-in operations on list, such as pop, append, 
 len, etc. list is sequential storage, and when Python initializes a list, 
 it is not necessary to specify the length of list, which makes Python list 
 implementation very simple and convenient.
Note: when initializing arrays (lists) in C and Java, the length of arrays
 (lists) must be declared. In Python, there is no limit, but the efficiency
 of adding append is obviously lower than that of direct assignment (for 
 example: list [1] = "Python").
"""

代码

class ListStack:
    def __init__(self):
        self.stack = []  # 列表,不指定长度
        # self.stack = [0]*10  # 列表,指定长度
    # 入栈
    def stack_push(self, x):
        self.stack.append(x)  # 入栈
        print("********入栈成功********")
    # 出栈
    def stack_pop(self):
        if self.stack_len() > 0:
            self.stack.pop()  # 出栈
            print("********出栈成功********")
        else:
            print("********栈已空********")
    # 获取栈顶元素
    def get_stack_top(self):
        if self.stack_is_empty():
            print("********空栈********")
            return None
        else:
            return self.stack[self.stack_len() - 1]
    # 判断栈是否为空
    def stack_is_empty(self):
        if self.stack_len() == 0:
            return True
        else:
            return False
    # 栈长度
    def stack_len(self):
        return len(self.stack)

方法二:链表实现栈

"""
Method Two : 链表实现栈
核心思想:以链表作为存储栈数据的数据结构,Python里本身
是不含链表这种数据结构的,所以需要我们自己去写对链表的基
本操作,当然在上一章中我们已经非常熟悉链表了,所以操作起
来还是很简单。
注意:Python内置的数据结构里没有链表,我们一般用引用实现
链表这一数据结构,创建一个类LinkNode,包含两个属性,data
为数据域,存放当前结点数据,next为指针域。存放下一个结点的
地址(指针)。
Method two: linked list implementation stack
Core idea: take linked list as the data structure to store stack data.
  Python itself does not contain linked list, so we need to write the
  basic operation of linked list. Of course, in the previous chapter, 
  we are very familiar with linked list, so the operation is very simple.
Note: there is no linked list in Python's built-in data structure. Generally,
 we use reference to implement the linked list data structure. We create a 
 linknode class, which contains two attributes. Data is the data field, which 
 stores the current node data, and next is the pointer field. Store the 
 address (pointer) of the next node.
"""

代码

class LinkNode:
    def __init__(self, x):
        self.data = x  # 数据域
        self.next = None  # 指针域
class LinkStack:
    def __init__(self):
        self.data = "head"
        self.next = None  # 头结点,栈的top指针
    # 入栈
    def stack_push(self, x):
        node = LinkNode(x)  # 新建一个结点
        node.next = self.next
        self.next = node  #  插入到头结点后
        print("********入栈成功********")
    # 出栈
    def stack_pop(self):
        if not self.stack_is_empty():
            node = self.next
            self.next = node.next # 出栈,让self.next指向第二个结点
            print("********出栈成功********")
        else:
            print("********栈已空********")
    # 获取栈顶元素
    def get_stack_top(self):
        if self.stack_is_empty():
            print("********空栈********")
            return None
        else:
            return self.next.data
    # 判断栈是否为空
    def stack_is_empty(self):
        if self.stack_len() == 0:
            return True
        else:
            return False
    # 栈长度
    def stack_len(self):
        link_len = 0
        cur_node = self.next
        while cur_node:  # 遍历计算链表长,即栈长
            cur_node = cur_node.next
            link_len = link_len + 1
        return link_len

测试代码

# 当然,也许还有别的方法,比如建一个辅助的链表
# 欢迎你说出你的想法
# 程序入口,测试函数功能
if __name__ == "__main__":
    # 初始化一个栈
    # my_stack = ListStack()  # 列表栈测试
    my_stack = LinkStack()  # 链表栈测试
    # 入栈
    my_stack.stack_push(1)
    my_stack.stack_push(2)
    # 获取栈顶
    print("当前栈顶为:", my_stack.get_stack_top())
    # 出栈
    my_stack.stack_pop()
    # 判断栈是否为空
    if my_stack.stack_is_empty():
        print("********栈已空********")
    else:
        print("********栈没空********")
    # 栈长
    print("栈长为:", my_stack.stack_len())
    # 出栈
    my_stack.stack_pop()
    # 判断栈是否为空
    if my_stack.stack_is_empty():
        print("********栈已空********")
    else:
        print("********栈没空********")

本文代码思路来自书籍《Python程序员面试宝典》,书中部分代码有问题,文中已经修改过了,并添加上了丰厚的注释,方便大家学习,后面我会把所有内容开源放到Github上,包括代码,思路,算法图解(手绘或者电脑画),时间充裕的话,会录制视频。

希望大家多多支持。

大家好,我是老表

觉得本文不错的话,转发、留言、点赞,是对我最大的支持。

欢迎关注微信公众号:简说Python

关注后回复:1024,可以领取精选编程学习电子书籍。

相关文章
|
2月前
|
Java 数据挖掘 数据处理
(Pandas)Python做数据处理必选框架之一!(一):介绍Pandas中的两个数据结构;刨析Series:如何访问数据;数据去重、取众数、总和、标准差、方差、平均值等;判断缺失值、获取索引...
Pandas 是一个开源的数据分析和数据处理库,它是基于 Python 编程语言的。 Pandas 提供了易于使用的数据结构和数据分析工具,特别适用于处理结构化数据,如表格型数据(类似于Excel表格)。 Pandas 是数据科学和分析领域中常用的工具之一,它使得用户能够轻松地从各种数据源中导入数据,并对数据进行高效的操作和分析。 Pandas 主要引入了两种新的数据结构:Series 和 DataFrame。
390 0
|
5月前
|
存储 监控 安全
企业上网监控系统中红黑树数据结构的 Python 算法实现与应用研究
企业上网监控系统需高效处理海量数据,传统数据结构存在性能瓶颈。红黑树通过自平衡机制,确保查找、插入、删除操作的时间复杂度稳定在 O(log n),适用于网络记录存储、设备信息维护及安全事件排序等场景。本文分析红黑树的理论基础、应用场景及 Python 实现,并探讨其在企业监控系统中的实践价值,提升系统性能与稳定性。
159 1
|
6月前
|
编译器 C语言 C++
栈区的非法访问导致的死循环(x64)
这段内容主要分析了一段C语言代码在VS2022中形成死循环的原因,涉及栈区内存布局和数组越界问题。代码中`arr[15]`越界访问,修改了变量`i`的值,导致`for`循环条件始终为真,形成死循环。原因是VS2022栈区从低地址到高地址分配内存,`arr`数组与`i`相邻,`arr[15]`恰好覆盖`i`的地址。而在VS2019中,栈区先分配高地址再分配低地址,因此相同代码表现不同。这说明编译器对栈区内存分配顺序的实现差异会导致程序行为不一致,需避免数组越界以确保代码健壮性。
126 0
栈区的非法访问导致的死循环(x64)
232.用栈实现队列,225. 用队列实现栈
在232题中,通过两个栈(`stIn`和`stOut`)模拟队列的先入先出(FIFO)行为。`push`操作将元素压入`stIn`,`pop`和`peek`操作则通过将`stIn`的元素转移到`stOut`来实现队列的顺序访问。 225题则是利用单个队列(`que`)模拟栈的后入先出(LIFO)特性。通过多次调整队列头部元素的位置,确保弹出顺序符合栈的要求。`top`操作直接返回队列尾部元素,`empty`判断队列是否为空。 两题均仅使用基础数据结构操作,展示了栈与队列之间的转换逻辑。
|
11月前
|
存储 C语言 C++
【C++数据结构——栈与队列】顺序栈的基本运算(头歌实践教学平台习题)【合集】
本关任务:编写一个程序实现顺序栈的基本运算。开始你的任务吧,祝你成功!​ 相关知识 初始化栈 销毁栈 判断栈是否为空 进栈 出栈 取栈顶元素 1.初始化栈 概念:初始化栈是为栈的使用做准备,包括分配内存空间(如果是动态分配)和设置栈的初始状态。栈有顺序栈和链式栈两种常见形式。对于顺序栈,通常需要定义一个数组来存储栈元素,并设置一个变量来记录栈顶位置;对于链式栈,需要定义节点结构,包含数据域和指针域,同时初始化栈顶指针。 示例(顺序栈): 以下是一个简单的顺序栈初始化示例,假设用C语言实现,栈中存储
516 77
|
9月前
|
存储 人工智能 索引
Python数据结构:列表、元组、字典、集合
Python 中的列表、元组、字典和集合是常用数据结构。列表(List)是有序可变集合,支持增删改查操作;元组(Tuple)与列表类似但不可变,适合存储固定数据;字典(Dictionary)以键值对形式存储,无序可变,便于快速查找和修改;集合(Set)为无序不重复集合,支持高效集合运算如并集、交集等。根据需求选择合适的数据结构,可提升代码效率与可读性。
|
10月前
|
算法 调度 C++
STL——栈和队列和优先队列
通过以上对栈、队列和优先队列的详细解释和示例,希望能帮助读者更好地理解和应用这些重要的数据结构。
240 11
|
10月前
|
DataX
☀☀☀☀☀☀☀有关栈和队列应用的oj题讲解☼☼☼☼☼☼☼
### 简介 本文介绍了三种数据结构的实现方法:用两个队列实现栈、用两个栈实现队列以及设计循环队列。具体思路如下: 1. **用两个队列实现栈**: - 插入元素时,选择非空队列进行插入。 - 移除栈顶元素时,将非空队列中的元素依次转移到另一个队列,直到只剩下一个元素,然后弹出该元素。 - 判空条件为两个队列均为空。 2. **用两个栈实现队列**: - 插入元素时,选择非空栈进行插入。 - 移除队首元素时,将非空栈中的元素依次转移到另一个栈,再将这些元素重新放回原栈以保持顺序。 - 判空条件为两个栈均为空。
|
11月前
|
存储 C++ 索引
【C++数据结构——栈与队列】环形队列的基本运算(头歌实践教学平台习题)【合集】
【数据结构——栈与队列】环形队列的基本运算(头歌实践教学平台习题)【合集】初始化队列、销毁队列、判断队列是否为空、进队列、出队列等。本关任务:编写一个程序实现环形队列的基本运算。(6)出队列序列:yzopq2*(5)依次进队列元素:opq2*(6)出队列序列:bcdef。(2)依次进队列元素:abc。(5)依次进队列元素:def。(2)依次进队列元素:xyz。开始你的任务吧,祝你成功!(4)出队一个元素a。(4)出队一个元素x。
427 13
【C++数据结构——栈与队列】环形队列的基本运算(头歌实践教学平台习题)【合集】

推荐镜像

更多