牛客网_算法初级班_Lesson3_part1_数组结构实现栈_数组结构实现队列_特殊栈可以返回栈中最小值_队列结构形成栈_栈结构形成队列_python语言描述

一、实现栈结构

问题描述:用数组结构实现大小固定的栈
如:给定长度为6的数组,形成一个长度为6的栈。限制长度,如果长度超过6给用户报错

1、方法
设置一个指针index指向数组“0号”位,加入元素,index++;弹出元素,index–;

2、python实现

class ArrayStack:
    '''
    问题一:
    数组结构实现栈
    '''
    def __init__(self, initsize):
        self.initsize = initsize
        
        '''
        定义栈的结构
        '''   
        if self.initsize < 0:
            print('The init size is less than 0')
        
        self.arr = [0 for i in range(self.initsize)]
        self.index = 0
    
    #def ArrayStack(self):
 
    def peek(self):
        '''
        返回栈顶元素函数
        '''        
        if self.index == 0:
            return 0
    
        return self.arr[self.index - 1]
    
    def push(self, num):
        '''
        添加元素函数:
            可以让用户往栈中不断添加元素
        
        '''
        if self.index == self.initsize:
            print("It's wrong!")
        
        self.arr[self.index] = num
        self.index += 1
        
    def pop(self):
        
        '''
        弹出元素函数:
            允许用户将栈中的元素弹出
        
        '''
        if self.index == 0:
            print("It's wrong!")
        
        #self.arr[index] = 0    #这个可以不加,因为弹出操作其实只需要让指针变量改变位置就行,因为再添加push的时候会覆盖原先的值的
        self.index -= 1 
        return self.arr[self.index]
     
        
stacktmp = ArrayStack(3)
stacktmp.push(2)
print(stacktmp.arr) 
print(stacktmp.pop()) 

二、实现队列结构

1、问题描述
用数组结构实现大小固定的队列
方法:

  1. 三个指针变量。指针变量start用来弹出数据,用户想要弹出数据时,弹出的是start指的值;指针变量end用来添加数据,用户想要添加数据时,添加的位置是end所指向的位置;指针变量index用来判断队列中的大小,也就是队列当前的大小,它要小于等于initsize
  2. 当 size = initsize时,不可以再添加元素进入队列

2、python实现

class ArrayQueue:
    '''
    问题二:
    数组结构实现队列
    '''
    
    def __init__(self, initsize):
        self.initsize = initsize
        
        '''
        定义队列的结构
        '''   
        if self.initsize < 0:
            print('The init size is less than 0')
        
        self.arr = [0 for i in range(self.initsize)]
        self.index = 0   #判断队列所含元素个数指针变量
        self.start = 0   #弹出元素指针变量
        self.end = 0   #添加元素指针变量
     
    def peek(self):
        '''
        返回队顶元素函数
        '''        
        if self.index == 0:
            return 0
    
        return self.arr[self.start]
    
    def push(self, num):
        '''
        添加元素函数:
            可以让用户往队列中不断添加元素
        
        '''
        if self.index == self.initsize:
            print("It's wrong!")
        self.index += 1
        self.arr[self.end] = num
        self.end = 0 if (self.end == self.initsize - 1) else self.end + 1
        
    def pop(self):
        
        '''
        弹出元素函数:
            允许用户将队列中的元素弹出        
        '''
        if self.index == 0:
            print("It's wrong!")
             
        self.index -= 1 
        tmp = self.start   #因为stat的值要减一了,所以引入一个临时变量,用来储存减一前的值
        self.start = 0 if (self.start == self.initsize - 1) else self.start + 1
        
        return self.arr[tmp]
   
queuetmp = ArrayQueue(3)

queuetmp.push(2)
queuetmp.push(5)
queuetmp.push(9)

print(queuetmp.arr) 
print(queuetmp.pop())   

queuetmp.push(0)  
print(queuetmp.arr)  

三、返回栈中最小元素

1、问题描述
实现一个特殊的栈,在实现栈的基本功能的基础上,再实现返 回栈中最小元素的操作。
【要求】 1.pop、push、getMin操作的时间复杂度都是O(1)。 2.设计的栈类型可以使用现成的栈结构。

方法:
利用两个栈实现;一个叫做data栈用来存储用户添加的数据;一个叫做min栈,用来存储最小值

2、python实现

class ArrayStack:
    '''
    问题三:
    实现特殊栈,但是先要定义一个具有基本功能的栈,然后在定义一个特殊的栈
    (其中这个特殊栈的属性是普通栈的对象!!!)
    '''
    def __init__(self, initsize):
        self.initsize = initsize
        
        '''
        定义栈的结构
        '''   
        if self.initsize < 0:
            print('The init size is less than 0')
        
        self.arr = [0 for i in range(self.initsize)]
        self.index = 0
    
    #def ArrayStack(self):
    def isEmpty(self):
        '''
        判断栈是否为空
        '''
        return not self.index
    
    def peek(self):
        '''
        返回栈顶元素函数
        '''        
        if self.index == 0:
            return 0
    
        return self.arr[self.index - 1]
    
    def push(self, num):
        '''
        添加元素函数:
            可以让用户往栈中不断添加元素
        
        '''
        if self.index == self.initsize:
            print("It's wrong!")
        
        self.arr[self.index] = num
        self.index += 1
        
    def pop(self):
        
        '''
        弹出元素函数:
            允许用户将栈中的元素弹出
        
        '''
        if self.index == 0:
            print("It's wrong!")
        
        #self.arr[index] = 0    #这个可以不加,因为弹出操作其实只需要让指针变量改变位置就行,因为再添加push的时候会覆盖原先的值的
        self.index -= 1 
        return self.arr[self.index]
    
class Mystack:
    '''
    问题三:
    实现特殊的栈,返回栈中最小的元素,并且要求时间复杂度O(1)
    '''
    def __init__(self, initsize):
        self.stackData = ArrayStack(initsize)
        self.stackMin = ArrayStack(initsize)
    
    def push(self, newNum):
        '''
        添加元素函数:
            可以让用户往栈中不断添加元素
        
        '''
        
        if self.stackMin.isEmpty():  #如果min栈为空,那么必须往其中添加元素
            self.stackMin.push(newNum)
        
        if newNum >= self.stackMin.peek():
            self.stackMin.push(self.stackMin.peek())
        else:
            self.stackMin.push(newNum)
        
        self.stackData.push(newNum)

        
    def pop(self):
        
        '''
        弹出元素函数:
            允许用户将栈中的元素弹出
        
        '''
        if self.stackData.isEmpty():
            print("It's wrong!")
        self.stackMin.pop()
        
        return self.stackData.pop()
    
    def getMin(self):
        '''
        获取最小值函数:
        得到栈的最小元素
        '''
        if self.stackMin.isEmpty():
            print("It's wrong!")
            
        return self.stackMin.peek()
     
        
stacktmp = Mystack(4)  #限制长度

stacktmp.push(2)
print(stacktmp.getMin()) 
stacktmp.push(4)
print(stacktmp.getMin()) 
stacktmp.push(1)
print(stacktmp.getMin()) 
print(stacktmp.pop()) 
print(stacktmp.getMin()) 

四、通过队列结构实现栈结构

1、问题描述
如何仅用队列结构实现栈结构?
队列:先进先出;栈:先进后出

方法:
利用两个队列结构,一个data队列结构用来接收用户输入的数据,一个help队列- 存取除了队顶以外的所有元素,然后将data队列仅剩的一个队顶输出;

2、python实现

class ArrayQueue:
    '''
    问题四:
    通过队列结构实现栈,因此我们需要先定义队列结构
    '''
    
    def __init__(self, initsize):
        self.initsize = initsize
        
        '''
        定义队列的结构
        '''   
        if self.initsize < 0:
            print('The init size is less than 0')
        
        self.arr = [0 for i in range(self.initsize)]
        self.index = 0   #判断队列所含元素个数指针变量
        self.start = 0   #弹出元素指针变量
        self.end = 0   #添加元素指针变量
        
    def isEmpty(self):
        '''
        判断队列是否为空
        '''
        return not self.index
    
    def peek(self):
        '''
        返回队顶元素函数
        '''        
        if self.index == 0:
            return 0
    
        return self.arr[self.start]
    
    def push(self, num):
        '''
        添加元素函数:
            可以让用户往队列中不断添加元素
        
        '''
        if self.index == self.initsize:
            print("It's wrong!")
        self.index += 1
        self.arr[self.end] = num
        self.end = 0 if (self.end == self.initsize - 1) else self.end + 1
        
    def pop(self):
        
        '''
        弹出元素函数:
            允许用户将队列中的元素弹出        
        '''
        if self.index == 0:
            print("It's wrong!")
             
        self.index -= 1 
        tmp = self.start   #因为stat的值要减一了,所以引入一个临时变量,用来储存减一前的值
        self.start = 0 if (self.start == self.initsize - 1) else self.start + 1
        
        return self.arr[tmp]
    
    
class TwoQueueStack:
    '''
    通过两个队列实现栈结构
    其中的属性是 队列对象
    '''
    def __init__(self, initsize):
        
        self.dataQueue = ArrayQueue(initsize)
        self.helpQueue = ArrayQueue(initsize)
        
    def push(self, newNum):
        '''
        用户添加元素,只存储在data队列中
        '''
        self.dataQueue.push(newNum)
    
    def peek(self):
        '''
        返回 “栈”结构的栈顶  (其实是队列的队尾元素)
        '''
        if self.dataQueue.isEmpty():
            print("队列中没有元素!")
        
        while self.dataQueue.index > 1:
            self.helpQueue.push(self.dataQueue.pop())
            
        res = self.dataQueue.pop()
        self.helpQueue.push(res)  #这里加这句的目的是因为这个函数只是想获取“栈顶”元素,不想改变data队列,不然再获取别的元素可能会出问题,因此再把获取的添加进去,然后help、data队列互换。保证pop的时候数据不变
        self.swap()
        return res
    
    def pop(self):
        '''
        
        '''
        if self.dataQueue.isEmpty():
            print("队列中没有元素!") 
        
        while self.dataQueue.index > 1:
            self.helpQueue.push(self.dataQueue.pop())
            
        res = self.dataQueue.pop()
        self.swap()
        return res
    
    def swap(self):
        '''
        每次取出要弹出去的result以后,将help队列和data队列互换
        保证每次help队列开始时都是空队列
        '''
        self.dataQueue, self.helpQueue = self.helpQueue, self.dataQueue
        

tmpStack = TwoQueueStack(3)
tmpStack.push(3) 
tmpStack.push(4) 
tmpStack.push(5) 

print(tmpStack.peek())
print(tmpStack.pop())
print(tmpStack.pop()) 

五、栈结构实现队列

1、问题描述
如何仅用栈结构实现队列结构?

方法:
用两个栈结构实现;一个栈结构叫做push,用来接收用户的输入数据;一个栈结构叫做pop,只负责弹出用户数据;push“倒入”pop,即可实现数据顺序反过来了。

两个原则:

  1. push倒入数据进入pop时,必须一次性全部倒完
  2. 如果pop中有数据,则push不准倒入数据进pop

2、python实现

class ArrayStack:
    '''
    问题五:
    通过栈结构实现队列结构,
    因此先要定义栈结构
    '''
    def __init__(self, initsize):
        self.initsize = initsize
        
        '''
        定义栈的结构
        '''   
        if self.initsize < 0:
            print('The init size is less than 0')
        
        self.arr = [0 for i in range(self.initsize)]
        self.index = 0
    
    #def ArrayStack(self):
    def isEmpty(self):
        '''
        判断栈是否为空
        '''
        return not self.index
    
    def peek(self):
        '''
        返回栈顶元素函数
        '''        
        if self.index == 0:
            return 0
    
        return self.arr[self.index - 1]
    
    def push(self, num):
        '''
        添加元素函数:
            可以让用户往栈中不断添加元素
        
        '''
        if self.index == self.initsize:
            print("It's wrong!")
        
        self.arr[self.index] = num
        self.index += 1
        
    def pop(self):
        
        '''
        弹出元素函数:
            允许用户将栈中的元素弹出
        
        '''
        if self.index == 0:
            print("It's wrong!")
        
        #self.arr[index] = 0    #这个可以不加,因为弹出操作其实只需要让指针变量改变位置就行,因为再添加push的时候会覆盖原先的值的
        self.index -= 1 
        return self.arr[self.index]
    
    
class TwoStackQueue:
    '''
    通过两个栈结构实现队列结构
    其中的属性是 栈对象
    '''
    def __init__(self, initsize):
        
        self.pushStack = ArrayStack(initsize)
        self.popStack = ArrayStack(initsize)
    
    def push(self, newNum):
        '''
        接受用户的输入
        '''
        self.pushStack.push(newNum)
        
    def peek(self):
        '''
        获取“队顶”函数
        '''
        if self.popStack.isEmpty() and self.pushStack.isEmpty():
            print("Queue is empty!")
            
        self.pourIn()
        return self.popStack.peek()
    
    def pop(self):
        '''
        “队列”弹出操作
        '''
        
        if self.popStack.isEmpty() and self.pushStack.isEmpty():
            print("Queue is empty!")
            
        self.pourIn()
        return self.popStack.pop()
        
    def pourIn(self):
        '''
        将push栈的元素全部倒入pop栈
        '''
        
        if not self.popStack.isEmpty():
            return
            
        #while not self.pushStack.isEmpty() and self.popStack.isEmpty(): #这样写结果不对。 原因:这块是个循环,希望一直跑下去的。你多加一个and在循环肯定让他可循环次数减少了,这不像条件语句一样。因此注意
        while not self.pushStack.isEmpty():
            print(1)
            self.popStack.push(self.pushStack.pop())
      

tmpQueue = TwoStackQueue(3)
tmpQueue.push(3) 
tmpQueue.push(4) 
tmpQueue.push(5) 

print(tmpQueue.peek())
print(tmpQueue.pop())
print(tmpQueue.pop())
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值