Ejemplo n.º 1
0
class FavoritesList(PositionalList):
    '''List of elements ordered from most frequently accessed to least.'''

    class _Item:
        __slots__ = '_value', '_count' # For memory usage
        def __init__(self, e):
                self._value = e # The user's element
                self._count = 0 # Access count
            
    def _find_position(self, e):
        '''Search for element and return its Pisition (or None if not found).'''
        walk = self._data.first()
        while walk is not None and walk.element()._value != e:
            walk = self._data.after(walk)
        return walk

    def _move_up(self, pos):
        '''Move item at Position pos earlier in the list based on access count.'''
        if pos != self._data.first(): # Consider moving
            cnt = pos.element()._count
            walk = self._data.before(pos)
            if cnt > walk.element()._count: # Must shift forward
                while (walk != self._data.first() and cnt > self._data.before(walk).element()._count):
                    walk = self._data.before(walk)
                self._data.add_before(walk, self._data.delete(pos)) # Delete / reinsert

    def __init__(self):
        self._data = PositionalList() # Will be list of _Item instances

    def __len__(self):
        return len(self._data)

    def is_empty(self):
        return len(self._data) == 0

    def access(self, e): 
        '''Access element e, thereby increasing its access count.'''
        pos = self._find_position(e) # Try to locate existing element
        if pos is None:
            pos = self._data.add_last(self._Item(e)) # Place at end if new
        p.element()._count += 1
        self._move_up(pos) # Consider moving forward.

    def remove(self, e):
        '''Remove element e from the list of favorites.'''
        pos = self._find_position(e) # Try to locate element
        if pos is not None:
            self._data.delete(pos) # Delete if found

    def top(self, k):
        '''Generate sequence of top k elements in terms of access count.'''
        if not 1 <= k <= len(self):
            raise ValueError('Illegal value for k')
        walk = self._data.first()
        for j in range(k):
            item = walk.element() # Element of list is _Item
            yield item._value # Report user's element
            walk = self._data.after(walk)
class SortedPriorityQueue(PriorityQueueBase):  # Base class defines _Item
    '''A min-oriented priority queue implemented with a sorted list.'''
    def __init__(self):
        '''Create a new empty Priority Queue.'''
        self._data = PositionalList()

    def __len__(self):
        '''Return the number of items in the priority queue.'''
        return len(self._data)

    def add(self, key, value):
        '''Add a key-value pair.'''
        newest = self._Item(key, value)  # Make new item instance
        walk = self._data.last()  # Walk backward looking for smaller key
        while walk is not None and newest < walk.element():
            walk = self._data.before(walk)
        if walk is None:
            self._data.add_first(newest)  # New key is smallest
        else:
            self._data.add_after(walk, newest)  # Newest goes after walk

    def min(self):
        '''Return but do not remove (k,v) tuple with minimum key.'''
        if self.is_empty():
            raise ValueError('Priority queue is empty.')
        p = self._data.first()
        item = p.element()
        return (item._key, item._value)

    def remove_min(self):
        '''Remove and return (k,v) tuple with minimum key.'''
        if self.is_empty():
            raise ValueError('Priority queue is empty.')
        item = self._data.delete(self._data.first())
        return (item._key, item._value)
    def top(self, k):  # Override top because list is no longer sorted.
        '''Generate sequence of top k elements in terms of access counts.'''
        if not 1 <= k <= len(self):
            raise ValueError('Illegal value for k')

        temp = PositionalList()
        for item in self._data:  # Positional lists support iteration.
            temp.add_last(item)

        for j in range(
                k
        ):  # We repeatedly find, report, and remove element with largest count.
            highPos = temp.first()  # Find and report next highest from temp.
            walk = temp.after(highPos)
            while walk is not None:
                if walk.element()._count > highPos.element()._count:
                    highPos = walk
                walk = temp.after(walk)
            yield highPos.element()._value  # Report element to user
            temp.delete(highPos)  # Remove from temp list.
class UnsortedPriorityQueue(PriorityQueueBase):  # Base class defines _Item
    '''A min-oriented priority queue implemented with an unsorted list.'''
    def __init__(self):
        '''Create a new empty Priority Queue.'''
        self._data = PositionalList()

    def _find_min(self):  # nonpublic utility
        '''Return Position of item with minimum key.'''
        if self.is_empty():  # is_empty inherited from base class
            raise ValueError('Priority queue is empty')
        small = self._data.first()
        walk = self._data.after(small)
        while walk is not None:
            if walk.element() < small.element():
                small = walk
            walk = self._data.after(walk)
        return small

    def __len__(self):
        '''Return the number of items in the priority queue.'''
        return len(self._data)

    def add(self, key, value):
        '''Add a key-value pair.'''
        self._data.add_last(self._Item(key, value))

    def min(self):
        '''Return but do not remove (k,v) tuple with minimum key.'''
        p = self._find_min()
        item = p.element()
        return (item._key, item._value)

    def remove_min(self):
        '''Remove and return (k,v) tuple with minumum key.'''
        p = self._find_min()
        item = self._data.delete(p)
        return (item._key, item._value)
 def __init__(self):
     '''Create a new empty Priority Queue.'''
     self._data = PositionalList()
Ejemplo n.º 6
0
 def __init__(self):
     self._data = PositionalList() # Will be list of _Item instances