python中栈的单链表实现

参考博客:https://www.cnblogs.com/stacklike/p/8284550.html

基于列表的简单实现

# 先进后出
# 以列表实现的简单栈
class SimpleStack:
    # 特殊属性,用以限制class可添加的属性
    __slots__ = (‘__items‘,)

    def __init__(self):
        self.__items = []

    def is_empty(self):
        return self.__items == []

    def peek(self):
        return self.__items[len(self.__items)-1]

    def size(self):
        return len(self.__items)

    def push(self, item):
        self.__items.append(item)

    def pop(self):
        self.__items.pop()

以单链表的形式实现栈

class StackFullException(Exception):  # 满栈时要抛出的异常
    pass

class StackEmptyException(Exception):  # 空栈时要抛出的异常
    pass

class Node:
    def __init__(self, val=None, nxt=None):
        self.value = val  # 信息域
        self.next = nxt   # 指针域

    def __str__(self):
        return str(self.value)

class Stack:
    # 初始化一个空栈
    def __init__(self, max=0):
        self._top = None  # 栈的顶部元素
        self._max = 0  # 栈的最大高度
        self.max = max  # 用户将设置的最大栈高度

    @property
    def length(self):
        if self._top is None:
            return 0
        node = self._top
        count = 1  # 只要不为空,就至少有一个节点,因此由1开始
        # 借由节点内的指针来判断是否有下一个元素,只要就由当前节点跳到下一个节点,并将计数加1
        while node.next:
            node = node.next
            count += 1
        return count

    @property
    def is_empty(self):
        return self._top is None

    @property
    def is_full(self):
        # 满栈的条件是栈的最大高度不是无限的(设置最大值时会将负数也转为0,0就代表了无限大小)
        # 而且当前栈高等于允许的最大栈高
        return bool(self._max and self.length == self._max)

    @property
    def max(self):
        return self._max

    @max.setter
    def max(self, m):
        m = int(m)  # 可能传入值是str或float
        if m < self.length:  # 设置值是否小于当前栈的高度,是则要抛出异常
            raise Exception(‘Stack resize failed, please pop some elements first.‘)
        self._max = 0 if m < 0 else m  # 输入值又是否是负数或0,是则都设置为0,当作无限大小

    # 通过逐个压入传入的iterable,由空栈构建出一个栈
    def init(self, iterable=()):
        if not iterable:  # 传入一个可迭代对象
            return
        self._top = Node(iterable[0])  # 将其起始元素设置为栈顶
        for item in iterable[1::]:  # 将之后的元素也依次压入栈中,每一次压入栈定元素都会被替换
            node = self._top  # 原栈顶元素先储存起来
            self._top = Node(item)  # 将当前元素设置为栈顶
            self._top.next = node  # 将设置过的栈定的指针指向原来的栈顶

    """
    |   5   |
    |   4   |
    |   3   |
    |   2   |
    |   1   |  显示的样板
    """
    def show(self):
        # 定义的子函数是为了遍历栈,这里用到了生成器
        def _traversal(self):
            node = self._top
            while node and node.next:
                yield node
                node = node.next
            # 这里如果不yield,则栈底的元素会无法被遍历到,因为最后一个元素并不满足while循环的条件,会中止迭代
            yield node
        # <>^ 左/右/居中对齐
        # 生成器也是可迭代的,这里用高阶函数将字符串格式方法映射到每一个元素上
        print(‘\n‘.join(map(lambda x: ‘|{:^7}|‘.format(str(x)), _traversal(self))) + ‘\n ‘ + 7 * ‘-‘)

    def push(self, item):
        # 如果栈已满,则抛出异常
        if self.is_full:
            raise StackFullException(‘Error: trying to push an item into a full stack.‘)
        # 如果栈是空的,则直接将item设置为栈顶,返回即可,因为不需要设置指针
        if not self._top:
            self._top = Node(item)
            return
        node = self._top  # 先取到原栈顶
        self._top = Node(item)  # 设置item为栈顶
        self._top.next = node  # 将设置过的栈顶的指针指向原栈顶

    def pop(self):
        if self.is_empty:
            raise StackEmptyException(‘Error: trying to pop from an empty stack.‘)
        node = self._top  # 先取到原栈顶
        self._top = self._top.next  # 将栈顶设置为原栈顶的下一个元素
        return node.value  # 返回原栈顶的值

    def top(self):
        return self._top.value if self._top else None

    def clear(self):  # 在已构造的方法上再构造新方法
        while self._top:
            self.pop()

s = Stack()
s.init([1, 2, 3, 4, 5])
s.show()

原文地址:https://www.cnblogs.com/yifeixu/p/8723578.html

时间: 2024-08-12 17:36:53

python中栈的单链表实现的相关文章

python中的数据结构-链表

一.什么是链表 链表是由一系列节点构成,每个节点由一个值域和指针域构成,值域中存储着用户数据,指针域中存储这指向下一个节点的指针.根据结构的不同,链表可以分为单向链表.单向循环链表.双向链表.双向循环链表等.单向链表的结构如下图所示: head 节点永远指向第一个节点, tail节点永远指向最后一个节点,节点中最后一个指针指向的是None 值,链表本质上就是由指针链接起来的一系列值. 二.为什么使用链表 我们经常拿链表和数组作比较,实际上数组是一组固定长度的序列,链表可以动态地分配元素,下面我们

C#中泛型和单链表

泛型是 2.0 版 C# 语言和公共语言运行库 (CLR) 中的一个新功能.泛型将类型参数的概念引入 .NET Framework,类型参数使得设计如下类和方法成为可能:这些类和方法将一个或多个类型的指定推迟到客户端代码声明并实例化该类或方法的时候.例如,通过使用泛型类型参数 T,您可以编写其他客户端代码能够使用的单个类,而不致引入运行时强制转换或装箱操作的成本或风险 泛型概述:1.使用泛型类型可以最大限度地重用代码.保护类型的安全以及提高性能.2.泛型最常见的用途是创建集合类.3..NET F

Javascript - 栈 和 单链表

最近在重温数据结构,于是写了一些代码玩玩,都是很初级的,表喷各位.... function Stack() { this.dataStore = []; this.top = 0; } Stack.prototype = { length: function () { return this.top; }, push: function (element) { this.dataStore[this.top++] = element; return this.top; }, pop: funct

python中栈和队列简单学习

栈#模拟栈结构#栈有先后顺序的.后进的先取出,先进的最后取出stack=[] #压栈(向栈里存数据)stack.append("a")print(stack)stack.append("b")print(stack) #出栈(在栈里取数据)res1=stack.pop()print("res1=",res1)print(stack)res2 =stack.pop()print("res2=",res2)print(stack)

用栈实现单链表的逆转

#include<iostream> #include<stack> using namespace std; struct ListNode { ListNode *next; int data; ListNode(int x): { data=x; next=NULL: } }; ListNode* ReverseList(ListNode* pHead) { if(pHead==NULL||pHead->next == NULL) { return pHead; } L

在python中一对单引号,一对双引号,三个单双引号的区别和用法

首先说明,在python中三个单双引号并不是真正的注释 >>> type("""abcde""") <class 'str'> >>> type('''abcd''') <class 'str'> 这样可以看出三对单,双引号是有数据类型的 三对单,双引号的用法是定义的时候可以定义多行字符串 >>> a = """ ... a ... b .

java单链表常用操作

总结提高,与君共勉 概述. 数据结构与算法亘古不变的主题,链表也是面试常考的问题,特别是手写代码常常出现,将从以下方面做个小结 [链表个数] [反转链表-循环] [反转链表-递归] [查找链表倒数第K个节点] [查找链表中间节点] [判断链表是否有环] [从尾到头打印单链表-递归] [从尾到头打印单链表-栈] [由小到大合并有序单链表-循环] [由小到大合并有序单链表-递归] 通常在java中这样定义单链表结构 <span style="font-family:Microsoft YaHe

Python实现栈、队列

目录 1. 栈的Python实现 1.1 以列表的形式简单实现栈 1.2 以单链表形式实现栈 2. 队列的Python实现 2.1 以列表实现简单队列 ? 本文将使用python实现数据结构中的栈.队列:有关栈.队列的理论原理请参考:<数据结构与算法>-3-栈和队列: 1. 栈的Python实现 1.1 以列表的形式简单实现栈 """ 以列表的形式简单实现栈 栈:先进后出 """ class Stack: def __init__(s

Python中的raw字符串和多行字符串

1.raw字符串(原始字符串) 如果一个字符串包含很多需要转义的字符,对每一个字符都进行转义会很麻烦.为了避免这种情况, 我们可以在字符串前面加个前缀r,表示这是一个 raw 字符串,里面的字符就不需要转义了.例如: r'\(^_^)/ \(~_~)/' raw字符串表示原始字符串,我对于原始的理解就是:你看到这个字符串是什么就显示什么,去掉 所有字符都不进行转义,该显示啥就是啥. 2.多行显示 Python中除了可以使用单引号' '.双引号" "表示一个字符串,还可以使用三引号来表示