Binary Search Trees Information Retrieval Overview Binary Search
Binary Search Trees (Information Retrieval)
Overview • Binary Search Trees. • Hash Tables. 2
Recall - Binary Search Tree A Binary Tree such that: • Every node entry has a unique key. • All the keys in the left subtree of a node are less than the key of the node. • All the keys in the right subtree of a node are greater than the key of the node. 3
Example 1: key is an integer 43 31 64 20 40 28 33 56 47 89 59 4
Example 2: key is a string Fred Dan Alan Bill Mary Eve Eric Kate Greg Sue Len 5
Binary Tree Node entry link to left child node link to right child node 6
Binary Search Tree Node Example 1: struct Tree. Node. Rec { int key; struct Tree. Node. Rec* left. Ptr; right. Ptr; }; typedef struct Tree. Node. Rec Tree. Node; 7
Binary Search Tree Node Example 2: #define MAXLEN 15 struct Tree. Node. Rec { char key[MAXLEN]; struct Tree. Node. Rec* left. Ptr; right. Ptr; }; typedef struct Tree. Node. Rec Tree. Node; 8
Recall: #define MAXLEN 15 struct Tree. Node. Rec { char key[MAXLEN]; struct Tree. Node. Rec* maximum string length is fixed left. Ptr; right. Ptr; }; typedef struct Tree. Node. Rec Tree. Node; 9
Example 3: struct Tree. Node. Rec { char* key; struct Tree. Node. Rec* left. Ptr; right. Ptr; }; typedef struct Tree. Node. Rec Tree. Node; 10
Recall: • Allows strings of arbitrary length. • Memory needs to be allocated dynamically before use. struct Tree. Node. Rec { char* key; • Use strcmp to compare strings. struct Tree. Node. Rec* left; right; }; typedef struct Tree. Node. Rec Tree. Node; 11
12
Book Record struct Book. Rec { char* author; char* title; char* publisher; key /* etc. : other book information. */ }; typedef struct Book. Rec Book; 13
Example 4: Binary Search Tree Node struct Tree. Node. Rec { Book info; struct Tree. Node. Rec* left. Ptr; right. Ptr; }; typedef struct Tree. Node. Rec Tree. Node; 14
Tree Node struct Tree. Node. Rec { float key; struct Tree. Node. Rec* left. Ptr; right. Ptr; }; typedef struct Tree. Node. Rec Tree. Node; 15
#ifndef TREEH #define TREEH struct Tree. Node. Rec { float struct Tree. Node. Rec* }; key; left. Ptr; right. Ptr; typedef struct Tree. Node. Rec Tree. Node; Tree. Node* make. Tree. Node(float value); Tree. Node* insert(Tree. Node* node. Ptr, float item); Tree. Node* search(Tree. Node* node. Ptr, float item); void print. Inorder(const Tree. Node* node. Ptr); void print. Preorder(const Tree. Node* node. Ptr); void print. Postorder(const Tree. Node* node. Ptr); #endif 16
Make. Node • parameter: item to be inserted • steps: – allocate memory for the new node – check if memory allocation is successful – if so, put item into the new node – set left and right branches to NULL • returns: pointer to (i. e. address of) new node 17
Tree. Node* make. Tree. Node(float value) { Tree. Node* new. Node. Ptr = NULL; new. Node. Ptr = (Tree. Node*)malloc(sizeof(Tree. Node)); if (new. Node. Ptr == NULL) { fprintf(stderr, “Out of memoryn”); exit(1); } else { new. Node. Ptr->key = value; new. Node. Ptr->left. Ptr = NULL; new. Node. Ptr->right. Ptr = NULL; } return new. Node. Ptr; } 18
value 3. 3 new. Node. Ptr NULL new. Node. Ptr 0 x 2000 3. 3 NULL 19
Inorder • Inorder traversal of a Binary Search Tree always gives the sorted order of the keys. void print. Inorder(Tree. Node* node. Ptr) { initially, pointer to root node } 20
Inorder • Inorder traversal of a Binary Search Tree always gives the sorted order of the keys. void print. Inorder(Tree. Node* node. Ptr) { traverse left sub-tree visit the node traverse right sub-tree } 21
Inorder • Inorder traversal of a Binary Search Tree always gives the sorted order of the keys. void print. Inorder(Tree. Node* node. Ptr) { print. Inorder(node. Ptr->left. Ptr); printf(“ %f, node. Ptr->key); print. Inorder(node. Ptr->right. Ptr); } 22
Inorder • Inorder traversal of a Binary Search Tree always gives the sorted order of the keys. void print. Inorder(Tree. Node* node. Ptr) { if (node. Ptr != NULL) { print. Inorder(node. Ptr->left. Ptr); printf(“ %f”, node. Ptr->key); print. Inorder(node. Ptr->right. Ptr); } } 23
Inorder node. Ptr void print. Inorder(Tree. Node* node. Ptr){ if (node. Ptr != NULL){ print. Inorder(node. Ptr->left. Ptr); printf(“ %f”, node. Ptr->key); print. Inorder(node. Ptr->right. Ptr); } } 24
Inorder node. Ptr void print. Inorder(Tree. Node* node. Ptr){ if (node. Ptr != NULL){ print. Inorder(node. Ptr->left. Ptr); printf(“ %f”, node. Ptr->key); print. Inorder(node. Ptr->right. Ptr); } } 25
Inorder node. Ptr void print. Inorder(Tree. Node* node. Ptr){ if (node. Ptr != NULL){ print. Inorder(node. Ptr->left. Ptr); printf(“ %f”, node. Ptr->key); print. Inorder(node. Ptr->right. Ptr); } } 26
Inorder node. Ptr void print. Inorder(Tree. Node* node. Ptr){ if (node. Ptr != NULL){ print. Inorder(node. Ptr->left. Ptr); printf(“ %f”, node. Ptr->key); print. Inorder(node. Ptr->right. Ptr); } } 27
Inorder node. Ptr void print. Inorder(Tree. Node* node. Ptr){ if (node. Ptr != NULL){ print. Inorder(node. Ptr->left. Ptr); printf(“ %f”, node. Ptr->key); print. Inorder(node. Ptr->right. Ptr); } } 28
Inorder node. Ptr void print. Inorder(Tree. Node* node. Ptr){ if (node. Ptr != NULL){ print. Inorder(node. Ptr->left. Ptr); printf(“ %f”, node. Ptr->key); print. Inorder(node. Ptr->right. Ptr); } } 29
Inorder node. Ptr void print. Inorder(Tree. Node* node. Ptr){ if (node. Ptr != NULL){ print. Inorder(node. Ptr->left. Ptr); printf(“ %f”, node. Ptr->key); print. Inorder(node. Ptr->right. Ptr); } } 30
Inorder node. Ptr void print. Inorder(Tree. Node* node. Ptr){ if (node. Ptr != NULL){ print. Inorder(node. Ptr->left. Ptr); printf(“ %f”, node. Ptr->key); print. Inorder(node. Ptr->right. Ptr); } } 31
Inorder node. Ptr void print. Inorder(Tree. Node* node. Ptr){ if (node. Ptr != NULL){ print. Inorder(node. Ptr->left. Ptr); printf(“ %f”, node. Ptr->key); print. Inorder(node. Ptr->right. Ptr); } } 32
Inorder node. Ptr void print. Inorder(Tree. Node* node. Ptr){ if (node. Ptr != NULL){ print. Inorder(node. Ptr->left. Ptr); printf(“ %f”, node. Ptr->key); print. Inorder(node. Ptr->right. Ptr); } } 33
Inorder node. Ptr void print. Inorder(Tree. Node* node. Ptr){ if (node. Ptr != NULL){ print. Inorder(node. Ptr->left. Ptr); printf(“ %f”, node. Ptr->key); print. Inorder(node. Ptr->right. Ptr); } } 34
Inorder node. Ptr void print. Inorder(Tree. Node* node. Ptr){ if (node. Ptr != NULL){ print. Inorder(node. Ptr->left. Ptr); printf(“ %f”, node. Ptr->key); print. Inorder(node. Ptr->right. Ptr); } } 35
Inorder node. Ptr void print. Inorder(Tree. Node* node. Ptr){ if (node. Ptr != NULL){ print. Inorder(node. Ptr->left. Ptr); printf(“ %f”, node. Ptr->key); print. Inorder(node. Ptr->right. Ptr); } } 36
Inorder node. Ptr void print. Inorder(Tree. Node* node. Ptr){ if (node. Ptr != NULL){ print. Inorder(node. Ptr->left. Ptr); printf(“ %f”, node. Ptr->key); print. Inorder(node. Ptr->right. Ptr); } } 37
Inorder node. Ptr void print. Inorder(Tree. Node* node. Ptr){ if (node. Ptr != NULL){ print. Inorder(node. Ptr->left. Ptr); printf(“ %f”, node. Ptr->key); print. Inorder(node. Ptr->right. Ptr); } } 38
Inorder node. Ptr void print. Inorder(Tree. Node* node. Ptr){ if (node. Ptr != NULL){ print. Inorder(node. Ptr->left. Ptr); printf(“ %f”, node. Ptr->key); print. Inorder(node. Ptr->right. Ptr); } } 39
Inorder node. Ptr void print. Inorder(Tree. Node* node. Ptr){ if (node. Ptr != NULL){ print. Inorder(node. Ptr->left. Ptr); printf(“ %f”, node. Ptr->key); print. Inorder(node. Ptr->right. Ptr); } } 40
Inorder node. Ptr void print. Inorder(Tree. Node* node. Ptr){ if (node. Ptr != NULL){ print. Inorder(node. Ptr->left. Ptr); printf(“ %f”, node. Ptr->key); print. Inorder(node. Ptr->right. Ptr); } } 41
Inorder node. Ptr void print. Inorder(Tree. Node* node. Ptr){ if (node. Ptr != NULL){ print. Inorder(node. Ptr->left. Ptr); printf(“ %f”, node. Ptr->key); print. Inorder(node. Ptr->right. Ptr); } } 42
Inorder node. Ptr void print. Inorder(Tree. Node* node. Ptr){ if (node. Ptr != NULL){ print. Inorder(node. Ptr->left. Ptr); printf(“ %f”, node. Ptr->key); print. Inorder(node. Ptr->right. Ptr); } } 43
Inorder node. Ptr void print. Inorder(Tree. Node* node. Ptr){ if (node. Ptr != NULL){ print. Inorder(node. Ptr->left. Ptr); printf(“ %f”, node. Ptr->key); print. Inorder(node. Ptr->right. Ptr); } } 44
Inorder node. Ptr void print. Inorder(Tree. Node* node. Ptr){ if (node. Ptr != NULL){ print. Inorder(node. Ptr->left. Ptr); printf(“ %f”, node. Ptr->key); print. Inorder(node. Ptr->right. Ptr); } } 45
Inorder node. Ptr void print. Inorder(Tree. Node* node. Ptr){ if (node. Ptr != NULL){ print. Inorder(node. Ptr->left. Ptr); printf(“ %f”, node. Ptr->key); print. Inorder(node. Ptr->right. Ptr); } } 46
Inorder node. Ptr void print. Inorder(Tree. Node* node. Ptr){ if (node. Ptr != NULL){ print. Inorder(node. Ptr->left. Ptr); printf(“ %f”, node. Ptr->key); print. Inorder(node. Ptr->right. Ptr); } } 47
Search Example: 59 43 31 64 20 40 28 33 56 47 89 59 57 found 48 48
Search Example: 61 43 31 64 20 40 28 33 56 47 89 59 57 failed 49 49
Search: Checklist • if target key is less than current node’s key, search the left sub-tree. • else, if target key is greater than current node’s key, search the right sub-tree. • returns: – if found, or if target key is equal to current node’s key, a pointer to node containing target key. – otherwise, NULL pointer. 50
Tree. Node* search(Tree. Node* node. Ptr, float target) { if (node. Ptr != NULL) { if (target < node. Ptr->key) { node. Ptr = search(node. Ptr->left. Ptr, target); } else if (target > node. Ptr->key) { node. Ptr = search(node. Ptr->right. Ptr, target); } } return node. Ptr; } 51
Function Call to Search /* …other bits of code omitted… */ printf(“Enter target ”); scanf(“%f”, &item); if (search(root. Ptr, item) == NULL) { printf(“Item was not foundn”); } else { printf(“Item foundn”); } /* …and so on… */ 52
Search node. Ptr Find 0. 7 1. 0 0. 6 0. 3 1. 9 0. 8 0. 4 0. 7 1. 4 1. 1 2. 7 1. 8 Tree. Node* search(Tree. Node* node. Ptr, float target){ if (node. Ptr != NULL){ if (target < node. Ptr->key) node. Ptr = search(node. Ptr->left. Ptr, target); else if (target > node. Ptr->key) node. Ptr = search(node. Ptr->right. Ptr, target); } return node. Ptr; } 53
Search node. Ptr Find 0. 7 1. 0 0. 6 0. 3 1. 9 0. 8 0. 4 0. 7 1. 4 1. 1 2. 7 1. 8 Tree. Node* search(Tree. Node* node. Ptr, float target){ if (node. Ptr != NULL){ if (target < node. Ptr->key) node. Ptr = search(node. Ptr->left. Ptr, target); else if (target > node. Ptr->key) node. Ptr = search(node. Ptr->right. Ptr, target); } return node. Ptr; } 54
Search node. Ptr Find 0. 7 1. 0 0. 6 0. 3 1. 9 0. 8 0. 4 0. 7 1. 4 1. 1 2. 7 1. 8 Tree. Node* search(Tree. Node* node. Ptr, float target){ if (node. Ptr != NULL){ if (target < node. Ptr->key) node. Ptr = search(node. Ptr->left. Ptr, target); else if (target > node. Ptr->key) node. Ptr = search(node. Ptr->right. Ptr, target); } return node. Ptr; } 55
Search node. Ptr Find 0. 7 1. 0 0. 6 0. 3 1. 9 0. 8 0. 4 0. 7 1. 4 1. 1 2. 7 1. 8 Tree. Node* search(Tree. Node* node. Ptr, float target){ if (node. Ptr != NULL){ if (target < node. Ptr->key) node. Ptr = search(node. Ptr->left. Ptr, target); else if (target > node. Ptr->key) node. Ptr = search(node. Ptr->right. Ptr, target); } return node. Ptr; } 56
Search node. Ptr Find 0. 5 1. 0 0. 6 0. 3 1. 9 0. 8 0. 4 0. 7 1. 4 1. 1 2. 7 1. 8 Tree. Node* search(Tree. Node* node. Ptr, float target){ if (node. Ptr != NULL){ if (target < node. Ptr->key) node. Ptr = search(node. Ptr->left. Ptr, target); else if (target > node. Ptr->key) node. Ptr = search(node. Ptr->right. Ptr, target); } return node. Ptr; } 57
Search node. Ptr Find 0. 5 1. 0 0. 6 0. 3 1. 9 0. 8 0. 4 0. 7 1. 4 1. 1 2. 7 1. 8 Tree. Node* search(Tree. Node* node. Ptr, float target){ if (node. Ptr != NULL){ if (target < node. Ptr->key) node. Ptr = search(node. Ptr->left. Ptr, target); else if (target > node. Ptr->key) node. Ptr = search(node. Ptr->right. Ptr, target); } return node. Ptr; } 58
Search node. Ptr Find 0. 5 1. 0 0. 6 0. 3 1. 9 0. 8 0. 4 0. 7 1. 4 1. 1 2. 7 1. 8 Tree. Node* search(Tree. Node* node. Ptr, float target){ if (node. Ptr != NULL){ if (target < node. Ptr->key) node. Ptr = search(node. Ptr->left. Ptr, target); else if (target > node. Ptr->key) node. Ptr = search(node. Ptr->right. Ptr, target); } return node. Ptr; } 59
Search node. Ptr Find 0. 5 1. 0 0. 6 0. 3 1. 9 0. 8 0. 4 0. 7 1. 4 1. 1 2. 7 1. 8 Tree. Node* search(Tree. Node* node. Ptr, float target){ if (node. Ptr != NULL){ if (target < node. Ptr->key) node. Ptr = search(node. Ptr->left. Ptr, target); else if (target > node. Ptr->key) node. Ptr = search(node. Ptr->right. Ptr, target); } return node. Ptr; } 60
Search node. Ptr Find 0. 5 1. 0 0. 6 0. 3 1. 9 0. 8 0. 4 0. 7 1. 4 1. 1 2. 7 1. 8 Tree. Node* search(Tree. Node* node. Ptr, float target){ if (node. Ptr != NULL){ if (target < node. Ptr->key) node. Ptr = search(node. Ptr->left. Ptr, target); else if (target > node. Ptr->key) node. Ptr = search(node. Ptr->right. Ptr, target); } return node. Ptr; } 61
Insert Example: 57 43 31 64 20 40 28 33 56 47 89 59 62
Insert Example: 57 43 31 64 20 40 28 33 56 47 89 59 57 63
Insert • Create new node for the item. • Find a parent node. • Attach new node as a leaf. 64
Insert: Recursive • parameters: – pointer to current node (initially: root node). – item to be inserted. • If current node is NULL – Create a new node and return it. • Else if item’s key is less (greater) than current node’s key: – otherwise, let the left (right) child node be the current node, setting the parent left (right) link equal that node, and repeat recursively. 65
Tree. Node* insert(Tree. Node* node. Ptr, float item) { if (node. Ptr == NULL) { node. Ptr = make. Tree. Node(item); } else if (item < node. Ptr->key) { node. Ptr->left. Ptr = insert(node. Ptr->left. Ptr, item); } else if (item > node. Ptr->key) { node. Ptr->right. Ptr = insert(node. Ptr->right. Ptr, item); } return node. Ptr; } 66
Function Call to Insert /* …other bits of code omitted… */ printf(“Enter number of items ”); scanf(“%d”, &n); for (i = 0; i < n; i++) { scanf(“%f”, &item); root. Ptr = insert(root. Ptr, item); } /* …and so on… */ 67
Insert node. Ptr Insert 0. 9 1. 0 0. 6 0. 3 1. 9 0. 8 0. 4 0. 7 1. 4 1. 1 2. 7 1. 8 Tree. Node* insert(Tree. Node* node. Ptr, float item) { if (node. Ptr == NULL) node. Ptr = make. Tree. Node(item); else if (item < node. Ptr->key) node. Ptr->left. Ptr = insert(node. Ptr->left. Ptr, item); else if (item > node. Ptr->key) node. Ptr->right. Ptr = insert(node. Ptr->right. Ptr, item); return node. Ptr; } 68
Insert node. Ptr Insert 0. 9 1. 0 0. 6 0. 3 1. 9 0. 8 0. 4 0. 7 1. 4 1. 1 2. 7 1. 8 Tree. Node* insert(Tree. Node* node. Ptr, float item) { if (node. Ptr == NULL) node. Ptr = make. Tree. Node(item); else if (item < node. Ptr->key) node. Ptr->left. Ptr = insert(node. Ptr->left. Ptr, item); else if (item > node. Ptr->key) node. Ptr->right. Ptr = insert(node. Ptr->right. Ptr, item); return node. Ptr; } 69
Insert node. Ptr Insert 0. 9 1. 0 0. 6 0. 3 1. 9 0. 8 0. 4 0. 7 1. 4 1. 1 2. 7 1. 8 Tree. Node* insert(Tree. Node* node. Ptr, float item) { if (node. Ptr == NULL) node. Ptr = make. Tree. Node(item); else if (item < node. Ptr->key) node. Ptr->left. Ptr = insert(node. Ptr->left. Ptr, item); else if (item > node. Ptr->key) node. Ptr->right. Ptr = insert(node. Ptr->right. Ptr, item); return node. Ptr; } 70
Insert node. Ptr Insert 0. 9 1. 0 0. 6 0. 3 1. 9 0. 8 0. 4 0. 7 1. 4 1. 1 2. 7 1. 8 Tree. Node* insert(Tree. Node* node. Ptr, float item) { if (node. Ptr == NULL) node. Ptr = make. Tree. Node(item); else if (item < node. Ptr->key) node. Ptr->left. Ptr = insert(node. Ptr->left. Ptr, item); else if (item > node. Ptr->key) node. Ptr->right. Ptr = insert(node. Ptr->right. Ptr, item); return node. Ptr; } 71
Insert node. Ptr Insert 0. 9 1. 0 0. 6 0. 3 1. 9 0. 8 0. 4 0. 7 1. 4 0. 9 1. 1 2. 7 1. 8 Tree. Node* insert(Tree. Node* node. Ptr, float item) { if (node. Ptr == NULL) node. Ptr = make. Tree. Node(item); else if (item < node. Ptr->key) node. Ptr->left. Ptr = insert(node. Ptr->left. Ptr, item); else if (item > node. Ptr->key) node. Ptr->right. Ptr = insert(node. Ptr->right. Ptr, item); return node. Ptr; } 72
Sorting To sort a sequence of items: • Insert items into a Binary Search Tree. • Then Inorder Traverse the tree. 73
Sorting: Analysis • Average Case: O(n log(n)) ~ log 2 n • Insert (i+1)th item: ~ log 2(i) comparisons 74
Sort the following list into a binary search tree 1. 0 2. 5 0. 7 3. 6 2. 1 75
Sort 1. 0 Sort the following list into a binary search tree 1. 0 2. 5 0. 7 3. 6 2. 1 76
Sort 1. 0 2. 5 Sort the following list into a binary search tree 1. 0 2. 5 0. 7 3. 6 2. 1 77
Sort 1. 0 0. 5 2. 5 Sort the following list into a binary search tree 1. 0 2. 5 0. 7 3. 6 2. 1 78
Sort 1. 0 0. 5 2. 5 0. 7 Sort the following list into a binary search tree 1. 0 2. 5 0. 7 3. 6 2. 1 79
Sort 1. 0 0. 5 2. 5 0. 7 3. 6 Sort the following list into a binary search tree 1. 0 2. 5 0. 7 3. 6 2. 1 80
Sort 1. 0 0. 5 2. 5 0. 7 2. 1 3. 6 Sort the following list into a binary search tree 1. 0 2. 5 0. 7 3. 6 2. 1 81
Sorting: Analysis • Worst Case: O(n 2) Example: Insert: 1, 3, 7, 9, 11, 15 • Insert (i+1)th item: ~ i comparisons 82
- Slides: 82