示例#1
0
class Queue(object):
    """
    FIFO queue based on single linked list
    All operations are O(1)
    """
    def __init__(self, data=None):
        # Use composition to hide the linked list implementation details
        self._linked_list = LinkedList() if not data else LinkedList.from_array(data)
        self._lock = Lock()

    def __iter__(self):
        yield from self._linked_list

    def __len__(self):
        with self._lock:
            return len(self._linked_list)

    def enqueue(self, value):
        with self._lock:
            self._linked_list.append(value)

    def dequeue(self):
        with self._lock:
            return self._linked_list.remove(0).value

    def peek(self):
        with self._lock:
            return self._linked_list.get(0).value

    def is_empty(self):
        with self._lock:
            return len(self._linked_list) == 0
示例#2
0
class Queue(object):
    """
    FIFO queue based on single linked list
    All operations are O(1)
    """
    def __init__(self, data=None):
        # Use composition to hide the linked list implementation details
        self._linked_list = LinkedList(
        ) if not data else LinkedList.from_array(data)
        self._lock = Lock()

    def __iter__(self):
        yield from self._linked_list

    def __len__(self):
        with self._lock:
            return len(self._linked_list)

    def enqueue(self, value):
        with self._lock:
            self._linked_list.append(value)

    def dequeue(self):
        with self._lock:
            return self._linked_list.remove(0).value

    def peek(self):
        with self._lock:
            return self._linked_list.get(0).value

    def is_empty(self):
        with self._lock:
            return len(self._linked_list) == 0
示例#3
0
    def __init__(self, data=None):
        """
        Build a binomial heap from the provided dataset
        """
        if data is None:
            data = []

        self.trees = LinkedList()
        self.trees.append(None)

        # Pointer to the minimal tree
        self.min_tree = None

        for i in data:
            self.insert(i)
示例#4
0
class Stack(object):
    """
    FILO queue based on single linked list
    All operations are O(1)
    """
    def __init__(self):
        # Use composition to hide the linked list implementation details
        self._linked_list = LinkedList()
        self._lock = Lock()

    def __len__(self):
        with self._lock:
            return len(self._linked_list)

    def __contains__(self, item):
        return item in self._linked_list

    def to_array(self):
        return list(self._linked_list)[::-1]

    def push(self, value):
        with self._lock:
            self._linked_list.prepend(value)

    def pop(self):
        with self._lock:
            return self._linked_list.remove(0).value

    def peek(self, depth=0):
        with self._lock:
            return self._linked_list.get(depth).value

    def is_empty(self):
        with self._lock:
            return len(self._linked_list) == 0

    def size(self):
        return len(self._linked_list)
示例#5
0
 def __init__(self, data=None):
     # Use composition to hide the linked list implementation details
     self._linked_list = LinkedList(
     ) if not data else LinkedList.from_array(data)
     self._lock = Lock()
示例#6
0
class BinomialHeap(object):

    def __init__(self, data=None):
        """
        Build a binomial heap from the provided dataset
        """
        if data is None:
            data = []

        self.trees = LinkedList()
        self.trees.append(None)

        # Pointer to the minimal tree
        self.min_tree = None

        for i in data:
            self.insert(i)

    def merge(self, heap: 'BinomialHeap') -> 'BinomialHeap':
        """
        Bread and butter of the binomial heap
        Merges two binomial heaps in O(log n)
        """
        # Initialize head pointers
        carry_over = None
        destination_heap = self.trees.head
        source_heap = heap.trees.head

        # Keep merging while the source heap is not empty or we have a carry over
        while source_heap or carry_over:

            # Both source and destination heap have an element of this order
            if destination_heap is not None and destination_heap.value and source_heap is not None and source_heap.value:
                new_carry_over = destination_heap.value.merge_min(source_heap.value)
                destination_heap.value = carry_over if carry_over else None
                carry_over = new_carry_over

            # Only the source heap has an element of this order
            elif source_heap is not None and source_heap.value:
                if carry_over:
                    carry_over = carry_over.merge_min(source_heap.value)
                    destination_heap.value = None
                else:
                    destination_heap.value = source_heap.value

            # Only the destination heap has an element of this order
            elif destination_heap is not None and destination_heap.value:
                if carry_over:
                    carry_over = carry_over.merge_min(destination_heap.value)
                    destination_heap.value = None

            # Only carry over
            else:
                destination_heap.value = carry_over
                carry_over = None

            # Increase the pointers and add an extra element to the linked list if needed
            source_heap = source_heap.get_next_node() if source_heap else None
            if (source_heap or carry_over) and destination_heap.get_next_node() is None:
                destination_heap.set_next_node(LinkedListNode(None))
            destination_heap = destination_heap.get_next_node() if destination_heap else None

        # Update min pointer
        self.min_tree = self.__find_min_tree()

    def insert(self, value):
        """
        Insert a value onto the heap
        Merges this heap with a new heap with only one node
        """
        # Create a heap with a single node
        new_heap = BinomialHeap()
        new_heap.trees.head.value = BinomialTreeNode(value)
        new_heap.min_tree = new_heap.trees.head
        # Merge it with the current heap
        self.merge(new_heap)

    def pop(self):
        """
        Remove and return the minimal node from the heap
        Creates a new heap from the
        """
        if self.min_tree is None or self.min_tree.value is None:
            raise IndexError()

        minimum = self.min_tree.value.value
        subtrees = self.min_tree.value.children
        self.min_tree.children = None
        self.min_tree.value = None

        heap = self.__build_heap_from_trees(subtrees)
        self.merge(heap)

        return minimum

    def peek(self):
        if self.min_tree is None:
            raise IndexError()
        return self.min_tree.value.value

    def __len__(self):
        return sum(map(lambda x: len(x) if x else 0, self.trees.to_array()))

    @staticmethod
    def __build_heap_from_trees(trees: List[Optional[BinomialTreeNode]]) -> 'BinomialHeap':
        """
        Build a new heap from an array of Binomial trees
        """
        trees.sort(key=lambda x: len(x))

        heap = BinomialHeap()
        current_node = heap.trees.head
        heap_size = 1

        for i in trees:
            index = math.log(len(i), 2)

            while heap_size <= index:
                current_node.set_next_node(LinkedListNode(None))
                current_node = current_node.get_next_node()
                heap_size += 1
            current_node.value = i

        heap.min_tree = heap.__find_min_tree()
        return heap

    def __find_min_tree(self) -> LinkedListNode:
        """
        Find the binomial subtree with the minimal element
        """
        node = self.trees.head

        current_min = None

        while node:
            if node.value and node.value.value:
                if current_min and current_min.value:
                    current_min = node if current_min.value.value > node.value.value else current_min
                else:
                    current_min = node
            node = node.get_next_node()
        return current_min
示例#7
0
 def __init__(self):
     # Use composition to hide the linked list implementation details
     self._linked_list = LinkedList()
     self._lock = Lock()
示例#8
0
 def __init__(self, data=None):
     # Use composition to hide the linked list implementation details
     self._linked_list = LinkedList() if not data else LinkedList.from_array(data)
     self._lock = Lock()