// Source code example for "A Practical Introduction // to Data Structures and Algorithm Analysis" // by Clifford A. Shaffer, Prentice Hall, 1998. // Copyright 1998 by Clifford A. Shaffer public class TTtree { // 2-3 Tree node class. Similar to BST in capabilities. private TTNode root; public TTtree() { root = null; } public void clear() { root = null; } public void insert(Elem it) { System.out.println("Insert: " + it); int retval; // Smallest value in newly created node TTNode retptr = null; // Newly created node Object[] temp = inserthelp(root, it); if (root == null) root = (TTNode)temp[0]; else if (temp != null) // Root overflowed: make new root root = new TTNode((Elem)temp[0], null, root, (TTNode)temp[1], null); } public void remove(int key) { } public Elem find(int key) { return findhelp(root, key); } public boolean isEmpty() { return root == null; } public void print() { if (root == null) System.out.print("The 2-3 Tree is empty."); else printhelp(root, 0); } private Object[] inserthelp(TTNode rt, Elem val) { // Do insert if (rt == null) { // Empty tree. rt = new TTNode(val, null, null, null, null); Object[] temp = {rt}; return temp; } if (rt.isLeaf()) // At leaf node -- insert here if (rt.numKeys() == 1) // Easy case { rt.addKey(val, null); return null; } else return splitnode(rt, val, null); // Now at Internal node Object[] retval; // Hold result from insert if (val.key() < rt.lkey().key()) retval = inserthelp(rt.lchild(), val); else if((rt.numKeys() == 1) || (val.key() < rt.rkey().key())) retval = inserthelp(rt.cchild(), val); else retval = inserthelp(rt.rchild(), val); if (retval == null) return null; // No split of child node // If here, child node split if (rt.numKeys() == 1) { // Just add to rt rt.addKey((Elem)retval[0], (TTNode)retval[1]); return null; // No further splitting } // Split this node as well return splitnode(rt, (Elem)retval[0], (TTNode)retval[1]); } // Split a node into two; return info on promoted value Object[] splitnode(TTNode rt, Elem val, TTNode child) { Object[] temp = new Object[2]; // Store info to be returned if (val.key() > rt.rkey().key()) { // Val is rightmost temp[0] = rt.rkey(); // Promote old right key TTNode hold = rt.rchild(); rt.setRkey(null); // Clear it temp[1] = new TTNode(val, null, hold, child, null); } else if (val.key() > rt.lkey().key()) { // Middle temp[0] = val; // Promote val temp[1] = new TTNode(rt.rkey(), null, child, rt.rchild(), null); rt.setRkey(null); // Clear it } else { // Val is leftmost temp[0] = rt.lkey(); // Promote old left key temp[1] = new TTNode(rt.rkey(), null, rt.cchild(), rt.rchild(), null); rt.setCenter(child); rt.setLkey(val); rt.setRkey(null); // Clear it } return temp; // Return promoted element and its subtree } private Elem findhelp(TTNode root, int val) { if (root == null) return null; // val not found if (val == root.lkey().key()) return root.lkey(); // val found if ((root.numKeys() == 2) && (val == root.rkey().key())) return root.rkey(); if (val < root.lkey().key()) // Search left subtree return findhelp(root.lchild(), val); else if (root.numKeys() == 1) // Search center subtree return findhelp(root.cchild(), val); else if (val < root.rkey().key()) // Search center subtree return findhelp(root.cchild(), val); else return findhelp(root.rchild(), val); // Search right } private void printhelp(TTNode rt, int level) { for (int i=1; i<=level; i++) System.out.print(" "); if (rt == null) { System.out.println("null"); return; } System.out.println(rt); if (rt.isLeaf()) return; printhelp(rt.lchild(), level+1); printhelp(rt.cchild(), level+1); printhelp(rt.rchild(), level+1); } }