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()
Beispiel #2
0
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__()
Beispiel #3
0
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))
Beispiel #4
0
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
Beispiel #5
0
    start_time1 = time()
    max_heap = MaxHeap()
    from random import randint

    for i in range(n):
        max_heap.add(randint(0, n))

    arr = []
    for i in range(n):
        arr.append(max_heap.extract_max())

    print('heap add: ', time() - start_time1)  # head add:  5.748132228851318

    for i in range(n - 1):
        if arr[i] < arr[i + 1]:
            raise ValueError("Error!")

    start_time2 = time()
    arr = Array()
    from random import randint

    for i in range(n):
        arr.add_last(randint(0, n))
    max_heap = MaxHeap(arr)

    print('heapify: ', time() - start_time2)  # heapify:  4.680660963058472

    arr = []
    for i in range(n):
        arr.append(max_heap.extract_max())