binary search trees. what’s on the menu? adt dictionarybst & algorithms simulatorcomplexity

Post on 27-Dec-2015

219 Views

Category:

Documents

0 Downloads

Preview:

Click to see full reader

TRANSCRIPT

Binary search trees

What’s on the menu?

ADT Dictionary BST & Algorithms

SimulatorComplexity

Abstract Data Type: Dictionary

We’ve seen two ADTs, or behaviours.

List Stack

add(Object o)

get(int i)

remove(int i)

push(Object o)

peek()

pop()

Let’s look at a 3rd ADT.

Dictionary

Binary Search Trees

Abstract Data Type: Dictionary

We’ve seen two ADTs, or behaviours. Let’s look at a 3rd ADT.

DictionaryWhat’s a dictionary?

A set of keys, each associated with a

value.key

value

Binary Search Trees

Abstract Data Type: Dictionary

public interface Dictionary{

void add(int key, Object value);

void reassign(int key, Object value);

Object remove(int key);

Object lookup(int key);

}

Binary Search Trees

add a new key associated with a value

change the value associated with the key

remove the key (hence the value) and return

the value

return the value associated with the key

Binary Search Trees

Abstract Data Type: Dictionarypublic void example(Dictionary D){

D.add(3, « cheers »);

D.add(5, « salamati »);

System.out.println( _____D.lookup(5));

D.reassign(5, « slàinte »);

System.out.println( _____D.lookup(5));

D.remove(3);

}

Dictionary D

{3, cheers}

{5, salamati}{5, slàinte}

> salamati

> slàinte

Binary Search Trees

An implementation: Binary Search Tree

A binary search tree (BST) is a tree in which a node can have at most two children and the keys into the right subtree of a node c are all greater than the key of c, while the keys in the left subtree are all smaller. 7

5

2

1 3

9

5

4

1

60

8Not a BST: 6 is greater than 4 (and

5) !

In representation, we usually only show the keys. Remember that

they are binded to a value.

Binary Search Trees

Algorithm: add(int key, Object data)The Rule: the keys into the right subtree of a node c are all greater than the key of c, while the keys in the left subtree are all smaller.

16

3

5

add(9, « blabla »);9 < 12

9 > 8

9 < 10

9

12

8

10

add(14, « blabla »);14 > 12

14 < 16

14

Binary Search Trees

Algorithm: add(int key, Object data)The Rule: the keys into the right subtree of a node c are all greater than the key of c, while the keys in the left subtree are all smaller. private void add(Node current, int key, Object data){ if(key>current.getKey()){ if(current.getRightChild()==null){

Node n = new Node(key, data); current.setRightChild(n); }else add(current.getRightChild(),key, data); }else{ if(current.getLeftChild()==null){ Node n = new Node(key, data); current.setLeftChild(n); }else add(current.getLeftChild(),key, data); } }

the key I want to add is higher than the current one,

I go in the right subtree

no right subtree? Then I make a Node and I’m done.

otherwise, go deeper in the tree

similarly, if the key is less or equal then go in the left

subtree

Binary Search Trees

Algorithm: add(int key, Object data)The Rule: the keys into the right subtree of a node c are all greater than the key of c, while the keys in the left subtree are all smaller. private void add(Node current, int key, Object data){ if(key>current.getKey()){ if(current.getRightChild()==null){

Node n = new Node(key, data); current.setRightChild(n); }else add(current.getRightChild(),key, data); }else{ if(current.getLeftChild()==null){ Node n = new Node(key, data); current.setLeftChild(n); }else add(current.getLeftChild(),key, data); } }

public void add(int key, Object data){ if(root==null) root = new Node(key,data); else add(root,key,data); }

In purple, the general case. In blue, when we stop. Below, how we

start.

The algorithm that the user calls is public.

The ‘real’ one private.

Binary Search Trees

Algorithm: lookup(int key)The Rule: the keys into the right subtree of a node c are all greater than the key of c, while the keys in the left subtree are all smaller.

Write the algorithm that returns the data bound to a key.

Steps you should be thinking of:

• what do I do in the general case?

• when do I stop?

• how do I start?

Functions: getRightChild() getLeftChild() getKey() getdata()

If the key is greater than the current, go in the right

subtree; otherwise, go left.

No node: null. Found the key: return the data.

No root: null. Otherwise, start on the root.

Binary Search Trees

Algorithm: lookup(int key)The Rule: the keys into the right subtree of a node c are all greater than the key of c, while the keys in the left subtree are all smaller.

public Object lookup(int key){ if(root==null) return null; return getNode(root, key); } private Object getNode(Node current, int key){ if(current==null) return null; if(current.getKey()==key) return current.getData(); if(key>current.getKey()) return getNode(current.getRightChild(), key); return getNode(current.getLeftChild(), key); }

start

general

stop

Binary Search Trees

Algorithm: lookup(int key)The Rule: the keys into the right subtree of a node c are all greater than the key of c, while the keys in the left subtree are all smaller.

public Object lookup(int key){ if(root==null) return null; return getNode(root, key); } private Object getNode(Node current, int key){ if(current==null) return null; if(current.getKey()==key) return current.getData(); if(key>current.getKey()) return getNode(current.getRightChild(), key); return getNode(current.getLeftChild(), key); }

9

1

lookup(5);

> null

8

4

6

lookup(1);

Binary Search Trees

Algorithm: findMin(Node current)Starting from a given node, return the node with the smallest key.

16

3

1

14

12

8

10 19

23

Strategy: go in the left subtree as long as you can.

If you follow the algorithm, it always goes forward in only one direction, like a

LinkedList.

So it’s not truly recursive, and it can be written in an iterative

fashion.

Binary Search Trees

Algorithm: findMin(Node current)Starting from a given node, return the node with the smallest key.

Strategy: go in the left subtree as long as you can.

private Node findMin( Node t ) { if( t != null ) while( t.getLeftChild() != null) t = t.getLeftChild(); return t;}

16

3

1

14

12

8

10 19

23

Binary Search Trees

Algorithm: remove(int key)

63

41

10

7 12

54 79

37 44 53 59 96

57 91 97

47

32

19

23

30

Case 0: You are removing a node with 0 children (i.e. a leaf).

stolen from John Edgar

Example: removing 30.

Strategy: go to the parent (here 23), and set the node to null.

Binary Search Trees

Algorithm: remove(int key)Case 1: You are removing a node with only one child.

stolen from John Edgar

Example: removing 79.

Strategy: go to the parent (here 63), and replace the node by its subtree.

47

6332

19 41

10 23

7 12

54 79

37 44 53 59 96

30 57 91 97

Binary Search Trees

Algorithm: remove(int key)Case 2: You are removing a node with two children.

stolen from John Edgar

Strategy: replace the node by the minimum in its right subtree.

47

6332

19 41

10 23

7 12

54 79

37 44 53 59 96

30 57 91 97

temp

If we want to remove 32, we need to replace it by one

of its children.

Binary Search Trees

protected Node remove(int key, Node current){ if(current==null) return null; if(key < current.getKey()) current.setLeftChild(remove(key, current.getLeftChild())); else if(key > current.getKey()) current.setRightChild(remove(key,current.getRightChild())); else if(current.getLeftChild() != null && current.getRightChild() != null ) { Node rightMin = findMin(current.getRightChild()); current.setData(rightMin.getData()); current.setKey(rightMin.getKey()); current.setRightChild(removeMin(current.getRightChild())); } else if(current.getLeftChild()==null) current = current.getRightChild(); else current = current.getLeftChild(); return current; }

Algorithm: remove(int key)

locate the node

If there are 2 children then replace by the minimum in

the right subtree, and delete this minimum.

1 child: replace by the subtree0 child: replace by the subtree (which is null…)

Binary Search Trees

Complexity

16

3 17

12

8

10 14

If I’m looking for something, how long can it take at most to find it?

The size of the longest path (root to leaf) is the height h of the tree.

Since I know exactly where I’m going, it takes me at most O(h).

Add/Remove/Lookup are in O(h).

If we’re lucky, the tree is well balanced: every level is full.

Level 1: 1 node.

Level 2: 2 nodes.

Level 3: 4 nodes.

Level 4: 8 nodes.

Level n: 2^n nodes.

h = log n2

Binary Search Trees

Complexity

16

3 17

12

8

10 14

If I’m looking for something, how long can it take at most to find it?

The size of the longest path (root to leaf) is the height h of the tree.

Since I know exactly where I’m going, it takes me at most O(h).

Add/Remove/Lookup are in O(h).

If we’re lucky, the tree is well balanced: every level is full.

h = log n2

3 8 10 12 1614 17

If we’re unlucky, the tree is totally unbalanced, looking like

a LinkedList: h = n.

Binary Search Trees

ComplexityAdd/Remove/Lookup are in O(h).

→ Balanced tree: Add/Remove/Lookup are in O(log n)

→ Unbalanced tree: Add/Remove/Lookup are in O(n)

It is important to keep the tree balanced in order to have the algorithms efficient. We will see different ways to achieve it.

2

If you’re simply asked about the complexity, say O(h). If you have to be more detailed, then distinguish balanced and unbalanced cases.

top related