python之栈的实现

一、用列表模拟栈

栈并不是python的内建类型,可以通过使用list来模拟栈,将列表的末尾看做栈的顶。用这种方法的主要缺点是:所有其他的列表操作也可以操作这个栈,包括任意位置插入、替换和删除元素,这些操作就违反了栈作为一种抽象数据类型的本意。

1.1 栈方法:

栈方法作用
s.isEmpty()如果为空,返回True,否则返回False
s.size()返回s中项目的数目
s.iter()从底部到顶部,访问s中的每一项
s.push(item)在s的顶部添加一项
s.pop()在s的顶部删除一项,并返回该项。先验条件:s必须不为空,如果栈为空,将抛出KeyError
s.peek()

返回s的顶部的项,先验条件:s必须不为空,如果栈为空,将抛出KeyError

s.clear()将s清空

1.2 用列表模拟栈的实现代码:

#用列表模拟栈
class Stack:
    """A list_based stack implementation."""
    
    # Constructor
    def __init__(self):
        """Sets the initial state of self,and the initial state is []"""
        self.items = []
    
    # Accessor methods
    def iter(self):
         """Supports iteration over a view of self.
         Visits items from bottom to top of stack."""
         for i in range(len(self.items)):
             yield self.items[i]
         
    def isEmpty(self):
        """Returns True if len(self) == 0, or False otherwise."""
        return len(self.items)==0

    def peek(self):
        """
        Returns the item at the top of the stack.
        Precondition: the stack is not empty.
        Raises: KeyError if the stack is empty."""
        if self.isEmpty():
            raise KeyError("The stack is empty.")
        
        return self.items[len(self.items)-1]
     
    def size(self):
        """return the len(self)"""
        return len(self.items)
    
    # Mutator methods
    def clear(self):
        """Makes self become empty."""
        self.items = []
        
    def push(self, item):
        """Adds item to the top of the stack."""
        self.items.append(item)
   
    def pop(self):
        """
        Removes and returns the item at the top of the stack.
        Precondition: the stack is not empty.
        Raises: KeyError if the stack is empty.
        Postcondition: the top item is removed from the stack."""
        if self.isEmpty():
            raise KeyError("The stack is empty.")
        return self.items.pop() 

1.3 栈操作效果

#测试    
if __name__=='__main__':
    s=Stack()                  #创建一个空栈
    s.push('a')
    s.push('b')
    s.push('c')
    print(list(s.iter()))       #return:['a', 'b', 'c']
    print(s.size())             #return:3
    print(s.pop())              #return:c
    print(s.peek())             #return:b
    print(s.pop())              #return:b
    print(s.pop())              #return:a
    #若在此处添加一句:s.pop()或s.peek(),将报错:"The stack is empty."
    s.clear()
    print(s.isEmpty())          #return:True

二、利用链表实现栈

2.1创建一个抽象集合类,并保存为abstractcollection.py文件

class AbstractCollection(object):
    """An abstract collection implementation."""

    # Constructor
    def __init__(self, sourceCollection = None):
        """Sets the initial state of self, which includes the
        contents of sourceCollection, if it's present."""
        self._size = 0
        if sourceCollection:
            for item in sourceCollection:
                self.add(item)

    # Accessor methods
    def isEmpty(self):
        """Returns True if len(self) == 0, or False otherwise."""
        return len(self) == 0
    
    def __len__(self):
        """Returns the number of items in self."""
        return self._size

    def __str__(self):
        """Returns the string representation of self."""
        return "[" + ", ".join(map(str, self)) + "]"

    def __add__(self, other):
        """Returns a new bag containing the contents
        of self and other."""
        result = type(self)(self)
        for item in other:
            result.add(item)
        return result

    def __eq__(self, other):
        """Returns True if self equals other,
        or False otherwise."""
        if self is other: return True
        if type(self) != type(other) or \
           len(self) != len(other):
            return False
        otherIter = iter(other)
        for item in self:
            if item != next(otherIter):
                return False
        return True

2.2 创建一个抽象栈类,保存为abstractstack.py

from abstractcollection import AbstractCollection

class AbstractStack(AbstractCollection):
    """An abstract stack implementation."""

    # Constructor
    def __init__(self, sourceCollection = None):
        """Sets the initial state of self, which includes the
        contents of sourceCollection, if it's present."""
        AbstractCollection.__init__(self, sourceCollection)

    # Mutator methods
    def add(self, item):
        """Adds item to self."""
        self.push(item)
2.3 创建一个节点类,保存为node.py
class Node(object):
    """Represents a singly linked node."""

    def __init__(self, data, next = None):
        self.data = data
        self.next = next

2.4 用链表实现栈,保存为linkedstack.py

from node import Node
from abstractstack import AbstractStack

class LinkedStack(AbstractStack):
    """A link-based stack implementation."""

    # Constructor
    def __init__(self, sourceCollection = None):
        """Sets the initial state of self, which includes the
        contents of sourceCollection, if it's present."""
        self._items = None
        AbstractStack.__init__(self, sourceCollection)

    # Accessor methods
    def __iter__(self):
        """Supports iteration over a view of self.
        Visits items from bottom to top of stack."""
        
        def visitNodes(node):
            """Adds items to tempList from tail to head."""
            if not node is None:
                visitNodes(node.next)
                tempList.append(node.data)
                
        tempList = list()                
        visitNodes(self._items)
        return iter(tempList)

    def peek(self):
        """
        Returns the item at the top of the stack.
        Precondition: the stack is not empty.
        Raises: KeyError if the stack is empty."""
        if self.isEmpty():
            raise KeyError("The stack is empty.")
        return self._items.data

    # Mutator methods
    def clear(self):
        """Makes self become empty."""
        self._size = 0
        self._items = None

    def push(self, item):
        """Adds item to the top of the stack."""
        self._items = Node(item, self._items)
        self._size += 1

    def pop(self):
        """
        Removes and returns the item at the top of the stack.
        Precondition: the stack is not empty.
        Raises: KeyError if the stack is empty.
        Postcondition: the top item is removed from the stack."""
        if self.isEmpty():
            raise KeyError("The stack is empty.")
        data = self._items.data
        self._items = self._items.next
        self._size -= 1
        return data

三、用数组实现栈

3.1 创建一个数组类,保存为arrays.py

"""
File: arrays.py

An Array is a restricted list whose clients can use
only [], len, iter, and str.

To instantiate, use

<variable> = array(<capacity>, <optional fill value>)

The fill value is None by default.
"""

class Array(object):
    """Represents an array."""

    def __init__(self, capacity, fillValue = None):
        """Capacity is the static size of the array.
        fillValue is placed at each position."""
        self._items = list()
        for count in range(capacity):
            self._items.append(fillValue)

    def __len__(self):
        """-> The capacity of the array."""
        return len(self._items)

    def __str__(self):
        """-> The string representation of the array."""
        return str(self._items)

    def __iter__(self):
        """Supports iteration over a view of an array."""
        return iter(self._items)

    def __getitem__(self, index):
        """Subscript operator for access at index."""
        return self._items[index]

    def __setitem__(self, index, newItem):
        """Subscript operator for replacement at index."""
        self._items[index] = newItem

3.2 创建一个抽象栈类,保存为abstractstack.py  (同上)

3.3用数组实现栈,保存为arraystack.py

from arrays import Array
from abstractstack import AbstractStack

class ArrayStack(AbstractStack):
    """An array-based stack implementation."""

    # Class variable
    DEFAULT_CAPACITY = 10

    # Constructor
    def __init__(self, sourceCollection = None):
        """Sets the initial state of self, which includes the
        contents of sourceCollection, if it's present."""
        self._items = Array(ArrayStack.DEFAULT_CAPACITY)
        AbstractStack.__init__(self, sourceCollection)

    # Accessor methods
    def __iter__(self):
        """Supports iteration over a view of self.
        Visits items from bottom to top of stack."""
        cursor = 0
        while cursor < len(self):
            yield self._items[cursor]
            cursor += 1

    def peek(self):
        """Returns the item at the top of the stack.
        Precondition: the stack is not empty.
        Raises: KeyError if stack is empty."""
        if self.isEmpty():
            raise KeyError("The stack is empty")
        return self._items[len(self) - 1]

    # Mutator methods
    def clear(self):
        """Makes self become empty."""
        self._size = 0
        self._items = Array(ArrayStack.DEFAULT_CAPACITY)

    def push(self, item):
        """Inserts item at top of the stack."""
        # Resize array here if necessary
        self._items[len(self)] = item
        self._size += 1

    def pop(self):
        """Removes and returns the item at the top of the stack.
        Precondition: the stack is not empty.
        Raises: KeyError if stack is empty.
        Postcondition: the top item is removed from the stack."""
        if self.isEmpty():
            raise KeyError("The stack is empty")
        oldItem = self._items[len(self) - 1]
        self._size -= 1
        # Resize the array here if necessary
        return oldItem
        
         

四、测试链表栈或数组栈

from arraystack import ArrayStack
from linkedstack import LinkedStack

def test(stackType):
    # Test any implementation with same code
    s = stackType()
    print("Length:", len(s))
    print("Empty:", s.isEmpty())
    print("Push 1-10")
    for i in range(10):
        s.push(i + 1)
    print("Peeking:", s.peek())
    print("Items (bottom to top):",  s)
    print("Length:", len(s))
    print("Empty:", s.isEmpty())
    theClone = stackType(s)
    print("Items in clone (bottom to top):",  theClone)
    theClone.clear()

    print("Length of clone after clear:",  len(theClone))

    print("Push 11")
    s.push(11)
    print("Popping items (top to bottom): ", end="")
    while not s.isEmpty(): print(s.pop(), end=" ")
    print("\nLength:", len(s))
    print("Empty:", s.isEmpty())

#test(ArrayStack)
test(LinkedStack)
链表和数组实现的栈比列表实现的栈要更加严格。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值