大话数据结构--第四章学习笔记--栈与队列

大话数据结构真的是一本好书,有这样系统的学习之后感觉自己零散的知识点回忆都被放入了整齐的盒子中。

4 栈和队列

①栈stack是只允许在尾部(栈顶)进行添加和删除数据元素的线性表(先进后出)。

可应用在Word等的撤销操作。

操作:进栈(push),出栈(pop)。

顺序存储的python代码如下:(用list实现)

#栈的顺序实现
class stack:
    def __init__(self):
        self.item = []
    def push(self,item):
        self.item.append(item)
        return self.item
    def pop(self):
        self.item.pop()
        return self.item
    def lens(self):
        return len(self.item)
    def top(self):
        return self.item[-1]

如果要查找栈中Minum的值,可以使用继承的方法。

注意继承的时候调用继承的类中的方法要加self。

Python代码如下:

class stack_min(stack):
    def __init__(self):
       stack.__init__(self)
       self.mins = stack()
    def push(self,item):
        stack.push(self,item)
        if item <= self.mins.top() or len(self.mins.lens()) == 0:
            self.mins.push(item)
    def min(self):
        return self.mins.top()
    def pop(self):
        item = stack.pop(self)
        if item == self.mins.top():
            self.mins.pop()
        return item

 

链式存储:链栈

链栈,头指针指向栈顶即可,栈顶为单链表的头结点。为空就是头指针指向空。

用python实现如下:

class linked_list:
    def __init__(self,item):
        self.val = item
        self.next = None

#链式存储结构
class stack_linked_list:
    def __init__(self):
        self.top = None #栈顶指针
        self.cur = None #游标

    def push_stack(self,item):
        node = linked_list(item)
        self.top = node
        node.next = self.cur
        self.cur = node
        return self.top

    def pop_stack(self):
        while self.top:
            value = self.top.val
            self.top = self.top.next
            return value

这里删除和插入的操作时间复杂度都是o(1)。

 

栈的应用:递归

首先介绍最有名的递归程序,斐波那契数列。

#菲波那切数列生成 0,1,1,2,3.......
def f(n):
    #寻找base case,和普遍规律
    if n == 0:
        return 0
    if n == 1:
        return 1
    return f(n-1) + f(n-2)
print(f(3))#n是指的数值的索引位置

 

说个题外话:斐波那契数列的实现这样递归会很耗时,所以还可以使用其他的方法。在牛客网上搞了好久,真的是really尴尬.....

def f(n):
    if n <= 2:
        return 1
    a,b = 0,1
    for i in range(n):
        a,b = b,a+b
    return a

栈和递归的关系是什么呢?

递归过程退回的顺序是她前行顺序的逆序,在退回过程中要执行某些动作,包括恢复在前行过程中存储的某些数据,这时就需要用到栈。

栈还可以应用到四则运算表达式求值,遇到左括号,就入栈,等遇到右括号,就出栈。

但是有括号还是要解决先加减后乘除的问题,所以rpn 逆波兰表示法诞生。将数学表达式转换成后缀表达式,初始化空栈,遇到数字就入栈,遇到符号就前两个数字出栈进行运算,结果再入栈,以此类推,最终得到结果。但是我们平时的标准四则运算表达式(中缀表达式)是如何转化为后缀表达式的呢?书108-110

②队列(queue)是可以在一头进行添加和另一头进行删除数据元素的线性表(先进先出)

操作系统和客服系统,使用队列。

顺序存储:

#queue by list
class queue:
    def __init__(self):
        self.item = []
    def enqueue(self,item):
        return self.item.append(item)
    def dequeue(self):
        while self.item:
            item = self.item[0]
            del self.item[0]
            return item
        return None

队列的入队时间复杂度为o(1),顺序存储时出队时间复杂度为o(n),因为出栈的时候所有元素要向前移动一位,为了节约时间,引出了循环队列。

循环队列是移动队头和队尾的指针,当front和rear指针相等时,队列为空。循环队列也会遇到数据容易溢出等问题,所以引出链式存储的队列。

链式存储:

class linked_list:
    def __init__(self,value):
        self.val = value
        self.next = None
class queue_linked_list:
    def __init__(self):
        self.top = None
        self.tail = None
    def enqueue(self,value):
        node = linked_list(value)
        if self.top == None and self.tail == None:
            self.top = self.tail = node
        else:
            self.tail.next = node
            self.tail = node
    def dequeue(self):
        while self.top:
            val = self.top.val
            self.top = self.top.next
            return val
        return None

 

如果要在队列中实现查找并返回队列最小值,也类似栈,使用继承。

class queue:
    def __init__(self):
        self.item = []

    def enqueue(self,item):
        return self.item.append(item)

    def dequeue(self):
        while self.item:
            item = self.item[0]
            del self.item[0]
            return item
        return None

class queue_min(queue):
    def __init__(self):
        queue.__init__(self)
        self.mins = queue()

    def mins(self):
        return self.mins.dequeue()

    def enqueue(self,item):
        queue.enqueue(self,item)
        if item <= self.mins.item[0] or len(self.mins.item) == 0:
            self.mins.enqueue(item)

    def dequeue(self):
        item = queue.dequeue()
        if item == self.mins.item[0]:
            self.mins.dequeue()
        return item

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值