栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Python

栈和队列—Python实现基本操作

Python 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

栈和队列—Python实现基本操作

目录

概述

应用

栈抽象数据类型

栈的顺序表实现

栈的链表实现

栈的应用

队列

栈抽象数据类型

队列的list实现

队列的链表实现


概述

        栈和队列都是保存数据元素的容器。这两种结构支持的元素访问操作包括存入、查看、元素弹出。栈和队列主要用于在计算过程中保存临时数据,这些数据是计算中发现或者产生的,在后面的计算中可能需要使用它们。

        栈和队列也是最简单的缓存结构,它们只支持数据项的存储和访问,不支持数据项之间的任何关系,因此栈和队列的实现结构只需要保证元素存入和取出的顺序,并不需要记录和保证新存入的元素和容器中已有元素之间的任何关系。

栈是后进先出关系结构,简称LIFO(Last In First Out)结构队列时先进先出关系结构,简称FIFO(First In First Out)结构

应用

栈和队列是计算中使用最广泛的缓存结构:

计算过程分为一些顺序进行的步骤计算中执行的某些步骤会不断产生一些后面可能需要的中间数据产生的数据中有些不能立即使用,但又需要在将来使用需要保存的数据的项数不能事先确定

栈(stack)是一种容器,可存入、访问、删除数据元素。栈的基本性质保证,在任何时刻可以访问、删除的元素都是在此之前最后存入的那个元素。

栈抽象数据类型
Stack:
    Stack(self)       # 创建空栈
    is_empty(self)    # 栈是否为空,True/False
    push(self, elem)  # 将元素elem加入栈
    pop(self)         # 删除栈最后压入的元素并将其返回
    top(self)         # 取得栈最后压入的元素,不删除

栈的顺序表实现
class StackUnderflow(ValueError):  # 栈下溢(空栈访问)
    pass

class SStack():
    """
    基于顺序表实现栈类,用list对象_elems存储栈中元素,所有栈操作映射到list操作
    """
    def __init__(self):
        self._elems = []
        
    def is_empty(self):
        return self._elems == []
    
    def top(self):
        if self._elems == []:
            raise StackUnderflow("in top")
        return self._elems[-1]
    
    def push(self, elem):
        self._elems.append(elem)
    
    def pop(self):
        if self._elems == []:
            raise StackUnderflow("in pop")
        return self._elems.pop()

栈的链表实现
class LNode:
    def __init__(self, elem, next_=None):
        self.elem = elem
        self.next = next_

class LStack():
    """
    基于链表实现,用LNode作为结点
    """
    def __init__(self):
        self._top = None
        
    def is_empty(self):
        return self._top is None
    
    def top(self):
        if self._top is None:
            raise StackUnderflow("in top")
        return self._top.elem
    
    def push(self, elem):
        self._top = LNode(elem, self._top)
        
    def pop(self):
        if self._top is None:
            raise StackUnderflow("in pop")
        p = self._top
        self._top = p.next
        return p.elem

栈的应用

1、括号匹配问题

思路:

顺序扫描被检查正文(一个字符串)里的一个个字符检查中跳过无关字符(所有非括号字符都与当前处理无关)遇到开括号时将其压入栈遇到闭括号时弹出当时的栈顶元素与之匹配如果匹配成功则继续,发现不匹配时检查以失败结束

def check_parens(text):
    """括号配对检查函数"""
    parens = "()[]{}"
    open_parens = "([{"
    opposite = {")": "(", "]": "[", "}": "{"}  # 配对关系
    
    def parentheses(text):
        """括号生成器,每次调用返回text里的下一个括号和位置"""
        i, text_len = 0, len(text)
        while True:
            while i < text_len and text[i] not in parens:
                i += 1
            if i >= text_len:
                return
            yield text[i], i
            i += 1
    st = SStack()
    for paren, i in parentheses(text):
        if paren in open_parens:
            st.push(paren)
        elif st.pop() != opposite[paren]:
            print("Not matching is found at", i, "for", paren)
            return False
        # else:  配对成功,什么也不做,继续
    print("All parentheses are correctly matched.")
    return True

队列 栈抽象数据类型
Queue:
    Queue(self)           # 创建空队列
    is_empty(self)        # 队列是否为空,True/False
    enqueue(self, elem)   # 将元素elem加入队列
    dequeue(self)         # 删除队列里最早进入的元素并将其返回
    peek(self)            # 查看队列里最早进入的元素,不删除

队列的list实现
class QueueUnderFlow(ValueError):
    pass

class SQueue():
    def __init__(self, init_len=8):
        self._len = init_len
        self._elems = [0] * init_len
        self._head = 0
        self._num = 0
        
    def is_empty(self):
        return self._num == 0
    
    def peek(self):
        if self._num == 0:
            raise QueueUnderFlow
        return self._elems[self._head]
    
    def dequeue(self):
        if self._num == 0:
            raise QueueUnderFlow
        e = self._elems[self._head]
        self._head = (self._head + 1) % self._len
        self._num -= 1
        return e
    
    def enqueue(self, e):
        if self._num == self._len:
            self.__extend()  # 将存储去长度加倍
        self._elems[(self._head + self._num) % self._len] = e
        self._num += 1
            
    def __extend(self):
        old_len = self._len
        self._len *= 2
        new_elems = [0] * self._len
        for i in range(old_len):
            new_elems[i] = self._elems[(self._head + 1) % old_len]
        self._elems, self._head = new_elems, 0

队列的链表实现

        链表实现队列操作没有实质性技术困难。由于需要在链接表的两端操作,从一端插入元素,从另一端删除。最简单的单链表只支持首端高效操作,在另一端操作需要O(n)时间,不适合作为队列的实现基础。带尾端指针的单链表,它支持O(1)时间的尾端插入操作。

        有了尾指针,尾端加入元素是O(1)时间操作,可以用作队列的入队操作enqueue。首端访问和删除都是O(1)时间操作,分别看作队列的peek和dequeue。实现单链表的技术可以直接用于队列,只需要修改几个名字。

class LNode:
    def __init__(self, elem, next_=None):
        self.elem = elem
        self.next = next_

class QueueUnderFlow(ValueError):
    pass

class LQueue():
    def __init__(self):
        self._head = None
        self._rear = None
    
    def is_empty(self):
        return self._head is None

    def enqueue(self, elem):
        if self._head is None:
            self._head = LNode(elem, self._head)
            self._rear = self._head
        else:
            self._rear.next = LNode(elem)
            self._rear = self._rear.next
    
    def dequeue(self):
        if self._head is None:  # 无结点,引发异常
            raise StackUnderflow("in dequeue")
        e = self._head.elem
        self._head = self._head.next
        return e
    
    def peek(self):
        if self._head is None:  # 无结点,引发异常
            raise StackUnderflow("in peek")
        return self._head.elem

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/739891.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号