《python全栈工程师 - 数据结构与算法》:栈

《python全栈工程师 - 数据结构与算法》

一、课程目标

  1. 什么是栈
  2. 栈的python实现

二、详情解读

  1. 什么是栈

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

在这里插入图片描述
在这里插入图片描述

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

列表实现

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

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.随着栈的增大,链表的内存占用线性增长

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):
        '''
        末尾插入
        :param node:
        :return:
        '''
        current=self.head
        while current.next is not None:
            current=current.next
        current.next=node
        self.length+=1

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

    def pop_last(self):
        '''
        弹出最后一个节点
        :return:
        '''
        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处插入数据
        :param index:
        :param new_node:
        :return:
        '''
        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):
        '''
        移除
        :param index:
        :return:
        '''
        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
from linkedist 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 push(self,data):
        node=Node(data)
        self.data.insert_head(node)
    def checkEmpty(self):
        if self.isEmpty():
            raise EmptyError(2,'stack is empty')
    def pop(self):
        self.checkEmpty()
        return self.data.pop_first().data

    def top(self):
        self.checkEmpty()
        return self.data.head.data

linkedstack=LinkedStack()
for i in range(10):
    linkedstack.push(i)

while not linkedstack.isEmpty():
    print(linkedstack.pop())
  1. 栈的时间复杂度

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值