Python 数据结构 栈与队列

先设置栈下溢异常

class StackUnderflow(ValueError): # 栈下溢
    pass

栈的顺序表实现

class SStack():                     # 基于顺序表技术实现的栈类
    def __init__(self):             # 用list对象 _elems存储栈中元素
        self._elems = []            # 所有栈操作都映射到list的操作

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

    def top(self):
        if self._elems == []
            raise StackUnderflow("in SStack.top()")
        return self._elems[-1]

    def push(self, elem):
        self._elems.append(elem)

    def pop(self):
        if self._elems == []
            raise StackUnderflow("in SStack.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 == None

    def top(self):
        if self._top is None
            raise StackUnderflow("in LStack.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 LStack.pop()")
        p = self._top
        self._top = p.next
        return p.elem

栈的应用: 简单背包问题

"""
一个背包可放入重量为weight的物品, 现有n件物品的集合S, 其中物品的重量分别为w0, w1,...,wn-1
问题是能否从中选出若干件物品,其重量之和正好等于weight。如果存在说明有解,否则无解。
"""
def knap_rec(weight, wlist, n):
    if weight == 0:
        return True
    if weight < 0 or (weight > 0 and n < 1):
        return False
    if knap_rec(weight - wlist[n-1], wlist, n-1):
        print("Item " + str(n) + ":", wlist[n-1])
        return True
    if knap_rec(weight, wlist, n-1):
        return True
    else:
        return False

队列

队列的list实现

队列的首元素在self._elems[self._head], peek 和 dequeue操作应该取这里的元素;下一个空位在self._elems[(self._head + self._num) % self._len], 入队的新元素应该存放在这里。

另外,队列空就是self._num = = 0, 当前队列满就是self._num == self._len, 这个条件成立时应该换一块存储区。

 

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("in peek")
        return self._elems[self._head]
    
    def dequeue(self):
        if self._num == 0:
            raise QueueUnderflow("in dequeue")
        e = self._elems[self._head]
        self._head = (self._head+1) % self._len
        self._num -= 1
        return e
    
    def enqueue(self):
        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+i)%old_len]
        self._elems, self._head = new_elems, 0

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值