栈和队列

Posted oldby

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了栈和队列相关的知识,希望对你有一定的参考价值。

栈:

用数组实现栈:

class ArrayStack(object):
    def __init__ (self):
        self._data = []
        
    def __len__ (self):
        return len(self._data)
    
    def is_empty(self):
        return len(self._data) == 0
    
    # O(1)
    def push(self, e):
        self._data.append(e)
        
    # O(1)
    def top(self):
        if self.is_empty( ):
            raise ValueError( Stack is empty )
        return self._data[-1]
    
    # O(1)
    def pop(self):
        if self.is_empty( ):
            raise ValueError( Stack is empty )
        return self._data.pop( )  
        
    def printstack(self):
        for i in range(len(self._data)):
            print(self._data[i], end =  )
        print()

用链表实现栈:

from LinkedList import LinkedList
from LinkedList import Node

class LinkedStack(object):
    def __init__ (self):
        self._list = LinkedList()
        
    def __len__ (self):
        return self._list.length
    
    def is_empty(self):
        return self._list.length == 0
    
    # O(1)
    def push(self, e):
        self._list.add_first(e);
        
    # O(1)
    def top(self):
        return self._list.get_first().value;
    
    # O(1)
    def pop(self):
        return self._list.remove_first().value;
        
    def printstack(self):
        self._list.printlist()

队列:

用数组实现队列:

class ArrayQueue:
    DEFAULT_CAPACITY = 10
    def __init__(self):
        self._data = [None] * ArrayQueue.DEFAULT_CAPACITY
        self._size = 0
        self._front = 0
        
    def __len__(self):
        return self._size
    
    def is_empty(self):
        return self._size == 0
    
    def first(self):
        if self.is_empty( ):
            raise ValueError( Queue is empty )
        return self._data[self._front]
    
    def dequeue(self):
        if self.is_empty( ):
            raise ValueError( Queue is empty )
        answer = self._data[self._front]
        self._data[self._front] = None
        self._front = (self._front + 1) % len(self._data)
        self._size -= 1
        return answer
    
    def enqueue(self, e):
        if self._size == len(self._data):
            self._resize(2 * len(self._data))
        pos = (self._front + self._size) % len(self._data)
        self._data[pos] = e
        self._size += 1
        
    def resize(self, cap):
        old = self._data
        self._data = [None] * cap
        walk = self._front
        for k in range(self._size):
            self._data[k] = old[walk]
            walk = (1 + walk) % len(old)
        self._front = 0
        
    def printqueue(self):
        for i in range(self._size):
            pos = (self._front + self._size - 1 - i) % len(self._data)
            #print(str(i), ": ", str(pos))
            print(self._data[pos], end = " ")  
        print()

用链表实现队列:

from LinkedList import LinkedList
from LinkedList import Node

class LinkedQueue(object):
    def __init__(self):
        self.head = None
        self.tail = None
        self.count = 0  
        
    def enqueue(self, value):
        new_node = Node(value)

        if self.tail is not None:
            self.tail.next = new_node

        else:
            self.head = new_node

        self.tail = new_node
        self.count += 1

    def dequeue(self):
        if not self.is_empty():
            # point head to next node
            tmp = self.head
            self.head = self.head.next
            print("dequeue sucess")
            self.count -= 1
            return tmp
        else:
            raise ValueError("Empty QUEUE")

    def is_empty(self):
        if self.head is None and self.tail is None:
            return True
        else:
            return False

    def peek(self):
        return self.head.data

        
    def __len__(self):
        return self.count    

    def is_empty(self):
        return self.count == 0
    
    def print(self):
        node = self.head
        while node:
            print(node.value, end = " ")
            node = node.next
        print(‘‘)    

一、用堆栈实现队列

class QueueWithTwoStacks:
    
    def __init__(self):
        self.insertStack = []
        self.popStack = []

    def enqueue(self, e):
        self.insertStack.append(e)
        return e
    
    def dequeue(self):
        if len(self.insertStack)==0 and len(self.popStack)==0:
            return None
        
        if len(self.popStack)==0:
            while len(self.insertStack)!=0:
                self.popStack.append(self.insertStack.pop())
        
        return self.popStack.pop()

二、用队列实现栈

class StackWithQueue:
    
    def __init__(self):
        self.queue = LinkedList()

    # Push element x onto stack.
    def push(self, x):
        self.queue.add_last(x)

    # Removes the element on top of the stack.
    def pop(self):
        size = self.queue.size()
        for i in range(1, size):
            self.queue.add_last(self.queue.remove_first())
        self.queue.remove_first()
        
    def top(self):
        size = self.queue.size()
        for i in range(1, size):
            self.queue.add_last(self.queue.remove_first())
        result = self.queue.remove_first()
        self.queue.add_last(result)
        return result

三、最小堆栈

题:设计一个支持push,pop,top,并在常量时间内检索最小元素的堆栈. • getMin() -- 检索堆栈中的最小元素.

import sys
from ArrayStack import ArrayStack

class MinStack(ArrayStack):
    
    def __init__(self):
        super(MinStack, self).__init__()
    
    def push(self, v):       
        newMin = min(v, self.min())
        super(MinStack, self).push(NodeWithMin(v, newMin))
    
    def min(self):
        if (super(MinStack, self).is_empty()):
            return sys.maxsize
        else:
            return super(MinStack, self).top()._min;
    

class NodeWithMin:
    def __init__(self, v, min):
        self._value = v
        self._min = min  

另:

class MinStack2(ArrayStack):
    
    def __init__(self):
        super(MinStack2, self).__init__()
        self.min_stack = ArrayStack()
        
    def push(self, value):
        if value <= self.min():
            self.min_stack.push(value)
        super(MinStack2, self).push(value)
        return value
          
    def min(self):
        if self.min_stack.is_empty():
            return sys.maxsize
        else:
            return self.min_stack.top()    
      
    def pop(self):
        value = super(MinStack2, self).pop()
        if value == self.min():
            self.min_stack.pop()
        return value

四、用一个数组实现两个堆栈

class twoStacks:
     
    def __init__(self, n): 
        self.size = n
        self.arr = [None] * n
        self.top1 = -1
        self.top2 = self.size
         
    # Method to push an element x to stack1
    def push1(self, x):
         
        # There is at least one empty space for new element
        if self.top1 < self.top2 - 1 :
            self.top1 = self.top1 + 1
            self.arr[self.top1] = x
 
        else:
            print("Stack Overflow ")
 
    # Method to push an element x to stack2
    def push2(self, x):
 
        # There is at least one empty space for new element
        if self.top1 < self.top2 - 1:
            self.top2 = self.top2 - 1
            self.arr[self.top2] = x
 
        else :
           print("Stack Overflow ")
 
    # Method to pop an element from first stack
    def pop1(self):
        if self.top1 >= 0:
            x = self.arr[self.top1]
            self.top1 = self.top1 -1
            return x
        else:
            print("Stack Underflow ")
 
    # Method to pop an element from second stack
    def pop2(self):
        if self.top2 < self.size:
            x = self.arr[self.top2]
            self.top2 = self.top2 + 1
            return x
        else:
            print("Stack Underflow ")

五、用一个数组实现三个堆栈

六、栈排序

def sortStack(s):
    r = ArrayStack()
    
    while not s.is_empty():
        tmp = s.pop()
        
        while not r.is_empty() and r.top() > tmp:
            s.push(r.pop())
            
        r.push(tmp)
    
    return r

递归*

def sortedInsert(s, x):
    if len(s) == 0 or x > s.top():
        s.push(x)
        return
    temp = s.pop()
    sortedInsert(s, x)
    s.push(temp)
    
def sortStack(s):
    if len(s) != 0:
        x = s.pop()
        sortStack(s)
        sortedInsert(s, x)

七、反转一个字符串

def reverse(s):
    lst = []
    for i in s:
        lst.append(i)
    result = []
    while len(lst) != 0:
        result.append(lst.pop())
    return ‘‘.join(result)

注:*字符串相加的处理速度很慢 如“A" + "b" ,用join函数会很快

八、有效的括号

def isValid(s):
    stack = []
    for c in s:
        if (c == ( or c == [ or c == {):
            stack.append(c)
        else:
            if len(stack)==0:
                return False
            if (   (c == ) and stack[-1] == ()
                or (c == ] and stack[-1] == [)
                or (c == } and stack[-1] == {)):
                stack.pop()
            else:
                return False
    return len(stack)==0

九、简化路径

题:? 简化路径 • 给定一个文件的绝对路径(Unix-style),简化它. • 例子, path = "/home/" => "/home" --->path = "/a/./b/../../c/" => "/c"

def simplifyPath(path):
    lst = []
    splits = path.split("/")
    
    for s in splits:
        if s == "":
            continue
        if s == ".":
            continue
            
        if s == "..":
            if len(lst) != 0:
                lst.pop()
        else:
            lst.append(s)
    
    result = []
    if len(lst) == 0:
        return "/"
    result = [/ + i for i in lst]
    return ‘‘.join(result)

 

 

十、解码字符串

题:给定一个编码字符串,返回它的解码字符串.

• 编码规则是: k[encoded_string],其中方括号内的encoded_string正好重复了k次.请注意,k保证是一个正 整数.

• 你可以假定输入字符串总是有效的; 没有多余的空格,方括号格式正确等.

• 此外,您可以假设原始数据不包含任何数字,并且这些数字仅用于那些重复数K。例如,不会有像 3A或2(4)那样的输入.

• 例子: • s = "3[a]2[bc]", return "aaabcbc". • s = "3[a2[c]]", return "accaccacc". • s = "2[abc]3[cd]ef", return "abcabccdcdcdef".

def decodeString(s):
    stack = []
    stack.append(["", 1])
    num = ""
    for ch in s:
        if ch.isdigit():
            num += ch
        elif ch == [:
            stack.append(["", int(num)])
            num = ""
        elif ch == ]:
            st, k = stack.pop()
            stack[-1][0] += st*k
        else:
            stack[-1][0] += ch
    return stack[0][0]

十一、棒球比赛

技术图片

 

 

def calPoints(ops):
    stack = []
    for op in ops:
        if op == +:
            stack.append(stack[-1] + stack[-2])
        elif op == C:
            stack.pop()
        elif op == D:
            stack.append(2 * stack[-1])
        else:
            stack.append(int(op))

    return sum(stack)

十二、行星碰撞

技术图片

 

 

def asteroidCollision(asteroids):
    ans = []
    for new in asteroids:
        while ans and new < 0 < ans[-1]:
            if ans[-1] < -new:
                ans.pop()
                continue
            elif ans[-1] == -new:
                ans.pop()
            break
        else:
            ans.append(new)
    return ans

 

以上是关于栈和队列的主要内容,如果未能解决你的问题,请参考以下文章

栈和队列基本操作

栈和队列

博客作业03--栈和队列

博客作业03--栈和队列

栈和队列知识点总结

栈和队列的面试题Java实现