Stacks, Queues and Hierarchical Collections 2501ICT Logan
Contents Linked Data Structures Revisited Stacks Queues Trees Binary Trees Generic Trees Implementations 2
Queues and Stacks Queues and Stacks Linear Collections Can be implemented in different ways, e.g. Arrays Linked Lists Are often used in Operating Systems and run time environments Function/Method calling Stacks Process priority Queues 3
Queues FIFO collections First element enqueued is first to be dequeued Insertions occur at one end, the rear Removals occur at the other end, the front Priority Queue Extensions Reordering according to priority Few priorities: multiple Queues Many priorities: insert according to priority 4
Queues using Lists Queues using Lists Use the head and tail Pointers head NULL NULL front data rear tail Enqueue: Insert from the tail (rear) Dequeue: Remove from the head (front) 5
Priority Queues Priority Queues Implementation #1: Multiple Lists One list per priority Enqueue on the corresponding list Dequeue starting at the highest priority list Go to next lower priority if empty, etc. Does not require search operation to enqueue Requires two pointers (head/tail) per priority: Faster enqueue, but slower dequeue operation Useful if number of different priorities is small 6
Priority Queues (2) Priority Queues (2) #2: Priority Ordering Only one list Enqueue according to priority Higher priority entries overtake lower ones Dequeue always from the head Requires linear search to enqueue: O(n) Dequeue doesn t require search: O(1) Useful if number of different priorities is large 7
Queue Applications Queue Applications First-Come-First Serve Algorithms OS Process Scheduling Event Handling Modeling and Simulation of Real-World Processes E.g. checkout queue in a supermarket 8
Stacks LIFO collection The last element pushed onto the stack is the first to be retrieved Both push (insertion) and pop (deletion) operations occur at the top of the stack Implementation Arrays Singly linked lists 9
Array Implementation Array Implementation Index: i = 0; Push: stack[i++] = element; Pop: element = stack[--i]; Peek: element = stack[i-1]; Sneak preview, without changing i Watch Preconditions! 10
Stack Example Stack Example Parsing Matching Parenthesis expression = { letter } ( expression ) [ expression ] either a letter or an expression in brackets Legal examples a ab (a) (ab) [(a)] [a(b)cd] Illegal examples a) )( a( [[(]) [a)a] 11
Matching () Algorithm Matching () Algorithm For each character c in the String If c is (, [, or { Push c onto the stack Else if c is ), ], or } If the stack is empty: return false Else pop the top opening bracket and check if it matches the corresponding closing bracket Return true if the stack is empty 12
Hierarchical Collections Hierarchical Collections Tree definition Types of Trees Binary Expressions Expression Trees Tree traversals: pre-, in-, postorder Examples Generating Postfix, Parsing 13
Tree Definition Tree Definition Each node has at most one predecessor Parent D1 Many Successors Children Siblings D2 D3 Nodes sharing the same parent (eg, D2 and D3) 14
Tree Definition (2) Tree Definition (2) Topmost Node: root D1 Successors Children, Children of Children Also called descendants All nodes are successors of root D2 D4 D3 15
Tree Definition (3) Tree Definition (3) Leaf Nodes: Nodes without Successors E.g. D3 and D4 D1 Frontier: The set of all leaf nodes D2 D4 D3 16
Tree Definition (4) Tree Definition (4) Interior Nodes: Nodes with at least one successor E.g. D1 and D2 D1 Ancestors: Immediate or indirect predecessors E.g, D1 is an ancestor of D2, D3, and D4 D2 D4 D3 17
Tree Definition (5) Tree Definition (5) Levels are numbered from 0 Level 0 is always the root This tree has 3 Levels Level 0: D1 Level 1: D2 and D3 Level 2: D4 D2 D4 D1 D3 Level 0 Level 1 Level 2 18
Binary Trees Binary Trees Binary Trees allow at most two children per Node D1 Generic Trees allow any number of children per Node D2 D4 D3 19
Generic Trees Generic Trees Order of the Tree: Maximum Number of successors allowed for any given Node D1 E.g., Order: 3 D2 D5 D3 Generic Trees are sometimes called General Trees D4 20
Tree Applications Tree Applications Parsing Languages Computer Languages, Mathematical Formula Natural Languages Searchable Data Structures Databases (e.g., B-Trees) Heaps and Balanced Trees Sorting and organising Data 21
Parsers Read in Expressions E.g., (2 + 3) * 5 Check Syntactical Correctness Is everything where it should be? Create Parse Tree Evaluator checks semantic meaning and processes the data in the Tree to produce meaningful output 22
Binary Expressions Binary Expressions Stored in Binary Trees: e.g. 3+5 Numbers Leaf Nodes + Operators Interior Nodes Operands 3 5 Contained in Subtree of the Expression 23
Example Expression Example Expression 3 * 4 + 5 + * 5 3 4 24
Example Expression (2) Example Expression (2) 3 * (4 + 5) * 3 + 4 5 25
Operator Precedence Operator Precedence 3 * (4 + 5) * The higher the precedence, the lower in the tree! 3 + Overridden by parentheses! 4 5 26
Operator Precedence (2) Operator Precedence (2) 3 + 4 + 5 If operators have equal precedence, the ones on the left appear lower in the tree when parsed from left to right! + + 3 4 5 27
Evaluating an Expression Tree Evaluating an Expression Tree Begin at the root Node If a number, return it, otherwise Run the operator w/ the results of Evaluating its left and right subtrees, and Return this value. 28
Evaluating Example Evaluating Example 3 * (4 + 5) * 3 + 4 5 29
Evaluating Example (2) Evaluating Example (2) 3 * (4 + 5) * * is an operator Evaluate left and right subtrees first! 3 + 4 5 30
Evaluating Example (3) Evaluating Example (3) 3 * (4 + 5) * 3 is a number Return 3 3 + 4 5 31
Evaluating Example (4) Evaluating Example (4) 3 * (4 + 5) * + is an operator Evaluate left and right subtrees first! 3 + 4 5 32
Evaluating Example (5) Evaluating Example (5) 3 * (4 + 5) * 4 is a number Return 4 3 + 4 5 33
Evaluating Example (6) Evaluating Example (6) 3 * (4 + 5) * 5 is a number Return 5 3 + 4 5 34
Evaluating Example (7) Evaluating Example (7) 3 * (4 + 5) * Add subtree results Return 4 + 5 = 9 3 + 9 4 5 35
Evaluating Example (8) Evaluating Example (8) 3 * (4 + 5) * 27 Multiply subtree results 3 + 9 Return 3 * 9 = 27 4 5 36
Evaluate Pseudocode Evaluate Pseudocode evaluate(node) { if node is a number return number; else { left = evaluate(node.left); right = evaluate(node.right); return compute(node, left, right); } } 37
Binary Tree Traversals Binary Tree Traversals Preorder Visit node, then go left, then go right Inorder Go left, then visit node then go right Postorder: Depth First Go left, then go right, then visit node Breadth First Level 0, then Level 1, then Level 2, etc. 38
Binary Tree Traversals (2) Binary Tree Traversals (2) Preorder, Inorder, and Postorder Correspond with Prefix, Infix, and Postfix Notations of an Expression Infix: 3 + 5 Prefix = Polish Notation (PN) : +(3,5) Postfix = Reverse Polish Notation (RPN) : 3 5 + Use the Same Generic Recursive Algorithm! 39
Prefix Pseudocode Prefix Pseudocode String prefix(node) { if (node == NULL) return ; else return node + prefix(node.left) + prefix (node.right); } 40
Infix Pseudocode Infix Pseudocode String infix(node) { if (node == NULL) return ; else return infix(node.left) + node + infix (node.right); } 41
Postfix Pseudocode Postfix Pseudocode String postfix(node) { if (node == NULL) return ; else return postfix(node.left) + postfix (node.right) + node; } 42
A Binary Tree Structure A Binary Tree Structure struct BTNode { protected: BTNode *left; // left child BTNode *right; // right child Element_Type value; // the actual data // here go the usual access methods: // 43
A Binary Tree Constructor A Binary Tree Constructor BTNode ( Element_Type E = 0, BTNode *L=NULL, BTNode *R=NULL) : value (E), left ( L), right (R) {} }; 44
Creating a Binary Tree Creating a Binary Tree BTNode *test_left= new BTNode ( 3, NULL,NULL); OR BTNode *test_left= new BTNode ( 3 ); 3 nil nil 45
Creating a Binary Tree Creating a Binary Tree BTNode *test_left= new BTNode ( 3 ); BTNode *test_right= new BTNode ( 5 ); 3 5 nil nil 46
Creating a Binary Tree Creating a Binary Tree BTNode *test_left= new BTNode ( 3 ); BTNode *test_right= new BTNode ( 5 ); BTNode *test_root= new BTNode ( +,test_left,test_right); + 3 5 47
Creating a Binary Tree Creating a Binary Tree BTNode *test_left= new BTNode ( 3 ); BTNode *test_right= new BTNode ( 5 ); BTNode *test_root= new BTNode ( +,test_left,test_right); Infix: 3 + 5 Postfix: 3 5 + P fi +(3 5) 3 + 5 48
Grammar Parsing Grammar Parsing Recursive Definition, e.g Infix: Expression = Term { + - Term } Term = Factor { * / Factor } Factor = number ( Expression ) Represents standard math formulas, e.g. 3 + 4 * ( 5 - ( 6 / 7 ) ) Can be used to create a parse tree! 49
Recursive Descent Parsing Recursive Descent Parsing Expression = Term { + - Term } Term = Factor { * / Factor } Factor = number ( Expression ) Expression() { Term(); while (token == '+' token == '-') { get_token(); Term(); } } 50
Recursive Descent Parsing Recursive Descent Parsing Expression = Term { + - Term } Term = Factor { * / Factor } Factor = number ( Expression ) Term() { Factor(); while (token == '*' token == '/') { get_token(); Factor(); } } 51
Recursive Descent Parsing Recursive Descent Parsing Expression = Term { + - Term } Term = Factor { * / Factor } Factor = number ( Expression ) Factor() { switch (token) { case number: get_token(); break; case '(': get_token(); Expression(); if (token!= ')') error( No closing ')'"); get_token(); break; } } default: error(error '%s'\n", token); 52
References Lambert, K. A., & Osborne, M. (2004): A Framework for Program Design and Data Structures: Brooks/Cole. Chapters 8-10 http://en.wikipedia.org/wiki/tree_data_structure http://en.wikipedia.org/wiki/binary_tree http://en.wikipedia.org/wiki/recursive_descent_parser http://mathworld.wolfram.com/weightedtree.html 53
Appendix C Language Examples
A Binary Tree Structure (C) A Binary Tree Structure (C) typedef struct BinTreeNode btnode; struct BinTreeNode { btnode *left; /* left child */ btnode *right; /* right child */ void *value; /* the actual data */ }; 55
A Binary Tree Constructor (C) A Binary Tree Constructor (C) btnode *newbtnode(void *data, btnode *left, btnode *right) { btnode *this = malloc(sizeof btnode); this->value = data; this->left = left; this->right = right; } return this; 56
Creating a Binary Tree (C) Creating a Binary Tree (C) btnode *left = newbtnode( 3, NULL, NULL); 3 NULL NULL 57
Creating a Binary Tree (C) Creating a Binary Tree (C) btnode *left = newbtnode( 3, NULL, NULL); btnode *right = newbtnode( 5, NULL, NULL); 3 5 NULL NULL 58
Creating a Binary Tree (C) Creating a Binary Tree (C) btnode *left = newbtnode( 3, NULL, NULL); btnode *right = newbtnode( 5, NULL, NULL); btnode *root = newbtnode( +, left, right); + 3 5 59
Creating a Binary Tree (C) Creating a Binary Tree (C) btnode *left = newbtnode( 3, NULL, NULL); btnode *right = newbtnode( 5, NULL, NULL); btnode *root = newbtnode( +, left, right); Infix: 3 + 5 + Postfix: 3 5 + Prefix: +(3, 5) add(3, 5) 3 Functional Notation 5 60
Appendix Objective-C Language Examples
A Binary Tree Structure A Binary Tree Structure @interface BTNode: NSObject; { BTNode *left; // left child BTNode *right; // right child id value; // the actual data } // here go the usual access methods: // -setleft, -setright, @end 62
A Binary Tree Constructor A Binary Tree Constructor - initwithvalue: v left: (BTNode *) l right: (BTNode *) r { if (!(self = [self init])) return nil; value = v; left = l; right = r; } return self; 63
Creating a Binary Tree Creating a Binary Tree BTNode *left = [[BTNode alloc] initwithvalue: @ 3 left: nil right: nil]; 3 nil nil 64
Creating a Binary Tree Creating a Binary Tree BTNode *left = [[BTNode alloc] initwithvalue: @ 3 left: nil right: nil]; BTNode *right = [[BTNode alloc] initwithvalue: @ 5 left: nil right: nil]; 3 5 nil nil 65
Creating a Binary Tree Creating a Binary Tree BTNode *left = [[BTNode alloc] initwithvalue: @ 3 left: nil right: nil]; BTNode *right = [[BTNode alloc] initwithvalue: @ 5 left: nil right: nil]; BTNode *root = [[BTNode alloc] initwithvalue: @ + + left: left right: right]; 3 5 66
Creating a Binary Tree Creating a Binary Tree BTNode *left = [[BTNode alloc] initwithvalue: @ 3 left: nil right: nil]; BTNode *right = [[BTNode alloc] initwithvalue: @ 5 left: nil right: nil]; BTNode *root = [[BTNode alloc] initwithvalue: @ + + left: left right: right]; Infix: 3 + 5 Postfix: 3 5 + Prefix: +(3, 5) add(3, 5) Functional notation 3 5 67