• 栈和队列(1)----实现


    一、题一

    1、设计一个有getMin功能的栈

    题目:实现一个特殊的栈,在实现栈的基本功能基础上,再实现返回栈中最小元素的操作。

    要求:(1)pop、push、getMin操作的时间复杂度都是O(1)。(2)设计的栈类型可以使用现成的栈结构。

    2、思路:

    使用两个栈,一个栈保存当前栈中的元素,记做stackData;一个栈保存最小值的栈,记做stackMin,栈顶数据为最小的数据。

    两个栈使用方案:

    push【压入数据】:

    假设要压入数据 x ,先压入原始栈 stackData,

    然后判断stackMin是否为空,如果空,直接将 x 也压入stackMin。

    如果不为空,则将 x 和 stackMin 栈顶数据比较大小,

    如果 x 较小或相等,则将其压入stackMin;

    如果 x 较大,则不压。

     

    pop【弹出数据】:

     从原始栈 stackData先弹出元素,记为data,然后比较当前stackMin的栈顶元素和data相等还是不等,【原因是stackMin中元素肯定比data小或者相等】。如果不等,则不操作,如果相等,则将stackMin的栈顶元素弹出。

    getMin【查询最小值】:

     返回stackMin中的栈顶元素。

    3、代码:

    import queue
    class Stack():
        def __init__(self):
            self.stack = queue.LifoQueue()
            self.stackMin = queue.LifoQueue()
        def pop(self):
            value = self.stack.get()
         if self.stackMin.empty():
          print("is empyty")
    valueMin
    = self.stackMin.get() if value != self.stackMin.get(): self.stackMin.put(valueMin) def push(self,x): self.stack.put(x) if self.stackMin.empty(): self.stackMin.put(x) else: value = self.stackMin.get() if x <= value: self.stackMin.put(value) self.stackMin.put(x) else: self.stackMin.put(value) def getMin(self): value = self.stackMin.get() self.stackMin.put(value) return value a = Stack() a.push(1) a.push(3) a.push(0) a.push(9) a.pop() print(a.getMin())

    二、题二

    1、由两个栈实现队列:

    思路一:将stack1作为存储空间,将stack2作为临时缓冲区,入队时,直接压入stack1,出队时,将stack1中的元素依次出栈压入stack2中,再将stack2的栈顶元素弹出,最后将stack2中的元素再倒回给stack1

    思路二:入队时,判断stack1是否为空,如果stack1为空,则将stack2中的所有元素都倒入stack1中,再将元素直接压入stack1,否则,直接压入stack1中  

               出队时,判断stack2是否为空,如果stack2为空,则将stack1中的元素倒入stack2中,在将stack2的栈顶元素弹出,否则,直接弹出stack2的栈顶元素

    2、思路三:

    入队时,直接压入stack1中

    出队时,判断stack2是否为空,如果stack2为空,则将stack1中的元素倒入stack2中,否则直接弹出stack2中的元素

    思路一与思路二相比,如果是连续出栈操作或连续进栈操作,思路二比思路一好很多。思路三最好。

    详细介绍思路三如下:

    stackPush栈只压入数据,stackPop只做弹出栈。

     

     实现流程:

    push:往stackPush插入;

    pop:首先判断stackPop是否为空,如果空则把stackPush压入stackPop,除了其栈底元素。

      如果不为空,则直接将stackPop中的栈顶元素删除;

    例子:

    先插入 a,b,c【往栈1压】;

    删除 a 【栈2中没有元素,则将栈1的元素倒入栈2中,除了栈底的元素】; 

    再删除b【栈2有元素,则将栈2栈顶数据删除】

    再插入d【加入栈1】

    再删除c 【栈2没空,则删除栈2栈顶元素】

    3、代码:

    import queue
    class builtqueue():
        def __init__(self):
            self.stackPush = queue.LifoQueue()
            self.stackPop = queue.LifoQueue()
        def push(self,x):
            self.stackPush.put(x)
        def pop(self):
            if self.stackPop.empty():
                while not self.stackPush.empty():
                    self.stackPop.put(self.stackPush.get())
            return self.stackPop.get()
            
    a = builtqueue()
    a.push('a')
    a.push('b')
    a.push('c')
    print(a.pop())
    print(a.pop())
    a.push('d')
    print(a.pop())

     


    三、题三

    1、两个队列实现一个栈:

    2、思路:

     将queue1用作进栈出栈,queue2作为一个中转站

    入栈时,直接压入queue1中

    出栈时,先将queue1中的元素除最后一个元素外依次出队列,并压入队列queue2中,将留在queue1中的最后一个元素出队列即为出栈元素,最后还要把queue2中的元素再次压入queue1中


    四、题四:栈的压入、弹出序列

    输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否可能为该栈的弹出顺序。假设压入栈的所有数字均不相等。例如序列1,2,3,4,5是某栈的压入顺序,序列4,5,3,2,1是该压栈序列对应的一个弹出序列,但4,3,5,1,2就不可能是该压栈序列的弹出序列。(注意:这两个序列的长度是相等的)

    思路:

      建立一个辅助栈stack,

      每次判断辅助栈stack顶部元素和popV的第一个元素是否一样,【一样则popV.pop(0)且stack.pop()】

      然后判断pushV[i] 和popV的第一个元素是否一样,【一样则popV.pop(0)且 i += 1】

        若不一样则stack.append(pushV[i])

     总体:

      建立一个辅助栈s,把序列1,2,3,4,5依次压入辅助栈s,并按照第二个序列4,5,3,2,1的顺序从辅助栈s中弹出数字。

      先将序列1,2,3,4,5依次压入栈s,每次压栈时都判断栈s的当前栈顶元素跟序列4,5,3,2,1的第一个元素是否相等。当压入4之后,发现栈顶元素跟序列4,5,3,2,1的第一个元素相等。弹出栈s的栈顶元素4,然后将序列4,5,3,2,1中第一个元素去掉,序列4,5,3,2,1变成序列5,3,2,1。在执行上述过程。

    代码:

      

        def IsPopOrder(self, pushV, popV):
            # write code here
            if not pushV:
                return True
            stack = []
            i = 0
            while i < len(pushV):
                while stack and stack[-1] == popV[0]:
                    popV.pop(0)
                    stack.pop()
                if pushV[i] == popV[0]:
                    popV.pop(0)
                    i += 1
                else:
                    stack.append(pushV[i])
                    i += 1
            while popV:
                if popV[0] != stack[-1]:
                    return False
                else:
                    popV.pop(0)
                    stack.pop()
            return True
  • 相关阅读:
    OpenMP vs WinSxS
    JIT, dynarec and binary translation
    VC++2010 bug
    控制和释放共享内存块
    分配和释放信号量
    代码列表5.1 (shm.c) 尝试共享内存
    绑定和脱离
    信号量
    每个字段动态添加一个随机数
    最近做了一个红底鞋类电商网站
  • 原文地址:https://www.cnblogs.com/Lee-yl/p/9690351.html
Copyright © 2020-2023  润新知