Python 算法(三、3) 队列和栈

一、固定数组实现队列和栈

class ArrayStack:
    def __init__(self, arr):
        self.arr = arr
        self.size = 0

    def peek(self):
        if self.arr == 0:
            return None
        return self.arr[self.size]

    def push(self, obj):
        if self.size == len(self.arr):
            print('The stack is full')
        self.arr[self.size] = obj
        self.size += 1

    def pop(self):
        if self.size == 0:
            print('The stack is empty')
        self.size -= 1
        res = self.arr[self.size]
        return res

print('array stack')
a = ArrayStack([0, 0, 0])
a.push(2)
a.push(3)
print(a.pop())
print(a.peek())
# 利用first、last、size相互制约
class ArrayQueue:
    def __init__(self,arr):
        self.arr = arr
        self.size = 0
        self.first = 0
        self.last = 0

    def peek(self):
        if self.size == 0:
            return None
        return self.arr[self.first]

    def push(self, obj):
        if self.size == len(self.arr):
            print('The queue is full')
        self.size += 1
        self.arr[self.last] = obj
        self.last = 0 if self.last == len(self.arr)-1 else self.last+1

    def poll(self):
        if self.size == 0:
            print('The queue is empty')
        self.size -= 1
        res = self.arr[self.first]
        self.first = 0 if self.first == len(self.arr)-1 else self.first+1
        return res
print('array queue')
b = ArrayQueue([0,0,0])
b.push(3)
b.push(4)
b.push(6)
print(b.poll())
print(b.peek())

二、栈中获取最小元素

实现一个特殊的栈,在实现栈的基本功能的基础上,再实现返
回栈中最小元素的操作。要求时间复杂度O(1)

思路:准备两个栈,一个栈专门放最小的数。

from queue import LifoQueue

class GetMinStack:
    def __init__(self):
        self.stack_data = LifoQueue()
        self.stack_min = LifoQueue()

    def push(self, obj):
        if self.stack_min.empty():
            self.stack_min.put(obj)
        elif obj <= self.get_min():
            self.stack_min.put(obj)
        self.stack_data.put(obj)

    def pop(self):
        if self.stack_data.empty():
            print('stack is empty')
        res = self.stack_data.get()
        if res == self.get_min():
            self.stack_min.get()
        return res

    def get_min(self):
        if self.stack_min.empty():
            print('Your stack is empty')
        return self.stack_min.queue[-1]

stack1 = GetMinStack()
stack1.push(3)
print(stack1.get_min())
stack1.push(4)
print(stack1.get_min())
stack1.push(1)
print(stack1.get_min())
print(stack1.pop())
print(stack1.get_min())

三、队列结构实现栈结构,栈实现队列结构

思路:

  • 用两个队列实现栈结构,例如1,2,3入队列,这时候将1,2先弹出到另一个队列,返回3,就实现了栈结构
from queue import Queue

class Queue2Stack:
    def __init__(self):
        self.queue = Queue()
        self.help = Queue()

    def push(self, push_num):
        self.queue.put(push_num)

    def peek(self):
        if self.queue.empty():
            print('stack is empty')
        while self.queue.maxsize != 1:
            self.help.put(self.queue.get())
        res = self.queue.get()
        self.help.put(res)
        self.queue, self.help = self.help, self.queue
        return res

    def pop(self):
        if self.queue.empty():
            print('stack is empty')
        while self.queue.maxsize != 1:
            self.help.put(self.queue.get())
        res = self.queue.get()
        self.queue, self.help = self.help, self.queue
        return res

stack1 = Queue2Stack()
stack1.push(3)
stack1.push(4)
stack1.push(5)
print(stack1.pop())
print(stack1.peek())


  • 用两个栈实现队列结构,将push栈全部倒入pop栈,保证全部倒完;pop栈有数据时不能倒。
from queue import LifoQueue

class Stack2Queue:
    def __init__(self):
        self.stack_push = LifoQueue()
        self.stack_pop = LifoQueue()

    def push(self, obj):
        self.stack_push.put(obj)

    def poll(self):
        if self.stack_pop.empty() and self.stack_push.empty():
            print('Queue is empty')
        elif self.stack_pop.empty():
            while not self.stack_push.empty():
                self.stack_pop.put(self.stack_push.get())
        return self.stack_pop.get()

    def peek(self):
        if self.stack_pop.empty() and self.stack_push.empty():
            print('Queue is empty')
        elif self.stack_pop.empty():
            while not self.stack_push.empty():
                self.stack_pop.put(self.stack_push.get())
        res = self.stack_pop.get()
        self.stack_pop.put(res)
        return res

queue1 = Stack2Queue()
queue1.push(3)
queue1.push(4)
queue1.push(5)
print(queue1.poll())
print(queue1.peek())

四、猫狗队列

用户可以调用add方法将cat类或dog类的
实例放入队列中; 用户可以调用pollAll方法,将队列中所有的实例按照进队列
的先后顺序依次弹出; 用户可以调用pollDog方法,将队列中dog类的实例按照
进队列的先后顺序依次弹出; 用户可以调用pollCat方法,将队列中cat类的实
例按照进队列的先后顺序依次弹出; 用户可以调用isEmpty方法,检查队列中是
否还有dog或cat的实例; 用户可以调用isDogEmpty方法,检查队列中是否有dog
类的实例; 用户可以调用isCatEmpty方法,检查队列中是否有cat类的实例。

思路:两个队列,并添加时间戳属性,解决pollAll方法中顺序问题

from queue import Queue

class Pet:
    def __init__(self, type):
        self.type = type

    def get_pet_type(self):
        return self.type

class Dog(Pet):
    def __init__(self, name='dog'):
        super().__init__(name)

class Cat(Pet):
    def __init__(self, name='cat'):
        super().__init__(name)

class PetEnterQueue:
    def __init__(self, type, count):
        self.pet = type
        self.count = count

    def get_pet(self):
        return self.pet

    def get_count(self):
        return self.count

    def get_enter_pet_type(self):
        return self.pet.get_pet_type()

class DogCatQueue:
    def __init__(self):
        self.dogQ = Queue()
        self.catQ = Queue()
        self.count = 0

    def add(self, pet):
        if 'dog' in pet.get_pet_type():
            self.dogQ.put(PetEnterQueue(pet, self.count))
            self.count += 1
        elif 'cat' in pet.get_pet_type():
            self.catQ.put(PetEnterQueue(pet, self.count))
            self.count += 1
        else:
            print('err, not dog or cat')

    def poll_all(self):
        if not self.dogQ.empty() and not self.catQ.empty():
            if self.dogQ.queue[0].get_count() < self.catQ.queue[0].get_count():
                return self.dogQ.get().get_pet()
            else:
                return self.catQ.get().get_pet()
        elif not self.dogQ.empty():
            return self.dogQ.get().get_pet()
        elif not self.catQ.empty():
            return self.catQ.get().get_pet()
        else:
            print('err, queue is empty')

    def poll_dog(self):
        if not self.dogQ.empty():
            return self.dogQ.get().get_pet()
        else:
            print('err, Dog queue is empty')

    def poll_cat(self):
        if not self.catQ.empty():
            return self.catQ.get().get_pet()
        else:
            print('err, Cat queue is empty')

    def is_empty(self):
        return self.dogQ.empty() and self.catQ.empty()

    def is_dog_queue_empty(self):
        return self.dogQ.empty()

    def is_cat_queue_empty(self):
        return self.catQ.empty()

def main():
    test = DogCatQueue()
    dog1 = Dog('dog1')
    dog2 = Dog('dog2')
    dog3 = Dog('dog3')
    cat1 = Cat('cat1')
    cat2 = Cat('cat2')
    cat3 = Cat('cat3')

    test.add(dog1)
    test.add(cat1)
    test.add(dog2)
    test.add(cat2)
    test.add(dog3)
    test.add(cat3)

    while not test.is_empty():
        print(test.poll_all().get_pet_type())

    # while not test.is_dog_queue_empty():
    # print(test.poll_dog().get_pet_type())
    #
    # while not test.is_cat_queue_empty():
    # print(test.poll_cat().get_pet_type())
main()
点赞