290 likes | 407 Views
This document explores key concepts in data structures, focusing on trees, heaps, and priority queues. It covers unique identification of trees via inorder and preorder traversals, the definition and properties of partially ordered trees, and the structure of heaps as partially ordered complete binary trees. It details algorithms for heap operations like Push and Pop, highlighting their implementation through generic programming. Additionally, it introduces priority queues, their operations, and an implementation using generic adaptors. Perfect for understanding advanced data structures.
E N D
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 D B F E A C A x B x D x E x F x C 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. 4 root 3 2 1 0
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
The Push Heap Algorithm • Add new data at next leaf
The Push Heap Algorithm • Repeat • Locate parent of v[k] = v[(k – 1)/2] • if POT not satisfied • swap • else • stop
The Push Heap Algorithm • Repeat • Locate parent of v[k] = v[(k – 1)/2] • if POT not satisfied • swap • else • stop
The Push Heap Algorithm • Repeat • Locate parent of v[k] = v[(k – 1)/2] • if POT not satisfied • swap • else • stop
The Push Heap Algorithm • Repeat • Locate parent of v[k] = v[(k – 1)/2] • if POT not satisfied • swap • else • stop
The Push Heap Algorithm • Repeat • Locate parent of v[k] = v[(k – 1)/2] • if POT not satisfied • swap • else • stop
The Push Heap Algorithm • Repeat • Locate parent of v[k] = v[(k – 1)/2] • if POT not satisfied • swap • else • stop
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
The Pop Heap Algorithm • Copy last leaf to root
The Pop Heap Algorithm • Remove last leaf
The Pop Heap Algorithm • Repeat • find the larger child • if POT not satisfied • swap • else • stop
The Pop Heap Algorithm • Repeat • find the larger child • if POT not satisfied • swap • else • stop
The Pop Heap Algorithm • Repeat • find the larger child • if POT not satisfied • swap • else • stop
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(); } };