1 of 68

Lecture 16-17-18

Binary Trees

Binary Search Trees�Search in BST

2 of 68

Binary Tree

3 of 68

Binary Tree Traversal

4 of 68

5 of 68

6 of 68

7 of 68

Possible?

Give a tree with at least 3 nodes (all nodes must have different keys) such that both its in-order read and its pre-order read are the same, or prove that there is no such tree.

8 of 68

Binary search trees

9 of 68

Binary SEARCH tree

  • A binary search tree (BST) is a binary-tree based data structure that offers O(log n) average-case time costs for:
    • Add(element)
    • Find(element)
    • Remove(element)
    • findLargest/removeLargest(element)

10 of 68

BST

  • Binary Search Tree is a node-based binary tree data structure which has the following properties:
    • The left subtree of a node contains only nodes with keys smaller than the node's key.
    • The right subtree of a node contains only nodes with keys greater than the node's key.

11 of 68

Reminders

  • Mic
  • If main with magic numbers and lost points, let me know (PA04)

12 of 68

13 of 68

14 of 68

15 of 68

16 of 68

17 of 68

CompareTo

18 of 68

compareTo, simplified

  • Allows us to compare Objects: Students, Cars, Apples, Animals…
  • In order to use this method, one needs to let Java know how to compare:

  • If the values are the same then 0 is returned.
  • If one value is less than the argument then the negative integer is returned.
  • If one value is greater than the argument then the positive integer is returned.

19 of 68

Example

public class Test {

public static void main(String args[]) {

Integer x = 5;

System.out.println(x.compareTo(3)); # 1

System.out.println(x.compareTo(5)); # 0

System.out.println(x.compareTo(8)); # -1

}

}

20 of 68

Example

public class Student {

int age;

int compareTo(Student st) {

if this.age == st.age return 0;

if this.age > st.age return 1;

If this.age < st.age return -1;

...

}

}

public static void main(String args[]) {

Student st1 = new Student(19);

Student st2 = new Student(22);

SOS(st1.compareTo(st2)); # -1

21 of 68

BST implementation

22 of 68

23 of 68

24 of 68

25 of 68

26 of 68

27 of 68

28 of 68

29 of 68

30 of 68

31 of 68

Insert

32 of 68

33 of 68

Do we need recursion for the third one?

A: Yes

B: No

34 of 68

35 of 68

36 of 68

37 of 68

38 of 68

Duplicate keys

Allow them and be consistent with the rule

Node is a linked (Array) list. All duplicates are linked.

39 of 68

How to delete an element from a BST

40 of 68

41 of 68

Lazy deletion

42 of 68

Complexity

43 of 68

Complexity

44 of 68

45 of 68

What is the output?

A: 10, 5, 3, 7, 15, 18

B: 3, 5, 7, 10, 15, 18

�C: 3, 7, 5, 18, 15, 10

�D: 3, 5, 7, 15, 10, 18

�E: Something else

46 of 68

Iterators

47 of 68

What is the time complexity?

for (int i = 0; i< linkedlist.size(); i++) {

elem = linkedlist.getElem( i ) ;

print(elem);

}

A: O(1)

B: O(n)

C: O(n log n)

D: O(n^2)

E: Something else

48 of 68

Iterators in Java, performance benefits

  • An “iterator” object helps us to avoid this wasted computation.
  • An iterator is a “helper object” with which the user can iterate across all elements in a data structure.
  • The iterator will “remember” where it left off.
  • Even very different data structures --e.g., graphs and lists -- can both support iterators.
  • Python has them as well

49 of 68

Iterator interface

In Java, the Iterator interface contains three (well, four now) method signatures:

  • boolean hasNext();
  • E next();
  • void remove();

Java documentation

50 of 68

Iterator for a Linked List

import java.util.*;

class IteratorExample {

public static void main(String [] args) {

// Create an linked list

LinkedList <Integer> intList = new LinkedList <>();

for (int i=10; i<20; i++)

intList.add(i);

51 of 68

import java.util.*;

class IteratorExample {

public static void main(String [] args) {

// Create an linked list

LinkedList <Integer> intList = new LinkedList <>();

for (int i=10; i<20; i++)

intList.add(i);

//To start, we need to obtain an Iterator from a Collection; this is done by calling the iterator() method.

// we’ll obtain Iterator instance from a list:

Iterator itr = intList.iterator(); // created the iterator object

52 of 68

import java.util.*;

class IteratorExample {

public static void main(String [] args) {

// Create an linked list

LinkedList <Integer> intList = new LinkedList <>();

for (int i=10; i<20; i++)

intList.add(i);

Iterator itr = intList.iterator(); // created the iterator object

while(itr.hasNext()) {

Object element = itr.next();

System.out.print(element + " ");

}

System.out.println();

  • boolean hasNext();
  • E next();
  • void remove();

53 of 68

import java.util.*;

class IteratorExample {

public static void main(String [] args) {

// Create an linked list

LinkedList <Integer> intList = new LinkedList <>();

for (int i=10; i<20; i++)

intList.add(i);

Iterator itr = intList.iterator(); //created the iterator object

while(itr.hasNext()) {

Object element = itr.next();

System.out.print(element + " ");

}

System.out.println();

10 11 12 13 14 15 16 17 18 19

54 of 68

import java.util.*;

class IteratorExample {

public static void main(String [] args) {

// Create an linked list

LinkedList <Integer> intList = new LinkedList <>();

for (int i=10; i<20; i++)

intList.add(i);

Iterator itr = intList.iterator(); // created the iterator object

while(itr.hasNext()) {

Object element = itr.next();

System.out.print(element + " ");

}

System.out.println();

10 11 12 13 14 15 16 17 18 19

55 of 68

Iterators for other data structures

  • When you develop your own data structure, you want a user to be able to iterate over it.
  • When the data structure is linear (lists, arrays, sets) then it is clear what the next element is.
  • But if you have a tree? Or a graph?

56 of 68

Iterable

interface

57 of 68

Iterable interface

58 of 68

Interface Iterator

  • In Java, the Iterator interface contains three method signatures:

boolean hasNext();

E next();

void remove();

• The ListIterator interface adds a few more methods.

boolean hasPrevious();

E previous();

59 of 68

In HW6

public class BSTree<T extends Comparable<? super T>> implements Iterable

60 of 68

Example: how to create an iterator

To implement an iterable data structure, we need to:

  1. Implement Iterable interface along with its methods in the said Data Structure

61 of 68

Example: how to create an iterator

To implement an iterable data structure, we need to:

  1. Implement Iterable interface along with its methods in the said Data Structure
  2. Create an Iterator class which implements Iterator interface and corresponding methods.
  3. boolean hasNext();
  4. E next();
  5. void remove();

62 of 68

import java.util.*;

public class A implements Iterable{

ArrayList arr = new ArrayList();

public Iterator iterator() {

return new ArrayList_It(); # another object!

}

Iterator: every second item in ArrayList

63 of 68

import java.util.*;

public class A implements Iterable{

ArrayList arr = new ArrayList();

public Iterator iterator() {

return new ArrayList_It(); # another object!}

# inner class

class ArrayList_It implements Iterator{

int cursor;

public ArrayList_It() {

cursor = 0;

}

64 of 68

import java.util.*;

public class A implements Iterable{

ArrayList arr = new ArrayList();

public Iterator iterator() {

return new ArrayList_It(); # another object!}

# inner class

class ArrayList_It implements Iterator{

int cursor;

public ArrayList_It() {

cursor = 0;

}

  • boolean hasNext();
  • E next();
  • void remove();

65 of 68

import java.util.*;

public class A implements Iterable{

ArrayList arr = new ArrayList();

public Iterator iterator() {

return new ArrayList_It(); # another object!}

# inner class

class ArrayList_It implements Iterator{

int cursor;

public ArrayList_It() {

cursor = 0;

}

public boolean hasNext() {

}

  • boolean hasNext();
  • E next();
  • void remove();

66 of 68

import java.util.*;

public class A implements Iterable{

ArrayList arr = new ArrayList();

public Iterator iterator() {

return new ArrayList_It(); # another object!}

# inner class

class ArrayList_It implements Iterator{

int cursor;

public ArrayList_It() {

cursor = 0;

}

public boolean hasNext() {

if (arr.size() == 0)

return false;

}

  • boolean hasNext();
  • E next();
  • void remove();

67 of 68

import java.util.*;

public class A implements Iterable{

ArrayList arr = new ArrayList();

public Iterator iterator() {

return new ArrayList_It(); # another object!}

# inner class

class ArrayList_It implements Iterator{

int cursor;

public ArrayList_It() {

cursor = 0;

}

public boolean hasNext() {

if (arr.size() == 0)

return false;

if (cursor==arr.size()-1)

return true;

if (cursor <= arr.size()-2) // needs to be tested

return true;

else

return false;

}

  • boolean hasNext();
  • E next();
  • void remove();

68 of 68

import java.util.*;

public class A implements Iterable{

ArrayList arr = new ArrayList();

public Iterator iterator() {

return new ArrayList_It(); # another object!}

# inner class

class ArrayList_It implements Iterator{

int cursor;

public ArrayList_It() {

cursor = 0;

}

public Object next() {

int to_return = (Integer) arr.get(cursor);

cursor = cursor + 2;

return to_return;

}

  • boolean hasNext();
  • E next();
  • void remove();