Chapter 11: Tables and Priority Queues TABLE ADT TABLE IMPLEMENTATIONS PRIORITY QUEUE ADT HEAPS HEAP APPLICATIONS CS 240 222 Table Abstract Data Type The concept of a table (or dictionary) abstract data type is intended to facilitate looking up complex records by using one of the data fields as a special search key. Language Developer Runtime Codesize Memory Codetime C AT&T 3 239 18 8 C++ AT&T 53 233 7 12 Java Sun 44 235 45 10 Perl open 16 76 18 3 Python CWI 25 80 16 3 Rexx IBM 623 111 15 6 Tcl Sun 40 98 28 4 For example, the table of programming languages above could be searched by the name of the language, the amount of memory required for a certain test program, the name of the developer, or any of its other fields. CS 240 223 Table: Array Implementing the table as an array has Implementation Language: C Runtime: 3 Memory: 1 Developer: AT&T Codesize: 239 Codetime: 8 several advantages: Language: C++ Runtime: 53 Memory: 7 Developer : AT&T Codesize : 233 Codetime : 12 Language: Java Runtime: 44 Memory: 45 Developer : Sun Codesize : 235 Codetime : 10 Language: Perl Runtime: 16 Memory: 18 Developer : open Codesize : 76 Codetime : 3 Insertion is efficient if the list is unsorted – just insert at the end of the list. If the list is kept sorted by the search key, then a binary search is made possible. An array implementation also has several disadvantages: × Memory must be allocated in advance, so some might be wasted or an adequate amount might not be reserved. × Deletion from the list requires inefficient gap-filling steps. CS 240 Language: Python Developer : CWI Runtime: 25 Codesize : 80 Memory: 16Rexx Codetime Language: Developer::3IBM Runtime: 623 Memory: 15 Codesize : 111 Codetime : 6 Language: Tcl Runtime: 40 Memory: 28 Developer : Sun Codesize : 98 Codetime : 4 224 Table: Linked List Implementation Lang: C Dev: AT&T RnTm: 3 CdSz: 239 Mem: 1 CdTm: 8 Lang: C++ Dev: AT&T RnTm: 53 CdSz: 233 Mem: 7 CdTm : 12 Lang: Java Dev: Sun RnTm: 44 CdSz: 235 Mem: 45 CdTm: 10 Lang: Perl Dev: open RnTm: 16 CdSz: 76 Mem: 18 CdTm: 3 Implementing the table as an linked list has several advantages: The dynamic allocation of memory ensures that the nodes being used are necessary and sufficient. Insertion is efficient if the list is unsorted – just insert at the head of the list. Deletion is efficient – just relink around the node being deleted. CS 240 Lang: Python Dev: CWI RnTm: 25 CdSz: 80 Mem: 16 CdTm: 3 Lang: Rexx Dev: IBM RnTm: 623 CdSz: 111 Mem: 15 CdTm: 6 Lang: Tcl Dev: Sun RnTm: 40 CdSz: 98 Mem: 28 CdTm: 4 A linked list implementation of the table also has several disadvantages: × Sorting the list and retrieving from the sorted list are difficult tasks (unless we use a skip list!). × There is extra overhead in maintaining the pointer fields of each node. 225 Table: Binary Search Tree Implementation Language: Perl Developer: open Runtime: 16 Codesize: 76 Memory: 18 Codetime: 3 Implementing the table as a binary search tree has several advantages: The dynamic allocation of memory ensures that the nodes being used are necessary and sufficient. If the search key of the table needs to be sorted, then searching, removing, and inserting can all have O(logn) time complexity (if the tree is kept balanced!). Language: C++ Developer: AT&T Runtime: 53 Codesize: 233 Memory: 7 Codetime: 12 Language: C Developer: AT&T Runtime: 3 Codesize: 239 Memory: 1 Codetime: 8 A binary search tree implementation of the table also has several ×disadvantages: Ensuring that the binary tree is balanced Language: Java Developer: Sun Runtime: 44 Codesize: 235 Memory: 45 Codetime: 10 Language: Rexx Developer: IBM Runtime: 623 Codesize: 111 Memory: 15 Codetime: 6 Language: Python Developer: CWI Runtime: 25 Codesize: 80 Memory: 16 Codetime: 3 Language: Tcl Developer: Sun Runtime: 40 Codesize: 98 Memory: 28 Codetime: 4 is difficult (unless we use an AVL, 2-3, or red-black tree – see Carrano’s × Chapter12). There is extra overhead in maintaining the pointer fields of each node. CS 240 226 Priority Queue Abstract Data Type Often, a FIFO queue structure has a need for a prioritization capability, so elements with greater priority are removed before lower-priority elements that were actually inserted first. Examples: • Short print jobs may be prioritized over longer print jobs on a printer queue. • Real-time network applications (e.g., video, audio) may be prioritized over email and simple file transfers on a network switch’s forwarding queue. • System maintenance tasks (e.g., memory defragmentation, mouse interrupts) may be prioritized over application software tasks on an operating system’s job queue. CS 240 227 Heap Implementation of Priority Queue 10 A min-heap is a complete binary tree in which every node’s value is less than or equal to all of its offsprings’ values. 17 13 25 45 31 61 58 15 47 30 23 Note: One convenient aspect of the heap is that it can be stored in an array. 1 0 1 7 1 3 2 5 3 1 1 5 3 0 4 5 6 1 5 8 4 7 2 3 • Offspring of node i: nodes 2i+1 and 2i+2 • Parent of node i: node (i-1)/2 CS 240 228 Inserting Into A Heap When inserting a new element into a heap, start at the new leaf node that would maintain the binary tree’s completeness, and “percolate” the new element up to its appropriate position to maintain the heap order property. 10 10 Insert 12 17 13 25 45 15 31 61 47 58 30 45 17 25 CS 240 13 12 31 61 58 47 23 61 47 58 23 30 12 10 17 25 45 15 31 Percolate Up 30 15 13 25 23 10 Percolate Up 45 17 12 13 31 61 58 47 23 30 15 229 Removing From A Heap When deleting the minimum element from a heap, create a “hole” node at the root (where the minimum element was), and slide the smaller of the hole’s offspring up until an appropriate slot is found for the last heap element. 29 43 65 75 51 63 58 87 Delete Min 91 80 77 73 75 75 CS 240 63 58 87 80 91 73 87 77 91 80 77 73 43 58 65 75 63 58 Percolate Down 51 65 51 65 43 Percolate Down 43 51 63 73 87 80 77 91 230 Heap Application: Discrete Event Simulation Rather than implementing a complicated (expensive) system, it is sometimes possible to simulate the system using a statistical model, and to work out the obvious bugs prior to actual implementation. A heap conveniently structures such simulations. The nodes represent the discrete “events” of the system, ordered according to the time at which they “occur”. PC1A PC1B Network PC1C Simulation PC1G TOKEN Example RING #1 PC1F PC1D ATM SWITCH #1 PC2A PC2B ATM SWITCH #2 PC2C PC2G TOKEN RING #2 PC2D FIBER BACKBONE PC2F PC2E PC1E CS 240 231 Network Simulation Example (continued) 045: PC1B xmits on TR1 053: ATMS1 xmits on FB 072: PC1B xmits on TR1 049: ATMS2 recvs on TR2 068: PC2F xmits on TR2 080: PC1D xmits on TR1 059: PC2B recvs on TR2 049: ATMS2 recvs on TR2 Delete Minimum 053: ATMS1 xmits on FB 072: PC1B xmits on TR1 059: PC2B recvs on TR2 068: PC2F xmits on TR2 080: PC1D xmits on TR1 047: ATMS1 recvs on TR1 Process Event 053: ATMS1 xmits on FB 072: PC1B xmits on TR1 049: ATMS2 recvs on TR2 068: PC2F xmits on TR2 080: PC1D xmits on TR1 059: PC2B recvs on TR2 049: ATMS2 recvs on TR2 Delete Minimum 053: ATMS1 xmits on FB 072: PC1B xmits on TR1 059: PC2B recvs on TR2 068: PC2F xmits on TR2 080: PC1D xmits on TR1 049: ATMS2 recvs on TR2 Process Event 053: ATMS1 xmits on FB 072: PC1B xmits on TR1 CS 240 068: PC2F xmits on TR2 Delete Minimum... 050: ATMS1 xmits on FB 080: PC1D xmits on TR1 059: PC2B recvs on TR2 232 Application: Heap Sort Take advantage of the max-heap property to sort an unordered list of values! // Percolate node i’s contents down // the size-n max-heap as needed. template <class Etype> void percDown(Etype A[], int i, int n) { int childIndex; Etype temp = A[i]; for ( ; 2*i <= n; i = childIndex) { childIndex = ((2*i != n) && (A[2*i+1] > A[2*i])) ? (2*i+1) : (2*i); if (temp < A[childIndex]) A[i] = A[childIndex]; else break; } A[i] = temp; } CS 240 // Sort the size-n list (indexed // 1 through n) by converting it // into a max-heap swapping the // largest elements to put them // in their proper positions, and // then percolating as needed. template <class Etype> void heapSort(Etype A[], int n) { Etype temp; // Set list up as a max-heap for (int j = n/2; j > 0; j--) percDown(A, j, n); for (int i = n; i >= 2; i--) { // Swap the first element // with the i-th element and // percolate! temp = A[1]; A[1] = A[i]; A[i] = temp; percDown(A, 1, i-1); } } 233 Heap Sort Example Original List: Frodo Samwise Gandalf Sauron Merry Pippin Aragorn Legolas Gollum Gimli Boromir Saruman Arwen After Converting Into Max-Heap: Sauron Samwise Saruman Legolas Merry Pippin Aragorn Frodo Gollum Gimli Boromir Gandalf Arwen Rest Of Heap Sort: Saruman Samwise Pippin Legolas Merry Gandalf Aragorn Frodo Gollum Gimli Boromir Arwen Sauron Samwise Merry Pippin Legolas Gimli Gandalf Aragorn Frodo Gollum Arwen Boromir Saruman Sauron Pippin Merry Gandalf Legolas Gimli Boromir Aragorn Frodo Gollum Arwen Samwise Saruman Sauron Merry Legolas Gandalf Gollum Gimli Boromir Aragorn Frodo Arwen Pippin Samwise Saruman SauronGandalf Frodo Gimli Boromir Aragorn Arwen Merry Pippin Samwise Legolas Gollum Saruman Sauron Gollum Gimli Gandalf Frodo Arwen Boromir Aragorn Legolas Merry Pippin Samwise Saruman Sauron Gimli Frodo Gandalf Aragorn Arwen Boromir Gollum Legolas Merry Pippin Samwise Saruman Sauron Gandalf Frodo Boromir Aragorn Arwen Gimli Gollum Legolas Merry Pippin Samwise Saruman Sauron Frodo Arwen Boromir Aragorn Gandalf Gimli Gollum Legolas Merry Pippin Samwise Saruman Sauron Boromir Arwen Aragorn Frodo Gandalf Gimli Gollum Legolas Merry Pippin Samwise Saruman Sauron Arwen Aragorn Boromir Frodo Gandalf Gimli Gollum Legolas Merry Pippin Samwise Saruman Sauron Aragorn Arwen Boromir Frodo Gandalf Gimli Gollum Legolas Merry Pippin Samwise Saruman Sauron CS 240 234 Heap Sort Time template <class Etype> Complexity void percDown(Etype A[], int i, int n) { int childIndex; 1 array access, 1 assignment: 4 time units Etype temp = A[i]; for ( ; 2*i <= n; i = childIndex) { childIndex = ((2*i != n) && (A[2*i+1] > A[2*i])) ? (2*i+1) : (2*i); if (temp < A[childIndex]) A[i] = A[childIndex]; else break; } A[i] = temp; 1 array access (including the assignment): 3 time units At most log(n-i) iterations; 3 time units each: 1 assignment, 1 multiplication, 1 comparison 2 array accesses (3 time units each), 5 multiplications, 2 additions, 2 comparisons, 1 boolean operation, 1 assignment: At most 17 time units 3 array accesses, 1 comparison: At most 10 time units Total time units for percDown: At most 7 + 30log(n-i) } CS 240 235 Heap Sort Time Complexity (continued) template <class Etype> void heapSort(Etype A[], int n) { (n / 2) iterations; 2 time units each: 1 division or subtraction, 1 comparison (+ 1 assignment in the first iteration) Etype temp; for (int j = n/2; j > 0; j--) percDown(A, j, n); At most 7 + 30log(n-j) time units for (int i = n; i >= 2; i--) { temp = A[1]; A[1] = A[i]; 13 time units: 4 array accesses, 1 additional assignment (n - 1) iterations; 2 time units each: 1 comparison, 1 subtraction or assignment A[i] = temp; percDown(A, 1, i-1); } } CS 240 At most 7 + 30log(i-2) time units Total time units for heapSort: At most 1+j=1,n/2(2+7+30log(nj))+i=2,n(2+13+7+30log(i-2)) = 1 + j=1,n/2(9) + 30j=1,n/2log(n-j)) + i=2,n(22) + 30i=2,nlog(i-2)) = 1 + 9(n/2) + 30j=1,n/2log(n-j)) + 22(n-1) + 30i=2,nlog(i-2)) 1 + 4.5n + 30(n/2)logn + 22n -22 +30nlogn = 236