Processing math: 100%
Close
Close Window

CS3 Coursenotes

Chapter 3 Week 4

Show Source |    | About   «  2.2. Binary Trees Part 1   ::   Contents   ::   3.2. Binary Trees Part 3  »

3.1. Binary Trees Part 2

3.1.1. Binary Trees Part 2

3.1.1.1. Full and Complete Binary Trees

Full binary tree: Each node is either a leaf or internal node with exactly two non-empty children.

Complete binary tree: If the height of the tree is d, then all leaves except possibly level d are completely full. The bottom level has all nodes to the left side.

Created with Raphaël 2.1.2
Created with Raphaël 2.1.2
(a)
(b)

3.1.1.2. Full Binary Tree Theorem (1)

Theorem: The number of leaves in a non-empty full binary tree is one more than the number of internal nodes.

Proof (by Mathematical Induction):

Base case: A full binary tree with 1 internal node must have two leaf nodes.

Induction Hypothesis: Assume any full binary tree T containing n1 internal nodes has n leaves.

3.1.1.3. Full Binary Tree Theorem (2)

Induction Step: Given tree T with n internal nodes, pick internal node I with two leaf children. Remove I’s children, call resulting tree T’.

By induction hypothesis, T’ is a full binary tree with n leaves.

Restore I’s two children. The number of internal nodes has now gone up by 1 to reach n. The number of leaves has also gone up by 1.

3.1.1.4. Full Binary Tree Corollary

Theorem: The number of null pointers in a non-empty tree is one more than the number of nodes in the tree.

Proof: Replace all null pointers with a pointer to an empty leaf node. This is a full binary tree.

3.1.1.5. Dictionary

/** The Dictionary abstract class. */
public interface Dictionary {

  /** Reinitialize dictionary */
  public void clear();

  /** Insert a record
      @param key The key for the record being inserted.
      @param elem The record being inserted. */
  public void insert(Comparable key, Object elem);

  /** Remove and return a record.
      @param key The key of the record to be removed.
      @return A maching record. If multiple records match
      "k", remove an arbitrary one. Return null if no record
      with key "k" exists. */
  public Object remove(Comparable key);

  /** Remove and return an arbitrary record from dictionary.
      @return the record removed, or null if none exists. */
  public Object removeAny();

  /** @return A record matching "k" (null if none exists).
      If multiple records match, return an arbitrary one.
      @param key The key of the record to find */
  public Object find(Comparable key);

  /** @return The number of records in the dictionary. */
  public int size();
}

3.1.1.6. .

.

3.1.1.7. Dictionary (2)

  • How can we implement a dictionary?

    • We know about array-based lists and linked lists.

    • They might be sorted or unsorted.

    • What are the pros and cons?

3.1.1.8. Binary Search Trees

Created with Raphaël 2.1.2
A
B
Created with Raphaël 2.1.2
A
B
(a)
(b)
Created with Raphaël 2.1.2
A
B
EMPTY
Created with Raphaël 2.1.2
A
EMPTY
B
(c)
(d)

3.1.1.9. BST as a Dictionary (1)

// Binary Search Tree implementation
class BST {
  private BSTNode root; // Root of the BST
  private int nodecount; // Number of nodes in the BST

  // constructor
  BST() { root = null; nodecount = 0; }

  // Reinitialize tree
  public void clear() { root = null; nodecount = 0; }

  // Insert a record into the tree.
  // Records can be anything, but they must be Comparable
  // e: The record to insert.
  public void insert(Comparable e) {
    root = inserthelp(root, e);
    nodecount++;
  }

3.1.1.10. BST as a Dictionary (2)

  // Remove a record from the tree
  // key: The key value of record to remove
  // Returns the record removed, null if there is none.
  public Comparable remove(Comparable key) {
    Comparable temp = findhelp(root, key); // First find it
    if (temp != null) {
      root = removehelp(root, key); // Now remove it
      nodecount--;
    }
    return temp;
  }

  // Return the record with key value k, null if none exists
  // key: The key value to find
  public Comparable find(Comparable key) { return findhelp(root, key); }

  // Return the number of records in the dictionary
  public int size() { return nodecount; }

3.1.1.11. BST findhelp

1 / 17 Settings
<<<>>>

Consider searching for the record with key value 32 in this tree. We call the findhelp method with a pointer to the BST root (the node with key value 37).

Created with Raphaël 2.1.2
  • private Comparable findhelp(BSTNode rt, Comparable key) {
  • if (rt == null) return null;
  • if (rt.value().compareTo(key) > 0)
  • return findhelp(rt.left(), key);
  • else if (rt.value().compareTo(key) == 0)
  • return rt.value();
  • else return findhelp(rt.right(), key);
  • }
Created with Raphaël 2.1.2
37
24
42
7
32
2
42
120
40
rt
Proficient Saving... Error Saving
Server Error
Resubmit

3.1.1.12. BST inserthelp

1 / 22 Settings
<<<>>>

Consider inserting a record with key value 30 in this tree. We call the inserthelp method with a pointer to the BST root (the node with value 37).

Created with Raphaël 2.1.2
  • private BSTNode inserthelp(BSTNode rt, Comparable e) {
  • if (rt == null) return new BSTNode(e);
  • if (rt.value().compareTo(e) >= 0)
  • rt.setLeft(inserthelp(rt.left(), e));
  • else
  • rt.setRight(inserthelp(rt.right(), e));
  • return rt;
  • }
Created with Raphaël 2.1.2
37
24
42
7
32
2
42
120
40
30
rt
Proficient Saving... Error Saving
Server Error
Resubmit

3.1.1.13. BST deletemax

1 / 6 Settings
<<<>>>

To remove the node with the maximum key value from a subtree, first find that node by starting at the subtree root and continuously move down the right link until there is no further right link to follow.

Created with Raphaël 2.1.2
  • // Delete the maximum valued element in a subtree
  • private BSTNode deletemax(BSTNode rt) {
  • if (rt.right() == null) return rt.left();
  • rt.setRight(deletemax(rt.right()));
  • return rt;
  • }
Created with Raphaël 2.1.2
10
5
20
12
15
rt
Proficient Saving... Error Saving
Server Error
Resubmit

3.1.1.14. BST removehelp

1 / 46 Settings
<<<>>>

Let's look a few examples for removehelp. We will start with an easy case. Let's see what happens when we delete 30 from this tree.

Created with Raphaël 2.1.2
  • private BSTNode removehelp(BSTNode rt, Comparable key) {
  • if (rt == null) return null;
  • if (rt.value().compareTo(key) > 0)
  • rt.setLeft(removehelp(rt.left(), key));
  • else if (rt.value().compareTo(key) < 0)
  • rt.setRight(removehelp(rt.right(), key));
  • else { // Found it
  • if (rt.left() == null) return rt.right();
  • else if (rt.right() == null) return rt.left();
  • else { // Two children
  • BSTNode temp = getmax(rt.left());
  • rt.setValue(temp.value());
  • rt.setLeft(deletemax(rt.left()));
  • }
  • }
  • return rt;
  • }
Created with Raphaël 2.1.2
37
24
42
7
32
2
30
42
120
40
rt
Proficient Saving... Error Saving
Server Error
Resubmit

3.1.1.15. .

.

3.1.1.16. BST Analysis

Find: O(d)

Insert: O(d)

Delete: O(d)

d= depth of the tree

d is O(logn) if the tree is balanced.

What is the worst case cost? When?

   «  2.2. Binary Trees Part 1   ::   Contents   ::   3.2. Binary Trees Part 3  »

Close Window