Beispiel #1
0
 def test_add_one_item(self):
     linked_list = DoublyLinkedList()
     linked_list.add(1)
     self.assertEqual(linked_list.head.value, 1)
     self.assertEqual(linked_list.head.previous, None)
     self.assertEqual(linked_list.tail.value, 1)
     self.assertEqual(linked_list.tail.previous, None)
Beispiel #2
0
 def test_remove_item_not_in_list(self):
     linked_list = DoublyLinkedList()
     linked_list.add(2)
     linked_list.add(4)
     linked_list.add(25)
     linked_list.add(20)
     linked_list.add(12)
     self.assertEqual(linked_list.remove(0), False)
     self.assertEqual(linked_list.walk(), [2, 4, 25, 20, 12])
Beispiel #3
0
 def test_remove_from_tail(self):
     linked_list = DoublyLinkedList()
     linked_list.add(2)
     linked_list.add(4)
     linked_list.add(25)
     linked_list.add(20)
     linked_list.add(12)
     self.assertEqual(linked_list.remove(12), True)
     self.assertEqual(linked_list.tail.next, None)
     self.assertEqual(linked_list.walk(), [2, 4, 25, 20])
Beispiel #4
0
 def test_remove_from_middle(self):
     linked_list = DoublyLinkedList()
     linked_list.add(2)
     linked_list.add(4)
     linked_list.add(25)
     linked_list.add(20)
     linked_list.add(12)
     self.assertEqual(linked_list.remove(25), True)
     self.assertEqual(linked_list.head.next.next.previous.value, 4)
     self.assertEqual(linked_list.walk(), [2, 4, 20, 12])
Beispiel #5
0
 def test_remove_from_head(self):
     linked_list = DoublyLinkedList()
     linked_list.add(2)
     linked_list.add(4)
     linked_list.add(25)
     linked_list.add(20)
     linked_list.add(12)
     self.assertEqual(linked_list.remove(2), True)
     self.assertEqual(linked_list.head.previous, None)
     self.assertEqual(linked_list.walk(), [4, 25, 20, 12])
Beispiel #6
0
 def test_walk_reverse(self):
     linked_list = DoublyLinkedList()
     linked_list.add(2)
     linked_list.add(4)
     linked_list.add(25)
     linked_list.add(20)
     linked_list.add(12)
     self.assertEqual(linked_list.walk_reverse(), [12, 20, 25, 4, 2])
Beispiel #7
0
 def test_walk(self):
     linked_list = DoublyLinkedList()
     linked_list.add(2)
     linked_list.add(4)
     linked_list.add(25)
     linked_list.add(20)
     linked_list.add(12)
     self.assertEqual(linked_list.walk(), [2, 4, 25, 20, 12])
Beispiel #8
0
 def test_search_item_at_tail(self):
     linked_list = DoublyLinkedList()
     linked_list.add(2)
     linked_list.add(4)
     linked_list.add(25)
     linked_list.add(20)
     linked_list.add(12)
     self.assertEqual(linked_list.search(12), True)
Beispiel #9
0
 def test_search_item_not_in_list(self):
     linked_list = DoublyLinkedList()
     linked_list.add(2)
     linked_list.add(4)
     linked_list.add(25)
     linked_list.add(52)
     linked_list.add(20)
     linked_list.add(12)
     self.assertEqual(linked_list.search(0), False)
Beispiel #10
0
class LRUCache:
    def __init__(self, limit=10):
        self.limit = limit
        self.length = 0
        self.storage = DoublyLinkedList()

    """
    Retrieves the value associated with the given key. Also
    needs to move the key-value pair to the end of the order
    such that the pair is considered most-recently used.
    Returns the value associated with the key or None if the
    key-value pair doesn't exist in the cache.
    """

    def get(self, key):
        current = self.storage.head
        while current is not None:
            if current.value[0] == key:
                self.storage.move_to_front(current)
                return current.value[1]
            current = current.next
        return None

    """
    Adds the given key-value pair to the cache. The newly-
    added pair should be considered the most-recently used
    entry in the cache. If the cache is already at max capacity
    before this entry is added, then the oldest entry in the
    cache needs to be removed to make room. Additionally, in the
    case that the key already exists in the cache, we simply
    want to overwrite the old value associated with the key with
    the newly-specified value.
    """

    def set(self, key, value):
        current = self.storage.head
        replaced = False
        while current is not None and replaced is not True:
            if current.value[0] == key:
                current.value[1] = value
                self.storage.move_to_front(current)
                replaced = True
            current = current.next

        if self.length == self.limit and replaced is not True:
            self.storage.remove_from_tail()
            self.storage.add_to_head([key, value])
        elif replaced is not True:
            self.storage.add_to_head([key, value])
            self.length = self.storage.length
Beispiel #11
0
class Queue:
    def __init__(self):
        self.size = 0
        # Why is our DLL a good choice to store our elements?
        # self.storage = ?
        self.storage = DoublyLinkedList()

    def enqueue(self, value):
        self.storage.add_to_tail(value)
        self.size += 1

    def dequeue(self):
        if self.size > 0:
            self.size -= 1
            return self.storage.remove_from_head()
        else:
            return None

    def len(self):
        return self.size
Beispiel #12
0
class Stack:
    def __init__(self):
        self.size = 0
        # Why is our DLL a good choice to store our elements?
        # self.storage = ?
        self.storage = DoublyLinkedList()

    def push(self, value):
        self.size += 1
        self.storage.add_to_head(value)

    def pop(self):
        if self.len() > 0:
            self.size -= 1
            return self.storage.remove_from_head()
        else:
            return None

    def len(self):
        return len(self.storage)
Beispiel #13
0
class Queue:
    def __init__(self):
        self.size = 0
        # what data structure should we
        # use to store queue elements?
        self.storage = DoublyLinkedList()

    def enqueue(self, item):
        self.storage.add_to_tail(item)
        self.size += 1

    def dequeue(self):
        item = self.storage.remove_from_head()
        if item:
            self.size -= 1
            return item
        else:
            return None

    def len(self):
        return self.size
Beispiel #14
0
class Queue:
    def __init__(self):
        self.size = 0
        # Why is our DLL a good choice to store our elements?
        # self.storage = ?
        self.dll = DoublyLinkedList()

    def enqueue(self, value):
        self.dll.add_to_head(value)
        self.size += 1

    def dequeue(self):
        if self.size == 0:
            pass
        else:
            self.size -= 1
            value = self.dll.remove_from_tail()
            return value

    def len(self):
        return self.size
Beispiel #15
0
 def test_prepend(self):
     linked_list = DoublyLinkedList()
     linked_list.add(1)
     linked_list.prepend(20)
     self.assertEqual(linked_list.head.value, 20)
     self.assertEqual(linked_list.tail.value, 1)
     self.assertEqual(linked_list.tail.previous, linked_list.head)
Beispiel #16
0
class Stack:
    def __init__(self):
        self.size = 0
        # Why is our DLL a good choice to store our elements?
        # self.storage = ?
        self.dll = DoublyLinkedList()

    def push(self, value):
        self.size += 1
        self.dll.add_to_tail(value)

    def pop(self):
        if self.size == 0:
            return
        else:
            self.size -= 1

            value = self.dll.remove_from_tail()
            return value

    def len(self):
        return self.size
Beispiel #17
0
 def test_add_two_items(self):
     linked_list = DoublyLinkedList()
     linked_list.add(1)
     linked_list.add(22)
     self.assertEqual(linked_list.head.next.value, 22)
     self.assertEqual(linked_list.head.next, linked_list.tail)
     self.assertEqual(linked_list.head.previous, None)
     self.assertEqual(linked_list.tail.previous, linked_list.head)
class LRUCache:
    def __init__(self, limit=10):
        self.limit = limit
        self.entries = {}
        self.cache = DoublyLinkedList()

    """
    Retrieves the value associated with the given key. Also
    needs to move the key-value pair to the top of the order
    such that the pair is considered most-recently used.
    Returns the value associated with the key or None if the
    key-value pair doesn't exist in the cache. 
    """

    def get(self, key):
        try:
            node, value = self.entries[key]
            self.cache.move_to_front(node)
            return value
        except KeyError:
            return None

    """
    Adds the given key-value pair to the cache. The newly-
    added pair should be considered the most-recently used
    entry in the cache. If the cache is already at max capacity
    before this entry is added, then the oldest entry in the
    cache needs to be removed to make room. Additionally, in the
    case that the key already exists in the cache, we simply 
    want to overwrite the old value associated with the key with
    the newly-specified value. 
    """

    def set(self, key, value):
        try:
            self.entries[key][1] = value
            self.cache.move_to_front(self.entries[key][0])
        except KeyError:
            if len(self.entries) == self.limit:
                key_to_remove = self.cache.remove_from_tail()
                self.entries.pop(key_to_remove)

            node = self.cache.add_to_head(key)
            self.entries[key] = [node, value]

    """
    Method added for testing purposes. Prints all the elements 
    in the cache in their current order.
    """

    def print_cache(self):
        cache = []
        pointer = self.cache.head
        while pointer:
            cache.append(pointer.value)
            pointer = pointer.next
        print(cache)
Beispiel #19
0
 def __init__(self, init=None):
     self.contents = DoublyLinkedList()
     # check if an init string is provided
     # if so, put the contents of the init string in self.contents
     if init:
         pass
Beispiel #20
0
 def __init__(self, limit=10):
     self.limit = limit
     self.length = 0
     self.storage = DoublyLinkedList()
Beispiel #21
0
from doubly_linked_list.doubly_linked_list import DoublyLinkedList

linked_list = DoublyLinkedList()
linked_list.add(2)
linked_list.add(4)
linked_list.add(25)
linked_list.add(20)
linked_list.add(12)
print(linked_list.walk())

linked_list.remove(20)
print(linked_list.walk())
print(linked_list.head.next.value, linked_list.tail.previous.value)
Beispiel #22
0
 def test_walk_list_empty(self):
     linked_list = DoublyLinkedList()
     self.assertEqual(linked_list.walk(), [])
 def __init__(self, limit=10):
     self.limit = limit
     self.entries = {}
     self.cache = DoublyLinkedList()
Beispiel #24
0
 def __init__(self):
     self.size = 0
     # Why is our DLL a good choice to store our elements?
     # self.storage = ?
     self.dll = DoublyLinkedList()
Beispiel #25
0
 def test_empty_list(self):
     linked_list = DoublyLinkedList()
     self.assertEqual(linked_list.head, None)
     self.assertEqual(linked_list.tail, None)
Beispiel #26
0
 def __init__(self):
     self.size = 0
     # what data structure should we
     # use to store queue elements?
     self.storage = DoublyLinkedList()
Beispiel #27
0
class LRUCache:
    """
    Our LRUCache class keeps track of the max number of nodes it
    can hold, the current number of nodes it is holding, a doubly-
    linked list that holds the key-value entries in the correct
    order, as well as a storage dict that provides fast access
    to every node stored in the cache.
    """
    def __init__(self, limit=10):
        self.limit = limit
        self.length = 0
        self.order_list = DoublyLinkedList()
        self.storage = {}

    def __len__(self):
        return self.length

    """ returns true if the key exists in this cache, false otherwise """

    def has_key(self, key):
        return key in self.storage

    """
    Retrieves the value associated with the given key. Also
    needs to move the key-value pair to the end of the order
    such that the pair is considered most-recently used.
    Returns the value associated with the key or None if the
    key-value pair doesn't exist in the cache.
    """

    def get(self, key):
        # check if the key exists
        if not self.has_key(key) or self.length == 0:
            return None

        # find the node with this key
        node = self.order_list.find_node(key)

        # move that node to the end of the used-order list
        self.order_list.move_to_end(node)

        # return the value
        return self.storage[key]

    """
    Adds the given key-value pair to the cache. The newly-
    added pair should be considered the most-recently used
    entry in the cache. If the cache is already at max capacity
    before this entry is added, then the oldest entry in the
    cache needs to be removed to make room. Additionally, in the
    case that the key already exists in the cache, we simply
    want to overwrite the old value associated with the key with
    the newly-specified value.
    """

    def set(self, key, value):
        if self.has_key(key):
            # overwriting an existing entry
            self.storage[key] = value

            # find existing node and move it to end
            node = self.order_list.find_node(key)
            self.order_list.move_to_end(node)
        else:
            # creating a new entry
            self.storage[key] = value

            # add new node to the end of the list
            self.order_list.add_to_tail(key)

            # if we are at the size limit, remove the oldest item
            if self.length == self.limit:
                # remove the oldest used entry from both the
                # order list and storage dict
                old_key = self.order_list.remove_from_head()
                del self.storage[old_key]
            else:
                # not at the limit, just added the new item
                self.length += 1