Python学习
一、学前花絮
数据结构是所有的计算机语言中非常重要的一部分,但对于python来说,很多数据结构的实现是天然的,不需要做太多的工作。比如数据结构中的“栈”,完全可以用列表功能实现。
但栈并不等同于列表。栈是后进先出 (LIFO, Last In First Out),比如生活中放一摞盘子,我们总是从最上面去放,取的时候也是从最上面取。也可以把栈看做一个上面开口的桶,我们往桶里面放篮球,与放盘子一样,依赖后进先出的规则。
二、PythonC语言如何实现“栈”
2.1 Python 实现栈(面向对象)
Python 的优势在于简洁和抽象。我们不需要关心内存地址,直接利用列表(List)作为底层容器,专注于逻辑实现。

以上程序通过class实现栈的封装。栈的操作最常见的就是push和pop,也就是俗话说的把东西放入栈和从栈中取出东西。此外还有查看栈元素、判断栈是否为空、计算栈的大小等。这些操作对应class的方法。
使用栈的方法:

输出结果:

我们看到栈s满足“后进先出”的原则,说明栈是成功的。
有细心的朋友会问,这与直接操作list有什么不同呢?既然列表本身就是栈,为什么我们还要费劲去“实现”它,或者讨论这个话题呢?
这是因为在编程思维中,“接口限制” 和 “语义明确” 非常重要:
1.限制操作权限(封装)
列表的功能太强了:列表不仅可以从末尾加减元素,还可以在开头插入(insert(0, item))、删除任意位置的元素、甚至通过索引直接修改中间的值。
栈的规则很死:栈必须严格遵守“后进先出”,你不能在中间插队,也不能从底下去拿东西。
如果直接用列表,一不小心写错了代码(比如用了 insert(0, ...)),就破坏了栈的逻辑。
如果封装成栈:你可以创建一个 Stack 类,只暴露 push 和 pop 方法,这样就从代码层面强制保证了数据结构的正确性。
2.代码的可读性(语义化)
看到 stack.pop(),你立刻知道这是在处理一个“栈”。
看到 list.pop(),你可能会疑惑:这是在处理栈,还是仅仅在删除列表的最后一个元素?
你可以这样理解:
列表(List) 是一个多功能瑞士军刀,什么都能干(切菜、开瓶、剪线)。
栈(Stack) 是一个专用工具,只用来做一件事(比如专门用来开瓶)。
2.2 C 语言实现栈(过程式/指针操作)
C 语言的优势在于控制力和效率。我们必须手动管理内存(使用 malloc 和 free),并显式地处理数组越界等问题。

通过以上程序,我们是不是感觉到python的易用?如果能看懂C语言栈的实现,那么恭喜你,已经是一个专业的程序员了。C语言实现栈的功能用到结构体和指针,这对于很多人来说是一个门槛。而python实现栈功能就很容易理解了。
C程序需要编译才可以运行,安装C编译器操作略。在cmd下执行:
gcc stack.c -o stack (生成stack.exe可执行文件) |
执行stack输出结果如下:
无论是python还是C语言,无论这些语言的规则多么不同,但对于使用者来说是一样的,这也是数据结构本身是跨语言的一个标志。只要实现了栈的功能,那么就是后进先出。
2.3 Python 与 C 语言实现栈的深度对比
Python 的栈:适合快速开发、算法竞赛或业务逻辑。你关注的是“我要把数据压进去”和“我要把数据拿出来”,至于内存怎么变大、怎么管理,交给解释器去头疼。
C 的栈:适合嵌入式系统、操作系统或高性能中间件。你必须关注每一个字节的内存使用,防止溢出,确保效率极致。

一句话概括:
Python 让你站在巨人的肩膀上(列表 List),你只需要定义规则;而 C 语言要求你从零开始造轮子(管理数组和指针),虽然累,但你完全掌控了机器。
2.5栈的典型应用场景
浏览器的后退按钮:你访问的网页顺序是 A -> B -> C。点击“后退”时,先回到 B,再回到 A。这就是典型的栈操作。
撤销操作 (Undo):在编辑器中,你依次输入了文字。按 Ctrl+Z 撤销时,总是先撤销最近的操作。
括号匹配:编译器检查代码中的括号 ()、{} 是否成对出现,就是利用栈来实现的(遇到左括号入栈,遇到右括号出栈匹配)。。
三、小结
通过python的数据结构“栈”的学习,并与C语言实现栈进行了对比。我们深刻体会到为什么说python语言易学易用,就好比使用python的人已经拥有了太多的工具(模块),拿起来就可以组装成很多功能。而C语言需要掌握底层知识,尽管C语言编译后的代码执行效率高,但门槛也不是一般人所能跨过的。
让我们保持学习热情,多做练习。我们下期再见!