annotate ch3ex5.py @ 20:0326803882ad

Finally completing Ch. 3, exercise 5: write a TreeMap that uses a red-black tree.
author Brian Neal <bgneal@gmail.com>
date Thu, 27 Dec 2012 15:30:49 -0600
parents
children
rev   line source
bgneal@20 1 """Chapter 3, exercise 5.
bgneal@20 2
bgneal@20 3 "A drawback of hashtables is that the elements have to be hashable, which usually
bgneal@20 4 means they have to be immutable. That's why, in Python, you can use tuples but
bgneal@20 5 not lists as keys in a dictionary. An alternative is to use a tree-based map.
bgneal@20 6 Write an implementation of the map interface called TreeMap that uses
bgneal@20 7 a red-black tree to perform add and get in log time."
bgneal@20 8
bgneal@20 9
bgneal@20 10 """
bgneal@20 11 import redblacktree
bgneal@20 12
bgneal@20 13
bgneal@20 14 class TreeMap(object):
bgneal@20 15 """A tree-based map class."""
bgneal@20 16
bgneal@20 17 def __init__(self):
bgneal@20 18 self.tree = redblacktree.Tree()
bgneal@20 19
bgneal@20 20 def get(self, k):
bgneal@20 21 """Looks up the key (k) and returns the corresponding value, or raises
bgneal@20 22 a KeyError if the key is not found.
bgneal@20 23
bgneal@20 24 """
bgneal@20 25 return self.tree.find(k)
bgneal@20 26
bgneal@20 27 def add(self, k, v):
bgneal@20 28 """Adds the key/value pair (k, v) to the tree. If the key already
bgneal@20 29 exists, the value is updated to the new value v.
bgneal@20 30
bgneal@20 31 Returns True if the pair was inserted, and False if the key already
bgneal@20 32 existed and the tree was updated.
bgneal@20 33
bgneal@20 34 """
bgneal@20 35 node, inserted = self.tree.insert(k, v)
bgneal@20 36 if not inserted:
bgneal@20 37 node.value = v
bgneal@20 38 return inserted
bgneal@20 39
bgneal@20 40 def remove(self, k):
bgneal@20 41 """Removes the mapping with the given key (k).
bgneal@20 42 Raises a KeyError if the mapping was not found.
bgneal@20 43
bgneal@20 44 """
bgneal@20 45 result = self.tree.remove(k)
bgneal@20 46 if not result:
bgneal@20 47 raise KeyError
bgneal@20 48
bgneal@20 49 def __len__(self):
bgneal@20 50 """Returns the number of mappings in the map."""
bgneal@20 51 return len(self.tree)
bgneal@20 52
bgneal@20 53
bgneal@20 54 def main(script):
bgneal@20 55 import string
bgneal@20 56 m = TreeMap()
bgneal@20 57 s = string.ascii_lowercase
bgneal@20 58
bgneal@20 59 for k, v in enumerate(s):
bgneal@20 60 m.add([k], v)
bgneal@20 61
bgneal@20 62 for k in range(len(s)):
bgneal@20 63 key = [k]
bgneal@20 64 print key, m.get(key)
bgneal@20 65 m.remove(key)
bgneal@20 66
bgneal@20 67 assert len(m) == 0
bgneal@20 68
bgneal@20 69 if __name__ == '__main__':
bgneal@20 70 import sys
bgneal@20 71 main(*sys.argv)