CS 261 – Winter 2010

16
CS 261 – Winter 2010 Binary Search Trees

description

CS 261 – Winter 2010. Binary Search Trees. Can we do something useful?. How can we make a collection using the idea of a binary tree? How about starting with an implementation of a BAG - PowerPoint PPT Presentation

Transcript of CS 261 – Winter 2010

Page 1: CS 261 – Winter 2010

CS 261 – Winter 2010

Binary Search Trees

Page 2: CS 261 – Winter 2010

Can we do something useful?•How can we make a collection using the idea of a binary tree?

•How about starting with an implementation of a BAG

•Goal: try to make the operations on the collection proportional to the length of a path, rather than the number of elements in the tree.

•First step. A Binary Search Tree.

Page 3: CS 261 – Winter 2010

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 4: CS 261 – Winter 2010

Binary Search Tree: Example

Alex

Abner Angela

Adela Alice Audrey

Adam Agnes Allen Arthur

Abigail

Page 5: CS 261 – Winter 2010

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 6: CS 261 – Winter 2010

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 – Winter 2010

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 8: CS 261 – Winter 2010

Add just calls the utility routine…

void BSTadd (struct BST * tree, EleType newValue) {

root = BSTnodeAdd(tree->root, newValue);

tree->size++;

}

What is the complexity? O( ?? )

Page 9: CS 261 – Winter 2010

Could do it with a loopStruct node * BSTnodeAdd (struct node * current, EleType newValue) {

Struct node * p = current;

If (current == 0) return newNode (newValue, 0, 0);

Else while (p != 0) {

if (newValue < p->value)

if (p->left == 0)

{p->left = newNode(newValue, 0, 0); return;}

else p = p->left;

else

if (p->right == 0)

{ p->right = newNode(newValue, 0, 0); return;}

else p = p->right;

}

return current;

}

Page 10: CS 261 – Winter 2010

newNode makes life a bit easierstruct node * newNode

(EleType newValue, struct node * l, struct node * r)

{

struct node * newnode =

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

assert(newnode != 0);

newnode->value = newValue;

newnode->left = l;

newnode->right = r;

return newnode;

}

Page 11: CS 261 – Winter 2010

An alternative way to look at it•A useful trick (adapted from the functional programming world). Make a secondary routine that returns the tree with the value inserted.

Node add (Node start, EleType newValue) if start 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 – Winter 2010

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 13: CS 261 – Winter 2010

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 internal routines EleType leftmostChild (struct node * current) {

… // return value of leftmost child of current

}struct node * removeLeftmostChild (struct node * current) {

… // return tree with leftmost child removed

}

Page 14: CS 261 – Winter 2010

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 15: CS 261 – Winter 2010

Remove: again easy if you return a treeNode remove (Node current, Object 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 16: CS 261 – Winter 2010

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??

Questions?? Now the worksheet.