Python学习笔记:4.1.3 栈

本文深入讲解了栈这一数据结构的概念,详细介绍了使用Python通过列表和链表两种方式实现栈的具体方法,包括栈的主要操作如压栈、弹栈、检查空栈等,并分析了不同实现方式的优劣及时间复杂度。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

本文是学习陆老师的《python全栈工程师 - 数据结构与算法》课程的笔记,欢迎学习交流。同时感谢陆老师的精彩传授!

一、课程目标
  • 什么是栈
  • 栈的python实现
二、详情解读

01.什么是栈: 栈是一种线性表

1.栈中必须有第一个元素与最后一个元素
2.对栈的操作只能从某一端操作,即栈顶(top)
3.栈的数据访问遵从LIFO(last-in first-out)协议

在这里插入图片描述
在这里插入图片描述
02.栈(stack)的python实现:
1).栈的方法(主要方法列表)

方法说明
s.isEmpty()栈是否为空
s.__ len __()栈中的项目数
s.push()在栈顶压入一项
s.top()如果s不为空,返回顶部第一项,否则抛出错误EmptyError
s.pop()如果s不为空,返回并删除第一项,否则抛出错误EmptyError

2).栈的实现

列表实现

1.使用列表实现栈,可以从列表末尾压入与弹出(因为从末尾操作时间复杂度为O(1),其他位置操作是O(n))
2.由于列表是一个动态数组,当栈的变化引起列表内存占用变大时,会引起性能的损耗
因此数据变化大时不宜用列表实现栈

'''
用列表实现的栈
'''

class EmptyError(Exception):
    def __init__(self, errno, error):
        self.errno = errno
        self.error = error


class ListStack:
    def __init__(self):
        self.data = []

    def __len__(self):
        return len(self.data)

    def isEmpty(self):
        return len(self.data) == 0

    def checkEmpty(self):
        if self.isEmpty():
            raise EmptyError(1, 'stack is empty')

    def push(self, data):
        self.data.append(data)

    def pop(self):
        self.checkEmpty()
        return self.data.pop()

    def top(self):
        self.checkEmpty()
        return self.data[-1]


mystack = ListStack()
for i in range(10):
    mystack.push(i)
print(mystack)
while True:
    try:
        print(mystack.pop())
    except EmptyError:
        break

链表实现栈

1.使用链表实现栈,可以从链表首部压入与弹出
2.随着栈的增大,链表的内存占用线性增长

from linkedlist import Node, LinkedList


class EmptyError(Exception):
    def __init__(self, errno, error):
        self.errno = errno
        self.error = error


class LinkedStack:
    def __init__(self):
        self.data = LinkedList()

    def __len__(self):
        return len(self.data)

    def isEmpty(self):
        return len(self.data) == 0

    def checkEmpty(self):
        if self.isEmpty():
            raise EmptyError(2, 'stack is empty')

    def push(self, data):
        node = Node(data)
        self.data.insert_head(node)

    def pop(self):
        self.checkEmpty()
        return self.data.pop_first().data

    def top(self):
        self.checkEmpty()
        return self.data.head.data
# linkedlist.py文件
class Node:
    def __init__(self, data, next=None):
        self.data = data
        self.next = next

    def get_data(self):
        return self.data

    def get_next(self):
        return self.next

    def set_data(self, new_data):
        self.data = new_data


class LinkedList:
    def __init__(self):
        self.head = None
        self.length = 0

    def __len__(self):
        return self.length

    def insert_head(self, node):
        '''
        插入节点
        '''
        self.head, node.next = node, self.head
        self.length += 1

    def __iter__(self):
        '''
        遍历链表
        '''
        head = self.head
        while head is not None:
            current, head = head, head.next
            yield current

    def append_node(self, node):
        '''
        末尾插入节点
        '''
        current = self.head
        while current.next is not None:
            current = current.next
        current.next = node
        self.length += 1

    def pop_first(self):
        '''
        弹出并返回第一个节点
        '''
        head = self.head
        if self.head is not None:
            self.head = self.head.next
        self.length -= 1
        return head

    def pop_last(self):
        '''
        弹出最后一个节点
        '''
        current = self.head
        while current.next.next is not None:
            current = current.next
        node, current.next = current.next, None
        self.length -= 1
        return node

    def insert(self, index, new_node):
        '''
        在第index处插入数据
        '''
        if self.head is None or index < 1:
            self.head, new_node.next = new_node, self.head
        else:
            current = self.head
            while index > 1 and current.next is not None:
                current = current.next
                index -= 1
            current.next, new_node.next = new_node, current.next
            self.length += 1

    def remove(self, index):
        '''
        删除index处节点
        '''
        if self.head is None or index < 0:
            return None
        else:
            current = self.head
            while index > 1 and current.next is not None:
                current = current.next
                index -= 1
            current.next = current.next.next
            self.length -= 1

03.栈的时间复杂度

栈的压入与弹出时间复杂度

无论是压入或者弹出,栈的时间复杂度始终是O(1)

三、课程小结
  • 学习了栈的概念
  • 学习了栈的python实现
  • 学习了栈的时间复杂度
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值