Python学习笔记:4.1.3 栈

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

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

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

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

Python学习笔记:4.1.3 栈_第1张图片
Python学习笔记:4.1.3 栈_第2张图片
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实现
  • 学习了栈的时间复杂度

你可能感兴趣的:(Python全栈工程师学习笔记,python,栈,python列表实现栈,python链表实现栈)