class ArrayStack(Stack): def __init__(self, capacity: int = 10): self.__data = Array(capacity) def peek(self): return self.__data.get_last() def push(self, ele): self.__data.add_to_last(ele) def get_size(self): return self.__data.get_size() def pop(self): return self.__data.remove_last() def is_empty(self): return self.__data.is_empty() def __str__(self): bstr = 'ArrayStack size: %d, capacity: %d\n' % ( self.__data.get_size(), self.__data.get_capacity()) bstr += '[' for i in range(self.__data.get_size()): bstr += '' + str(self.__data.get(i)) if i != self.__data.get_size() - 1: bstr += ', ' bstr += '] top' return bstr
class ArrayQueue(Queue): def __init__(self, capacity: int = 10): self.__data = Array(capacity) def get_size(self): return self.__data.get_size() def enqueue(self, ele): self.__data.add_to_last(ele) def is_empty(self): return self.__data.is_empty() def dequeue(self): return self.__data.remove_first() def get_front(self): return self.__data.get_first() def get_capacity(self): return self.__data.get_capacity() def __str__(self): bstr = 'ArrayQueue size: %d, capacity: %d\n' % (self.__data.get_size(), self.__data.get_capacity()) bstr += 'front [' for i in range(self.__data.get_size()): bstr += '' + str(self.__data.get(i)) if i != self.__data.get_size() - 1: bstr += ', ' bstr += '] tail' return bstr
class ArrayStack(StackBase): """使用自定义的Array实现""" def __init__(self, capacity=0): self._array = Array(capacity=capacity) def get_size(self): return self._array.get_size() def is_empty(self): return self._array.is_empty() def get_capacity(self): return self._array.get_capacity() def __str__(self): return str('<chapter_05_Stack_Queue.stack.ArrayStack> : {}'.format( self._array)) def __repr__(self): return self.__str__() def push(self, e): self._array.add_last(e) def pop(self): return self._array.remove_last() def peek(self): return self._array.get_last()
class ArrayQueue(QueueBase): def __init__(self, capacity=0): self._array = Array(capacity) def get_size(self): return self._array.get_size() def is_empty(self): return self._array.is_empty() def get_capacity(self): return self.get_capacity() def enqueue(self, e): self._array.add_last(e) def dequeue(self): return self._array.remove_first() def get_front(self): return self._array.get_first() def __str__(self): return str('<chapter_05_Stack_Queue.queue.ArrayQueue> : {}'.format( self._array)) def __repr__(self): return self.__str__()
class Stack(IStack): def __init__(self, capacity: int = 10): self.array = Array(capacity) def get_size(self) -> int: return self.array.get_size() def is_empty(self) -> bool: return self.array.is_arr_empty() def pop(self) -> Any: return self.array.remove_last_element() def push(self, element: Any): return self.array.add_last_element(element) def peek(self) -> Any: return self.array.get_last_element()
class Queue(IQueue): def __init__(self, capacity: int = 10): self.array = Array(capacity) def get_size(self) -> int: return self.array.get_size() def is_empty(self) -> bool: return self.array.is_arr_empty() def dequeue(self) -> Any: return self.array.remove_first_element() def enqueue(self, element: Any): self.array.add_last_element(element) def get_front(self) -> Any: return self.array.get_first_element()
class MaxHeap(object): def __init__(self, arr=None): if arr is None: self.__data = Array() elif isinstance(arr, int): self.__data = Array(arr) else: # 如果 arr 不为空,使用 heapify 操作将 arr 整理成堆 self.__data = Array(arr) i = (self.get_size() - 2) // 2 while i >= 0: self.__sift_down(i) i -= 1 # 堆大小 def get_size(self): return self.__data.get_size() # 堆是否为空 def is_empty(self): return self.__data.is_empty() # 起始索引为0的完全二叉树下,返回给定索引的父结点索引 def get_parent(self, index: int): if index == 0: raise IndexError('index-0 has no parent') return (index - 1) // 2 # 起始索引为0的完全二叉树下,返回给定索引的左孩子索引 def get_left_child(self, index: int): return 2 * index + 1 # 起始索引为0的完全二叉树下,返回给定索引的右孩子索引 def get_right_child(self, index: int): return 2 * index + 2 # 向堆内添加新元素 e def add(self, e): self.__data.add_to_last(e) self.__sift_up(self.__data.get_size() - 1) # 上浮操作 def __sift_up(self, index: int): while index > 0 and self.__data.get(self.get_parent(index)) < self.__data.get(index): self.__data.swap(index, self.get_parent(index)) index = self.get_parent(index) # 获取堆内最大元素 def get_max(self): if self.get_size() == 0: raise IndexError('heap is empty') return self.__data.get(0) # 获取并从堆内删除最大元素 def extract_max(self): ret = self.get_max() self.__data.set(0, ret) self.__data.remove_last() self.__sift_down(0) return ret # 下沉操作 def __sift_down(self, index: int): while self.get_left_child(index) < self.get_size(): j = self.get_left_child(index) if j + 1 < self.get_size() and self.__data.get(j + 1) > self.__data.get(j): j += 1 if self.__data.get(index) > self.__data.get(j): break else: self.__data.swap(index, j) index = j # 取出堆内元素最大值,并替换为新值 def replace(self, ele): ret = self.get_max() self.__data.set(0, ele) self.__sift_down(0) return ret
class IndexHeap: def __init__(self, capacity): # data 表示为元素的数组 self._data = Array(capacity=capacity) # index[i] 数组表示为对堆中第i的位置上的元素 self._index = Array(capacity=capacity) # reversed[i] 为i的在索引堆位置是index逆运算 self._reversed = Array(capacity=capacity) for i in range(capacity): self._reversed.add(i, -1) self.capacity = capacity self.count = 0 def getSize(self): return self.count def getCapacity(self): return self.capacity def isEmpty(self): return self.count == 0 def add(self, i, ele): self._data.add(i, ele) self._index.add_last(i) self._reversed.set(i, self.count) self.count += 1 self._shiftUp(self._data.get_size() - 1) def extractMin(self): if self.count < 0: raise ValueError("capacity should be >0") ele = self._data.get(self._index.get_first()) self._index.set(0, self._index.get_last()) self.count -= 1 if self.count != 0: self._index.remove_last() self._shiftDown(0) return ele def leftChid(self, index): return 2 * index + 1 def rightChild(self, index): return 2 * index + 2 def _shiftDown(self, index): if index < 0: raise ValueError("index should be postive") cur = self._data.get(self._index.get(index)) cur_index = self._index.get(index) while self.leftChid(index) < self._index.get_size(): max_index = self.leftChid(index) if self.rightChild(index) < self._index.get_size( ) and self._data.get(self._index.get( self.rightChild(index))) < self._data.get( self._index.get(self.leftChid(index))): max_index = self.rightChild(index) if self._data.get(self._index.get(max_index)) < cur: self._index._data[max_index], self._index._data[ index] = self._index._data[index], self._index._data[ max_index] self._reversed.set(self._index.get(max_index), max_index) self._reversed.set(self._index.get(index), index) index = max_index else: break def _shiftUp(self, index): if index < 0: raise ValueError("index should be postive") cur = self._data.get(self._index.get(index)) cur_index = self._index.get(index) while (index - 1) // 2 >= 0: parent = (index - 1) // 2 if self._data.get(self._index.get(parent)) > cur: self._index._data[parent], self._index._data[ index] = self._index._data[index], self._index._data[ parent] self._reversed.set(self._index.get(index), index) self._reversed.set(self._index.get(parent), parent) index = (index - 1) // 2 else: break def extractMinIndex(self): if self.count < 0: raise ValueError("capacity should be >0") ele = self._index.get(0) self._index.set(0, self._index.get_last()) self._reversed.set(self._index.get(0), 0) # self._reversed.set(self._index.get_last(), -1) self.count -= 1 if self.count != 0: self._reversed.set(self._index.get_last(), -1) self._index.remove_last() self._shiftDown(0) return ele def contains(self, index): return self._reversed.get(index) != -1 def getItem(self, index): assert self.contains(index) return self._data.get(index) def change(self, i, item): assert self.contains(i) j = self._reversed.get(i) if self._data.get(i) > item: self._data.set(i, item) self._shiftUp(j) else: self._data.set(i, item) self._shiftDown(j) # 找到index中的i的位置 index[j] == i # 之后shiftUp(j),shiftDown(j) # o(n) # for j, w in enumerate(self._index): # if w == i: # self._shiftDown(j) # self._shiftUp(j) # return def __str__(self): return str( ' heap_value: {}, heap_index:{},heap_reversed:{},capacity: {},size:{}' .format(self._data, self._index, self._reversed, self.capacity, self.count))
class MaxHeap: def __init__(self, arr=None, capacity=None): if isinstance(arr, Array): self._data = arr for i in range(self._parent(arr.get_size() - 1), -1, -1): self._sift_down(i) return if not capacity: self._data = Array() else: self._data = Array(capacity=capacity) def size(self): return self._data.get_size() def is_empty(self): return self._data.is_empty() # 返回完全二叉树数组表示中,一个索引所表示的元素的父亲节点的索引 i // 2 def _parent(self, index): if index == 0: raise ValueError('index-0 doesn\'t have parent.') return (index - 1) // 2 # 返回完全二叉树数组表示中,一个索引所表示的元素的左孩子节点的索引 2 * i + 1 def _left_child(self, index): return index * 2 + 1 # 返回完全二叉树数组表示中,一个索引所表示的元素的右孩子节点的索引 2 * i + 2 def _right_child(self, index): return index * 2 + 2 def add(self, e): self._data.add_last(e) self._sift_up(self._data.get_size() - 1) def _sift_up(self, index): cur = self._data.get(index) while index > 0 and self._data.get(self._parent(index)) < cur: self._data.set(index, self._data.get(self._parent(index))) index = self._parent(index) self._data.set(index, cur) def find_max(self): if self._data.get_size() == 0: raise ValueError('Can not find_max when heap is empty.') return self._data.get(0) def extract_max(self): ret = self.find_max() self._data.swap(0, self._data.get_size() - 1) self._data.remove_last() self._sift_down(0) return ret def _sift_down(self, index): while self._left_child(index) < self.size(): right = self._right_child(index) left = self._left_child(index) max = self._data.get(left) max_index = left if right < self.size() and max < self._data.get(right): right_chid = self._data.get(right) max = right_chid max_index = right if max > self._data.get(index): self._data.swap(max_index, index) index = max_index else: break def replace(self, e): ret = self.find_max() # 这样可以一次logn完成 self._data.set(0, e) self._sift_down(0) return ret