Stacks, Queues & Heaps in Python

Stacks, Queues & Heaps

© Joe James, 2019.

Stack using Python List

Stack is a LIFO data structure – last-in, first-out.
Use append() to push an item onto the stack.
Use pop() to remove an item.

my_stack = list()
my_stack.append(4)
my_stack.append(7)
my_stack.append(12)
my_stack.append(19)
print(my_stack)
[4, 7, 12, 19]
print(my_stack.pop())
print(my_stack.pop())
print(my_stack)
19
12
[4, 7]

Stack using List with a Wrapper Class

We create a Stack class and a full set of Stack methods.
But the underlying data structure is really a Python List.
For pop and peek methods we first check whether the stack is empty, to avoid exceptions.

class Stack():
    def __init__(self):
        self.stack = list()
    def push(self, item):
        self.stack.append(item)
    def pop(self):
        if len(self.stack) > 0:
            return self.stack.pop()
        else:
            return None
    def peek(self):
        if len(self.stack) > 0:
            return self.stack[len(self.stack)-1]
        else:
            return None
    def __str__(self):
        return str(self.stack)

Test Code for Stack Wrapper Class

my_stack = stack()
my_stack.push(1)
my_stack.push(3)
print(my_stack)
print(my_stack.pop())
print(my_stack.peek())
print(my_stack.pop())
print(my_stack.pop())
[1, 3]
3
1
1
None

Queue using Python Deque

Queue is a FIFO data structure – first-in, first-out.
Deque is a double-ended queue, but we can use it for our queue.
We use append() to enqueue an item, and popleft() to dequeue an item.
See Python docs for deque.

from collections import deque
my_queue = deque()
my_queue.append(5)
my_queue.append(10)
print(my_queue)
print(my_queue.popleft())
deque([5, 10])
5

Fun exercise:

Write a wrapper class for the Queue class, similar to what we did for Stack, but using Python deque.
Try adding enqueue, dequeue, and get_size methods.

Python Single-ended Queue Wrapper Class using Deque

We rename the append method to enqueue, and popleft to dequeue.
We also add peek and get_size operations.

from collections import deque
class Queue():
    def __init__(self):
        self.queue = deque()
        self.size = 0
    def enqueue(self, item):
        self.queue.append(item)
        self.size += 1
    def dequeue(self):
        if self.size > 0:
            self.size -= 1
            return self.queue.popleft()
        else: 
            return None
    def peek(self):
        if self.size > 0:
            ret_val = self.queue.popleft()
            self.queue.appendleft(ret_val)
            return ret_val
        else:
            return None
    def get_size(self):
        return self.size
    def __str__(self):
        return str(self.queue)
    
    __repr__ = __str__
test_que = Queue()
test_que.enqueue(1)
test_que.enqueue(2)
test_que.enqueue(3)
test_que.enqueue(4)
print(test_que)
test_que.dequeue()
print(test_que)
print(test_que.peek())
deque([1, 2, 3, 4])
deque([2, 3, 4])
2

Python MaxHeap

A MaxHeap always bubbles the highest value to the top, so it can be removed instantly.
Public functions: push, peek, pop
Private functions: __swap, __floatUp, __bubbleDown, str.

MaxHeap is fast!

  1. Insert in O(log n)
  2. Get Max in O(1)
  3. Remove Max in O(log n)
    在这里插入图片描述
class MaxHeap:
    def __init__(self, items=[]):
        super().__init__()
        self.heap = [0]
        for item in items:
            self.heap.append(item)
            self.__floatUp(len(self.heap) - 1)

    def push(self, data):
        self.heap.append(data)
        self.__floatUp(len(self.heap) - 1)

    def peek(self):
        if self.heap[1]:
            return self.heap[1]
        else:
            return False
            
    def pop(self):
        if len(self.heap) > 2:
            self.__swap(1, len(self.heap) - 1)
            max = self.heap.pop()
            self.__bubbleDown(1)
        elif len(self.heap) == 2:
            max = self.heap.pop()
        else: 
            max = False
        return max

    def __swap(self, i, j):
        self.heap[i], self.heap[j] = self.heap[j], self.heap[i]

    def __floatUp(self, index):
        parent = index//2
        if index <= 1:
            return
        elif self.heap[index] > self.heap[parent]:
            self.__swap(index, parent)
            self.__floatUp(parent)

    def __bubbleDown(self, index):
        left = index * 2
        right = index * 2 + 1
        largest = index
        if len(self.heap) > left and self.heap[largest] < self.heap[left]:
            largest = left
        if len(self.heap) > right and self.heap[largest] < self.heap[right]:
            largest = right
        if largest != index:
            self.__swap(index, largest)
            self.__bubbleDown(largest)
            
    def __str__(self):
        return str(self.heap)

MaxHeap Test Code

m = MaxHeap([95, 3, 21])
m.push(10)
print(m)
print(m.pop())
print(m.peek())
[0, 95, 10, 21, 3]
95
21
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值