Trees 1: Theory, Models, Generic Heap Algorithms, Priority Queues Andy Wang Data Structures, Algorithms, and Generic Programming Review Question Given the following information, can I uniquely identify a tree? Nodes listed based on an inorder traversal: D, B, F, E, A, C Nodes listed based on a preorder traversal: A, B, D, E, F, C Review Question D B F E A C A B D E F C Review Question A B D E F C D B F E A C x x x x x x Partially Ordered Trees Definition: A partially ordered tree is a tree T such that: There is an order relation >= defined for the vertices of T For any vertex p and any child c of p, p >= c Partially Ordered Trees Consequences: The largest element in a partially ordered tree (POT) is the root No conclusion can be drawn about the order of children Heaps Definition: A heap is a partially ordered complete (almost) binary tree. The tree is completely filled on all levels except possibly the lowest. root 3 1 0 4 2 Heaps Consequences: The largest element in a heap is the root A heap can be stored using the vector implementation of binary tree Heap algorithms: Push Heap Pop Heap The Push Heap Algorithm Add new data at next leaf Repair upward Repeat Locate parent if POT not satisfied swap else stop Until POT The Push Heap Algorithm Add new data at next leaf 0 1 2 3 4 5 6 0 l r ll lr rl rr 7 6 5 4 3 The Push Heap Algorithm Add new data at next leaf 0 1 2 3 4 5 6 0 l r ll lr rl rr 7 6 5 4 3 8 The Push Heap Algorithm Repeat Locate parent of v[k] = v[(k – 1)/2] if POT not satisfied swap else stop 0 1 2 3 4 5 6 0 l r ll lr rl rr 7 6 5 4 3 8 The Push Heap Algorithm Repeat Locate parent of v[k] = v[(k – 1)/2] if POT not satisfied swap else stop 0 1 2 3 4 5 6 0 l r ll lr rl rr 7 6 5 4 3 8 The Push Heap Algorithm Repeat Locate parent of v[k] = v[(k – 1)/2] if POT not satisfied swap else stop 0 1 2 3 4 5 6 0 l r ll lr rl rr 7 6 8 4 3 5 The Push Heap Algorithm Repeat Locate parent of v[k] = v[(k – 1)/2] if POT not satisfied swap else stop 0 1 2 3 4 5 6 0 l r ll lr rl rr 7 6 8 4 3 5 The Push Heap Algorithm Repeat Locate parent of v[k] = v[(k – 1)/2] if POT not satisfied swap else stop 0 1 2 3 4 5 6 0 l r ll lr rl rr 7 6 8 4 3 5 The Push Heap Algorithm Repeat Locate parent of v[k] = v[(k – 1)/2] if POT not satisfied swap else stop 0 1 2 3 4 5 6 0 l r ll lr rl rr 8 6 7 4 3 5 The Pop Heap Algorithm Copy last leaf to root Remove last leaf Repeat find the larger child if POT not satisfied swap else stop Until POT The Pop Heap Algorithm Copy last leaf to root 0 1 2 3 4 5 6 0 l r ll lr rl rr 8 6 7 4 3 5 The Pop Heap Algorithm Copy last leaf to root 0 1 2 3 4 5 6 0 l r ll lr rl rr 5 6 7 4 3 5 The Pop Heap Algorithm Remove last leaf 0 1 2 3 4 5 6 0 l r ll lr rl rr 5 6 7 4 3 The Pop Heap Algorithm Repeat find the larger child if POT not satisfied swap else stop 0 1 2 3 4 5 6 0 l r ll lr rl rr 5 6 7 4 3 The Pop Heap Algorithm Repeat find the larger child if POT not satisfied swap else stop 0 1 2 3 4 5 6 0 l r ll lr rl rr 5 6 7 4 3 The Pop Heap Algorithm Repeat find the larger child if POT not satisfied swap else stop 0 1 2 3 4 5 6 0 l r ll lr rl rr 7 6 5 4 3 Generic Heap Algorithms Apply to ranges Specified by random access iterators Current support Arrays TVector<T> TDeque<T> Source code file: gheap.h Test code file: fgss.cpp Priority Queues Element type with priority typename T t Predicate class P p Associative queue operations void Push(t) void Pop() T& Front() Priority Queues Associative property Priority value determined by p Push(t) inserts t, increases size by 1 Pop() removes element with highest priority value, decreases size by 1 Front() returns element with highest priority value, no state change The Priority Queue Generic Adaptor template <typename T, class C, class P> class CPriorityQueue { C c; P LessThan; public: typedef typename C::value_type value_type; int Empty() const { return c.Empty(); } unsigned int Size() const { return c.Size(); } void Clear() { c.Clear(); } CPriorityQueue& operator=(const CPriorityQueue& q) { if (this != &q) { c = q.c; LessThan = q.LessThan; } return *this; } The Priority Queue Generic Adaptor void Display(ostream& os, char ofc = ‘\0’) const { c.Display(os, ofc); } void Push(const value_type& t) { c.PushBack(t); g_push_heap(c.Begin(), c.End(), LessThan); } void Pop() { if (Empty()) { cerr << “error” << endl; exit(EXIT_FALIURE); } g_pop_heap(c.Begin(), c.End(), LessThan); c.PopBack(); } };