+ All Categories
Home > Documents > CS 261 – Fall 2009 Binary Search Trees Again, but in detail.

CS 261 – Fall 2009 Binary Search Trees Again, but in detail.

Date post: 11-Jan-2016
Category:
Upload: reynard-snow
View: 214 times
Download: 0 times
Share this document with a friend
23
CS 261 – Fall 2009 Binary Search Trees Again, but in detail
Transcript
Page 1: CS 261 – Fall 2009 Binary Search Trees Again, but in detail.

CS 261 – Fall 2009

Binary Search Trees

Again, but in detail

Page 2: CS 261 – Fall 2009 Binary Search Trees Again, but in detail.

Binary Search Tree•Binary search trees are binary tree’s where every node’s object value is:–Greater than or equal to all its descendents in the left subtree

–Less than or equal to all its descendents in the right subtree

•An in-order traversal will return the elements in sorted order

•If the tree is reasonably full, searching for an element is O(log n)

Page 3: CS 261 – Fall 2009 Binary Search Trees Again, but in detail.

Binary Search Tree: Example

Alex

Abner Angela

Adela Alice Audrey

Adam Agnes Allen Arthur

Abigail

Page 4: CS 261 – Fall 2009 Binary Search Trees Again, but in detail.

Binary Search Tree (BST): Implementationstruct BST { struct Node * root; int size;};

struct node { EleType value;

struct node * left;

struct node * right;

};

void BSTinit (struct BST *tree);

void BSTadd(struct BST *tree, EleType value);

int BSTcontains (struct BST *tree, EleType value);

void BSTremove (struct BST *tree, EleType value);

int BSTsze (struct BST *tree);

Page 5: CS 261 – Fall 2009 Binary Search Trees Again, but in detail.

Init - what needs to be done?struct BST { struct node * root; int size;};

void BSTinit (struct BST *tree) {

tree->root = 0;

tree->size = 0;

}

Page 6: CS 261 – Fall 2009 Binary Search Trees Again, but in detail.

Implementing the Bag: Contains•Start at the root.

•At each node, compare to test: return true if match

•If test is less than node, look at left child

•Otherwise if test is greater than node, look at right child

•Traverses a path from the root to the leaf.

•Therefore, if the tree is reasonably complete (an important if) the execution time is O( ?? )

Page 7: CS 261 – Fall 2009 Binary Search Trees Again, but in detail.

Use Recursion, or use a loop?•Both will work. Lets compare the two

int BSTcontains

(struct BST *tree, EleType value) {

struct node * current = tree->root;

while (current != 0) {

if (EQ(value, current->value)) return 1;

if (LT(value, current->value))

current = current->left;

else current = current->right;

}

return 0;

}

Page 8: CS 261 – Fall 2009 Binary Search Trees Again, but in detail.

Recursive versionint BSTcontains

(struct BST *tree, EleType value)

{ return BSTnodecontains(tree->root, value); }

int BSTnodeContains

(struct BST *current, EleType value) {

if (current == 0) return 0;

if (EQ(value, current->value)) return 1;

if (LT(value, current->value))

return BSTnodeContains(current->left, value);

else return BSTnodeContains(current->right, value);

}

Page 9: CS 261 – Fall 2009 Binary Search Trees Again, but in detail.

Which is easier to understand?•Somewhat a matter of style

•It is what you are used to

•Execution time will be very similar

Page 10: CS 261 – Fall 2009 Binary Search Trees Again, but in detail.

Implementing a Bag: Add•Do the same type of traversal from root to leaf.

•When you find a null value, create a new node.

Alex

Abner Angela

Adela Alice Audrey

Adam Agnes Allen Arthur

Abigail

Page 11: CS 261 – Fall 2009 Binary Search Trees Again, but in detail.

A useful trick•A useful trick (adapted from the functional programming world). Make a secondary routine that returns the tree with the value inserted.

Node add (Node current, EleType newValue) if current is null then return new Node with value

otherwise if newValue < Node value left child = add (left child, newValue) else right child = add (right child, newValue)

return current node

Page 12: CS 261 – Fall 2009 Binary Search Trees Again, but in detail.

Add just calls the utility routine

void BSTadd (EleType newValue) {

root = _BSTnodeAdd(root, newValue);

dataSize++;

}

Page 13: CS 261 – Fall 2009 Binary Search Trees Again, but in detail.

Real work is done inside Nodestruct node * BSTnodeAdd (struct node * current, EleType value) {

if (current == 0) {

current = (struct node *) malloc(sizeof(struct node));

assert(current != 0);

current->value = value;

current->left = current->right = 0;

} else if (LT(value, current->value))

current->left = BSTnodeAdd(current->left, value);

else

current->right = BSTnodeAdd(current->right, value);

return current;

}

Page 14: CS 261 – Fall 2009 Binary Search Trees Again, but in detail.

Notes on Add•See how it returns the Current value, the tree AFTER the insertion is made

•Again, could be done with a loop - some people find the recursive version easier, some people find the loop easier.

•Try writing it using a loop

Page 15: CS 261 – Fall 2009 Binary Search Trees Again, but in detail.

Bag Implementation: Remove•As is often the case, remove is the most complex. Leaves a “hole”. What value should fill the hole?

Alex

Abner Angela

Adela Alice Audrey

Adam Agnes Allen Arthur

Abigail

Page 16: CS 261 – Fall 2009 Binary Search Trees Again, but in detail.

Who can fill that hole?•Answer: The Leftmost child of the right child. (Smallest element in right subtree)

•Try this on a few values.

•Useful to have a couple of private inner routines

EleType leftmostChild (Node current) {

… // return value of leftmost child of current

}

Struct Node * removeLeftmostChild (Node current) {

… // return tree with leftmost child removed

}

Page 17: CS 261 – Fall 2009 Binary Search Trees Again, but in detail.

One additional special case•We have said you want to fill hole with leftmost child of right child. What if you don’t have a right child? Think about it. Can just return left child. Try remove “Audrey”Angela

Alice Audrey

Allen Arthur

Page 18: CS 261 – Fall 2009 Binary Search Trees Again, but in detail.

Once more, separate root and node

void BSTremove (struct BST * tree, EleType value) {

if (BSTincludes(tree, value)) {

tree->root = BSTnodeRemove (tree->root, value);

tree->size--;

}

}

Page 19: CS 261 – Fall 2009 Binary Search Trees Again, but in detail.

Node Remove: easy if you return a treeNode remove (Node current, EleType testValue)

if current->value is the thing we seek

if right child is null return left child

else replace value with leftmost child of right child

and set right child to be removeLeftmost (right)

else if testValue < current.value

left child = remove (left child, testValue)

else

right child = remove (right child, testValue)

return current node

Page 20: CS 261 – Fall 2009 Binary Search Trees Again, but in detail.

Translate the previous into codestruct BSTnodeRemove (struct node * current, EleType testValue) {

if (EQ(testValue, current->value)) { /* found it! */

if (current->right == 0) return current->left;

else {

current->value = leftmostChild(current->right);

current->right = removeLeftMost (current->right); }

} else if (LT(testValue, current.value))

current->left = BSTnodeRemove (current->left, testValue)

else

current->right = BSTnoderemove (current->right, testValue)

return current;

}

Page 21: CS 261 – Fall 2009 Binary Search Trees Again, but in detail.

Little Helper Routines - get value of lmcEleType leftMostChild (struct node * current) {

while (current->left != 0)

current = current->left;

return current->value;

}

Page 22: CS 261 – Fall 2009 Binary Search Trees Again, but in detail.

Second helper routine - remove leftmoststruct node * removeLeftMost (struct node * current) {

if (current->left == 0)

return current->right;

else

current->left = removeLeftMost (current->left);

return current;

}

Page 23: CS 261 – Fall 2009 Binary Search Trees Again, but in detail.

What is the complexity??Basically once more just running down a path from root to leaf

What is the complexity? O(???)

Careful! What can go wrong? What happens in the worst case??


Recommended