A binary search tree or BST is a binary tree that is either empty or in which the data element of each node has a key, and:



Similar documents
root node level: internal node edge leaf node Data Structures & Algorithms McQuain

A binary search tree or BST is a binary tree that is either empty or in which the data element of each node has a key, and:

Binary Search Trees. Data in each node. Larger than the data in its left child Smaller than the data in its right child

Converting a Number from Decimal to Binary

Binary Search Trees CMPSC 122

Ordered Lists and Binary Trees

Analysis of Algorithms I: Binary Search Trees

A binary search tree is a binary tree with a special property called the BST-property, which is given as follows:

Binary Heaps * * * * * * * / / \ / \ / \ / \ / \ * * * * * * * * * * * / / \ / \ / / \ / \ * * * * * * * * * *

Data Structures Using C++ 2E. Chapter 5 Linked Lists

Symbol Tables. Introduction

1) The postfix expression for the infix expression A+B*(C+D)/F+D*E is ABCD+*F/DE*++

Data Structures and Algorithms

Data Structures Using C++ 2E. Chapter 5 Linked Lists

Binary Search Trees. A Generic Tree. Binary Trees. Nodes in a binary search tree ( B-S-T) are of the form. P parent. Key. Satellite data L R

Questions 1 through 25 are worth 2 points each. Choose one best answer for each.

Binary Heap Algorithms

TREE BASIC TERMINOLOGIES

Sorting revisited. Build the binary search tree: O(n^2) Traverse the binary tree: O(n) Total: O(n^2) + O(n) = O(n^2)

B-Trees. Algorithms and data structures for external memory as opposed to the main memory B-Trees. B -trees

The ADT Binary Search Tree

Lecture 6: Binary Search Trees CSCI Algorithms I. Andrew Rosenberg

CS104: Data Structures and Object-Oriented Design (Fall 2013) October 24, 2013: Priority Queues Scribes: CS 104 Teaching Team

Binary Trees and Huffman Encoding Binary Search Trees

Unordered Linked Lists

1. The memory address of the first element of an array is called A. floor address B. foundation addressc. first address D.

Full and Complete Binary Trees

How To Create A Tree From A Tree In Runtime (For A Tree)

Data Structures, Practice Homework 3, with Solutions (not to be handed in)

Outline BST Operations Worst case Average case Balancing AVL Red-black B-trees. Binary Search Trees. Lecturer: Georgy Gimel farb

Heaps & Priority Queues in the C++ STL 2-3 Trees

PART-A Questions. 2. How does an enumerated statement differ from a typedef statement?

Algorithms Chapter 12 Binary Search Trees

Previous Lectures. B-Trees. External storage. Two types of memory. B-trees. Main principles

Binary Search Trees (BST)

MAX = 5 Current = 0 'This will declare an array with 5 elements. Inserting a Value onto the Stack (Push)

Lecture Notes on Binary Search Trees

Data Structures and Data Manipulation

From Last Time: Remove (Delete) Operation

Node-Based Structures Linked Lists: Implementation

C++ INTERVIEW QUESTIONS

Cpt S 223. School of EECS, WSU

Data Structure [Question Bank]

Why you shouldn't use set (and what you should use instead) Matt Austern

5. A full binary tree with n leaves contains [A] n nodes. [B] log n 2 nodes. [C] 2n 1 nodes. [D] n 2 nodes.

Linked List as an ADT (cont d.)

Chapter 14 The Binary Search Tree

CSE 326: Data Structures B-Trees and B+ Trees

Binary Search Trees 3/20/14

Operations: search;; min;; max;; predecessor;; successor. Time O(h) with h height of the tree (more on later).

Lecture Notes on Binary Search Trees

Persistent Binary Search Trees

Binary Heaps. CSE 373 Data Structures

Learning Outcomes. COMP202 Complexity of Algorithms. Binary Search Trees and Other Search Trees

Section IV.1: Recursive Algorithms and Recursion Trees

Algorithms and Data Structures

Why Use Binary Trees?

6 March Array Implementation of Binary Trees

Data Structures Fibonacci Heaps, Amortized Analysis

Pseudo code Tutorial and Exercises Teacher s Version

Big Data and Scripting. Part 4: Memory Hierarchies

KITES TECHNOLOGY COURSE MODULE (C, C++, DS)

Algorithms and Data Structures Written Exam Proposed SOLUTION

Glossary of Object Oriented Terms

WORKSPACE WEB DEVELOPMENT & OUTSOURCING TRAINING CENTER

10CS35: Data Structures Using C

DNS LOOKUP SYSTEM DATA STRUCTURES AND ALGORITHMS PROJECT REPORT

Introduction to data structures

A Comparison of Dictionary Implementations

Variable Base Interface

DATA STRUCTURES USING C

Chapter 13: Query Processing. Basic Steps in Query Processing

El Dorado Union High School District Educational Services

EE602 Algorithms GEOMETRIC INTERSECTION CHAPTER 27

Lecture 12 Doubly Linked Lists (with Recursion)

recursion, O(n), linked lists 6/14

PROBLEM SOLVING SEVENTH EDITION WALTER SAVITCH UNIVERSITY OF CALIFORNIA, SAN DIEGO CONTRIBUTOR KENRICK MOCK UNIVERSITY OF ALASKA, ANCHORAGE PEARSON

Physical Data Organization

Introduction to Data Structures and Algorithms

7.1 Our Current Model

Analysis of Binary Search algorithm and Selection Sort algorithm

- Easy to insert & delete in O(1) time - Don t need to estimate total memory needed. - Hard to search in less than O(n) time

Data Structure with C

Chapter Objectives. Chapter 9. Sequential Search. Search Algorithms. Search Algorithms. Binary Search

CSE 326, Data Structures. Sample Final Exam. Problem Max Points Score 1 14 (2x7) 2 18 (3x6) Total 92.

Sequences in the C++ STL

Integrating the C++ Standard Template Library Into the Undergraduate Computer Science Curriculum

Linked Lists: Implementation Sequences in the C++ STL

Sequential Data Structures

Binary storage of graphs and related data

Algorithms. Margaret M. Fleck. 18 October 2010

Sample Questions Csci 1112 A. Bellaachia

Analysis of Algorithms I: Optimal Binary Search Trees

GRAPH THEORY LECTURE 4: TREES

Alex. Adam Agnes Allen Arthur

Data Structures and Algorithms(5)

The C Programming Language course syllabus associate level

Data Structures. Level 6 C Module Descriptor

Any two nodes which are connected by an edge in a graph are called adjacent node.

Transcription:

1 The general binary tree shown in the previous chapter is not terribly useful in practice. The chief use of binary trees is for providing rapid access to data (indexing, if you will) and the general binary tree does not have good performance. Suppose that we wish to store data elements that contain a number of fields, and that one of those fields is distinguished as the key upon which searches will be performed. A binary search tree or ST is a binary tree that is either empty or in which the data element of each node has a key, and: 1. All keys in the left subtree (if there is one) are less than the key in the root node. 2. All keys in the right subtree (if there is one) are greater than or equal to the key in the root node. 3. The left and right subtrees of the root are binary search trees. ST Insertion 2 ere, the key values are characters (and only key values are shown). Inserting the following key values in the given order yields the given ST: In a ST, insertion is always at the leaf level. Traverse the ST, comparing the new value to existing ones, until you find the right spot, then add a new leaf node holding that value. What is the resulting tree if the (same) key values are inserted in the order: or

Searching in a ST 3 ecause of the key ordering imposed by a ST, searching resembles the binary search algorithm on a sorted array, which is O(log N) for an array of N elements. A ST offers the advantage of purely dynamic storage, no wasted array cells and no shifting of the array tail on insertion and deletion. A Trace searching for the key value. ST eletion 4 eletion is perhaps the most complex operation on a ST, because the algorithm must result in a ST. The question is: what value should replace the one deleted? As with the general tree, we have cases: - Removing a leaf node is trivial, just set the relevant child pointer in the parent node to NULL. - Removing an internal node which has only one subtree is also trivial, just set the relevant child pointer in the parent node to target the root of the subtree. NULL

ST eletion 5 - Removing an internal node which has two subtrees is more complex Simply removing the node would disconnect the tree. ut what value should replace the one in the targeted node? To preserve the ST property, we must take the smallest value from the right subtree, which would be the closest succcessor of the value being deleted. ortunately, the smallest value will always lie in the left-most node of the subtree. ST eletion 6 So, we first find the left-most node of the right subtree, and then swap data values between it and the targeted node. Note that at this point we don t necessarily have a ST. Now we must delete the swapped value from the right subtree. That looks straightforward here since the node in question is a leaf. owever - the node will NOT be a leaf in all cases - the occurrence of duplicate values is a complicating factor (so we might want to have a eleterightminimum() function to clean up at this point).

eleting the Minimum Value 7 Suppose we want to delete the value from the ST: After swapping the with the, we must delete We must be careful to not confuse this with the other node containing an. Also, consider deleting the value. In this case, the right subtree is just a leaf node, whose parent is the node originally targeted for deletion. Moral: be careful to consider ALL cases when designing. ST Template Interface A ST template can be derived from the general binary tree class, overriding all of the search-related functions inherited from the general binary tree base: 8 class STreeT : public inarytreet<t> { private: bool Insertelper(const T&, innodet<t>* sroot); bool eleteelper(const T&, innodet<t>* sroot); bool eleterightminimum(innodet<t>* sroot); T* const indelper(const T&, innodet<t>* sroot); public: STreeT(); STreeT(const T& ); // create empty ST // root holds bool Insert(const T& ); // insert element Arguably, the use of bool elete(const T& ); // delete element inheritance is T* const ind(const T& ); // return access to unjustified given the degree of virtual ~STreeT(); change needed in ; the derived type. //... continues with member function implementations...

ST onstructor and estructor 9 The default ST constructor just initializes an empty tree by calling the base default constructor: STreeT<T>::STreeT() : inarytreet<t>() { The second ST constructor is entirely similar, merely calling the corresponding base constructor. The ST destructor is simply an empty shell. The base class destructor will be invoked automatically, as needed, and the derived class does not allocate any dynamic content itself, so the base destructor is adequate. STreeT<T>::~STreeT() { ST Search Implementation 10 The ST ind() function takes advantage of the ST data organization: T* const STreeT<T>::ind(const T& toind) { if (Root == NULL) return NULL; return (indelper(toind, Root)); T* const STreeT<T>::indelper(const T& toind, innodet<t>* sroot) { if (sroot == NULL) return false; if (sroot->lement == toind) { urrent = sroot; return &(urrent->lement); if (toind < sroot->lement) return indelper(toind, sroot->left); else return indelper(toind, sroot->right); Uses operator== for the type T, which is customized by the client for the particular application at hand. Search direction is determined by relationship of target data to data in current node.

ST Insert Implementation 11 The public Insert() function is just a stub to call the recursive helper: bool STreeT<T>::Insert(const T& ) { return Insertelper(, Root); Warning: the ST definition in these notes allows for duplicate data values to occur, the logic of insertion may need to be changed for your specific application. The stub simply calls the helper function.. The helper function must find the appropriate place in the tree to place the new node. The design logic is straightforward: - locate the parent "node" of the new leaf, and - hang a new leaf off of it, on the correct side ST Insert elper The Insertelper() function: 12 bool STreeT<T>::Insertelper(const T&, innodet<t>*& sroot) { if (sroot == NULL) { // found the location innodet<t>* Temp = new(nothrow) innodet<t>(); if (Temp == NULL) return false; sroot = urrent = Temp; return true; // recursive descent logic goes next... When the parent of the new value is found, one more recursive call takes place, passing in a NULL pointer to the helper function. Note that the insert helper function must be able to modify the node pointer parameter, and that the search logic is precisely the same as for the find function.

ST elete Implementation 13 The public elete() function is very similar to the insertion function: bool STreeT<T>::elete(const T& ) { if ( Root == NULL ) return false; return eleteelper(, Root); The eleteelper() function design is also relatively straightforward: - locate the parent of the node containing the target value - determine the deletion case (as described earlier) and handle it: - parent has only one subtree - parent has two subtrees The details of implementing the delete helper function are left to the reader Some Refinements The given ST template inherits a number of useful features: - a function to provide the size of the tree - a function to provide the height of the tree - a function to display the tree in a useful manner 14 It is also useful to have some instrumentation during testing. or example: - log the values encountered and the directions taken during a search This is also easy to add, but it poses a problem since we generally do not want to see such output when the ST is used. I resolve this by adding some data members and mutators to the template that enable the client to optionally associate an output stream with the object, and to turn logging of its operation on and off as needed.

Adding an Iterator 15 A ST iterator can be added in a very similar way to that shown earlier for the linked list iterator. As before: - add a declaration of a class iterator within the ST declaration - an iterator will store a pointer to a tree node; dereferencing it will return the address of the data element within that node. - implement the expected increment/decrement operators for the iterator - add the expected iterator-supplying functions to the ST - there's no case for an iterator-based insertion function in a ST, but there may be a case for an iterator-based deletion function - add a search function that returns an iterator There are two considerations: - what traversal pattern should the iterator provide? - is it necessary to modify the ST implementation aside from adding support functions? Iterator-based ind 16 The public Insert() function is just a stub to call the recursive helper: typename STreeT<T>::iterator STreeT<T>::ind(const T& toind) { if (Root == NULL) return iterator(null); return (indelper(toind, Root)); The public stub simply calls the helper function: typename STreeT<T>::iterator STreeT<T>::indelper(const T& toind, innodet<t>* sroot) { if (sroot == NULL) return iterator(null); if (sroot->lement == toind) { return iterator(sroot); // recursive descent logic goes next...

Iterator Increment Logic 17 The only issue that is handled differently from the the linked list iterator is the pattern by which an iterator steps forward or backwards within the ST. onsider stepping forward as in an inorder traversal: A I J The pattern is reasonably straightforward, but how can we move up from a node to its parent within the ST? lient-side Use 18 ere is a somewhat trivial use of the iterator-supplied traversal: STreeT<int>::iterator It; for (It = T.begin(); It!= T.end(); It++) { if ( *It <= loor ) { *It = loor; Note also that the client can implement an inorder search of the ST using the same approach. In fact, the ST itself could do that instead of recursion. One point here is that the code above shows how the client can traverse the structure without knowing anything about the actual physical layout compare to a traversal of an STL vector, or even of a simple array.

Instrumentation The extended ST template: class STreeT { protected:... ostream* Log; bool loggingon;... public:... bool setlogstream(ostream* const L); bool logon(); bool logoff(); ; 19 The client may entirely ignore the ability to log an execution trace, or enable it and turn logging on and off at will. bool STreeT<T>::logOn() { if ( Log!= NULL ) loggingon = true; return loggingon; Of course, it's important to avoid dereferencing a null pointer T* STreeT<T>::Insertelper(...) {... if ( lem < (sroot->lement) ) { if ( loggingon ) *Log << "Insert: going left from " << (sroot->lement) << endl; return Insertelper(lem, sroot->left);... alance in a ST 20 owever, a ST with N nodes does not always provide O(log N) search times. A A well-balanced ST. This will have log(n) search times in the worst case. A What if we inserted the values in the order: A A poorly-balanced ST. This will not have log(n) search times in the worst case.

Search ost in a ST 21 rom an earlier theorem on binary trees, we know that a binary tree that contains L nodes must contain at least 1 + log L levels. If the tree is full, we can improve the result to imply that a full binary tree that contains N nodes must contain at least log N levels. So, for any ST, the there is always an element whose search cost is at least log N. Unfortunately, it can be much worse. If the ST is a "stalk" then the search cost for the last element would be N. It all comes down to one simple issue: how close is the tree to having minimum height? Unfortunately, if we perform lots of random insertions and deletions in a ST, there is no reason to expect that the result will have nearly-minimum height. ost of Insertion/eletion in a ST 22 learly, once the parent is found, the remaining cost of inserting a new node in a ST is constant, simply allocating a new node object and setting a pointer in the parent node. So, insertion cost is essentially the same as search cost. or deletion, the argument is slightly more complex. Suppose the parent of the targeted node has been found. If the parent has only one subtree, then the remaining cost is resetting a pointer in the parent and deallocating the node; that's constant. ut, if the parent has two subtrees, then an additional search must be carried out to find the minimum value in the right subtree, and then an element copy must be performed, and then that node must be removed from the right subtree (which is again a constant cost). In either case, we have no more than the cost of a worst-case search to the leaf level, plus some constant manipulations. So, deletion cost is also essentially the same as search cost.