CS61B Homework7作业回顾 (附代码)

发现编程真的是很强调逻辑。首先Track down the whole tree, split 3-key node into 2 node, move the middle element to the parent node. If the parent node is null, then creat a new one. 

然后针对node上keys 的数量进行分类讨论,同时设置position变量用于判断key的插入位置。如果position==0,则插入第一位,以此类推。

/* Tree234.java */

package com.homework7;

/**
 *  A Tree234 implements an ordered integer dictionary ADT using a 2-3-4 tree.
 *  Only int keys are stored; no object is associated with each key.  Duplicate
 *  keys are not stored in the tree.
 *
 *  @author Jonathan Shewchuk
 **/
public class Tree234 extends IntDictionary {

  /**
   *  You may add fields if you wish, but don't change anything that
   *  would prevent toString() or find() from working correctly.
   *
   *  (inherited)  size is the number of keys in the dictionary.
   *  root is the root of the 2-3-4 tree.
   **/
  Tree234Node root;

  /**
   *  Tree234() constructs an empty 2-3-4 tree.
   *
   *  You may change this constructor, but you may not change the fact that
   *  an empty Tree234 contains no nodes.
   */
  public Tree234() {
    root = null;
    size = 0;
  }

  /**
   *  toString() prints this Tree234 as a String.  Each node is printed
   *  in the form such as (for a 3-key node)
   *
   *      (child1)key1(child2)key2(child3)key3(child4)
   *
   *  where each child is a recursive call to toString, and null children
   *  are printed as a space with no parentheses.  Here's an example.
   *      ((1)7(11 16)22(23)28(37 49))50((60)84(86 95 100))
   *
   *  DO NOT CHANGE THIS METHOD.  The test code depends on it.
   *
   *  @return a String representation of the 2-3-4 tree.
   **/
  public String toString() {
    if (root == null) {
      return "";
    } else {
      /* Most of the work is done by Tree234Node.toString(). */
      return root.toString();
    }
  }

  /**
   *  printTree() prints this Tree234 as a tree, albeit sideways.
   *
   *  You're welcome to change this method if you like.  It won't be tested.
   **/
  public void printTree() {
    if (root != null) {
      /* Most of the work is done by Tree234Node.printSubtree(). */
      root.printSubtree(0);
    }
  }

  /**
   *  find() prints true if "key" is in this 2-3-4 tree; false otherwise.
   *
   *  @param key is the key sought.
   *  @return true if "key" is in the tree; false otherwise.
   **/
  public boolean find(int key) {
    Tree234Node node = root;
    while (node != null) {
      if (key < node.key1) {
        node = node.child1;
      } else if (key == node.key1) {
        return true;
      } else if ((node.keys == 1) || (key < node.key2)) {
        node = node.child2;
      } else if (key == node.key2) {
        return true;
      } else if ((node.keys == 2) || (key < node.key3)) {
        node = node.child3;
      } else if (key == node.key3) {
        return true;
      } else {
        node = node.child4;
      }
    }
    return false;
  }

  /**
   *  insert() inserts the key "key" into this 2-3-4 tree.  If "key" is
   *  already present, a duplicate copy is NOT inserted.
   *
   *  @param key is the key sought.
   **/
  public void insert(int key) {
    // Fill in your solution here.
      if (find(key)) return;
      if (root == null){
          root = new Tree234Node(null,key);
          size++;
          return;
      }
      Tree234Node node = root;
      //First, we travel down the tree, if we encounter any 3-key node, we
      // break it up, and move the middle element to its parent
      while (node != null){
          if (node.keys == 3){
              Tree234Node leftNode = new Tree234Node(node.parent,node.key1);
              Tree234Node rightNode = new Tree234Node(node.parent,node.key3);
              if (node.child1 != null){
                  leftNode.child1 = node.child1;
                  node.child1.parent = leftNode;
              }
              if (node.child2 != null){
                  leftNode.child2 = node.child2;
                  node.child2.parent = leftNode;
              }
              if (node.child3 != null){
                  rightNode.child1 = node.child3;
                  node.child3.parent = rightNode;
              }
              if (node.child4 != null){
                  rightNode.child2 = node.child4;
                  node.child4.parent = rightNode;
              }
              //parent node is null
              if (node.parent == null){
                  Tree234Node newRoot = new Tree234Node(null,node.key2);
                  newRoot.child1 = leftNode;
                  newRoot.child2 = rightNode;
                  leftNode.parent = newRoot;
                  rightNode.parent = newRoot;
                  root = newRoot;
              } else {
                  Tree234Node parent = node.parent;
                  int key2 = node.key2;
                  int position;
                  if (key2 < parent.key1){
                      position = 0;
                  } else if(parent.keys == 1 || key2 < parent.key2){
                      position = 1;
                  } else {
                      position = 2;
                  }
                  if (parent.keys == 1){
                      if (position == 0){
                          parent.key2 = parent.key1;
                          parent.key1 = key2;
                          parent.child3 = parent.child2;
                          parent.child2 = rightNode;
                          parent.child1 = leftNode;
                      } else {
                          parent.key2 = key2;
                          parent.child2 = leftNode;
                          parent.child3 = rightNode;
                      }
                  } else if (parent.keys == 2){
                      if (position == 0){
                          parent.key3 = parent.key2;
                          parent.key2 = parent.key1;
                          parent.key1 = key2;
                          parent.child4 = parent.child3;
                          parent.child3 = parent.child2;
                          parent.child2 = rightNode;
                          parent.child1 = leftNode;
                      } else if (position == 1){
                          parent.key3 = parent.key2;
                          parent.key2 = key2;
                          parent.child4 = parent.child3;
                          parent.child3 = rightNode;
                          parent.child2 = leftNode;
                      } else if (position == 2){
                          parent.key3 = key2;
                          parent.child4 = rightNode;
                          parent.child3 = leftNode;
                      }
                  }
                  parent.keys++;

              }
              // track down
              if (key < node.key2){
                  node = leftNode;
              } else {
                  node = rightNode;
              }
          }

          if (isLeaf(node)){
              int position;
              if (key < node.key1){
                  position = 0;
              } else if (node.keys == 1 || key < node.key2){
                  position = 1;
              } else {
                  position = 2;
              }

              if (node.keys == 1){
                  if (position == 0){
                      node.key2 = node.key1;
                      node.key1 = key;
                  } else if (position == 1){
                      node.key2 = key;
                  }
              } else if (node.keys == 2){
                  if (position == 0){
                      node.key3 = node.key2;
                      node.key2 = node.key1;
                      node.key1 = key;
                  } else if (position == 1){
                      node.key3 = node.key2;
                      node.key2 = key;
                  } else if (position == 2){
                      node.key3 = key;
                  }
              }
              node.keys++;
              size++;
              return;
          } else{
              if (key < node.key1){
                  node = node.child1;
              } else if (node.keys == 1 || key < node.key2){
                  node = node.child2;
              } else {
                  node = node.child3;
              }
          }
      }
  }

  public boolean isLeaf(Tree234Node node){
//      if (node.child1 == null) return true;
//      return false;
      return (node.child1 == null);
  }


  /**
   *  testHelper() prints the String representation of this tree, then
   *  compares it with the expected String, and prints an error message if
   *  the two are not equal.
   *
   *  @param correctString is what the tree should look like.
   **/
  public void testHelper(String correctString) {
    String treeString = toString();
    System.out.println(treeString);
    if (!treeString.equals(correctString)) {
      System.out.println("ERROR:  Should be " + correctString);
    }
  }

  /**
   *  main() is a bunch of test code.  Feel free to add test code of your own;
   *  this code won't be tested or graded.
   **/
  public static void main(String[] args) {
    Tree234 t = new Tree234();

    System.out.println("\nInserting 84.");
    t.insert(84);
    t.testHelper("84");

    System.out.println("\nInserting 7.");
    t.insert(7);
    t.testHelper("7 84");

    System.out.println("\nInserting 22.");
    t.insert(22);
    t.testHelper("7 22 84");

    System.out.println("\nInserting 95.");
    t.insert(95);
    t.testHelper("(7)22(84 95)");

    System.out.println("\nInserting 50.");
    t.insert(50);
    t.testHelper("(7)22(50 84 95)");

    System.out.println("\nInserting 11.");
    t.insert(11);
    t.testHelper("(7 11)22(50 84 95)");

    System.out.println("\nInserting 37.");
    t.insert(37);
    t.testHelper("(7 11)22(37 50)84(95)");

    System.out.println("\nInserting 60.");
    t.insert(60);
    t.testHelper("(7 11)22(37 50 60)84(95)");

    System.out.println("\nInserting 1.");
    t.insert(1);
    t.testHelper("(1 7 11)22(37 50 60)84(95)");

    System.out.println("\nInserting 23.");
    t.insert(23);
    t.testHelper("(1 7 11)22(23 37)50(60)84(95)");

    System.out.println("\nInserting 16.");
    t.insert(16);
    t.testHelper("((1)7(11 16)22(23 37))50((60)84(95))");

    System.out.println("\nInserting 100.");
    t.insert(100);
    t.testHelper("((1)7(11 16)22(23 37))50((60)84(95 100))");

    System.out.println("\nInserting 28.");
    t.insert(28);
    t.testHelper("((1)7(11 16)22(23 28 37))50((60)84(95 100))");

    System.out.println("\nInserting 86.");
    t.insert(86);
    t.testHelper("((1)7(11 16)22(23 28 37))50((60)84(86 95 100))");

    System.out.println("\nInserting 49.");
    t.insert(49);
    t.testHelper("((1)7(11 16)22(23)28(37 49))50((60)84(86 95 100))");

    System.out.println("\nInserting 81.");
    t.insert(81);
    t.testHelper("((1)7(11 16)22(23)28(37 49))50((60 81)84(86 95 100))");

    System.out.println("\nInserting 51.");
    t.insert(51);
    t.testHelper("((1)7(11 16)22(23)28(37 49))50((51 60 81)84(86 95 100))");

    System.out.println("\nInserting 99.");
    t.insert(99);
    t.testHelper("((1)7(11 16)22(23)28(37 49))50((51 60 81)84(86)95(99 100))");

    System.out.println("\nInserting 75.");
    t.insert(75);
    t.testHelper("((1)7(11 16)22(23)28(37 49))50((51)60(75 81)84(86)95" +
                 "(99 100))");

    System.out.println("\nInserting 66.");
    t.insert(66);
    t.testHelper("((1)7(11 16)22(23)28(37 49))50((51)60(66 75 81))84((86)95" +
                 "(99 100))");

    System.out.println("\nInserting 4.");
    t.insert(4);
    t.testHelper("((1 4)7(11 16))22((23)28(37 49))50((51)60(66 75 81))84" +
                 "((86)95(99 100))");

    System.out.println("\nInserting 80.");
    t.insert(80);
    t.testHelper("(((1 4)7(11 16))22((23)28(37 49)))50(((51)60(66)75" +
                 "(80 81))84((86)95(99 100)))");

    System.out.println("\nFinal tree:");
    t.printTree();
  }

}

猜你喜欢

转载自blog.csdn.net/everest115/article/details/79725704