*** Filename:TwoThreetree.java
Associated java files: NodeGUI.java, Mystack.java,
TreeGUI.java
Compiler : JDK 1.1.4
*** °ú ¸ñ : ÈÀÏ󸮷Ð
*** ´ã´ç±³¼ö : ¹Ú¿µ¹è
*** ¸íÁö´ëÇб³ ÄÄÇ»ÅͰøÇаú 3Çг⠹ÎÁ¤½Ä
*** E-Mail : mxxk@uriel.net
*** Execute on(Refe. to) http://www.uriel.net/~mxxk/File/btree.html
*** **********************************************************************/
import java.util.Stack;
public class TwoThreetree {
node23 tree[];
int y, a, t, stackindex, size;
Mystack parentstack;
static final int NIL = -1;
static final int SUCCESS = 1;
static final int FAIL = 0;
// Constructor
public TwoThreetree (int msize) {
tree = new node23[msize + 1];
size = msize;
t = NIL;
stackindex = 1;
for (int i = 1; i <= size; i++) {
tree[i] = new node23();
tree[i].Rdata = tree[i].Ldata = 0;
tree[i].left = NIL;
tree[i].middle = NIL;
tree[i].right = NIL;
}
}
public boolean Insert23 (int key) {
parentstack = new Mystack(size/2);
int p; boolean NotDone;
if (t == NIL) {
NewRoot(t, key, NIL);
return true;
}
else {
p = FindNode(key);
if (p == NIL) {
System.out.println("Insert23(), key is already in the tree");
return false;
}
else { // key is not in the tree
a = NIL; NotDone = true; y = key;
while (NotDone) {
if (tree[p].Rdata == 0) {
PutIn(p, y, a);
NotDone = false;
}
else {
Split(p, y, a);
if (p == t) {
NewRoot(t, y, a);
NotDone = false;
}
else
p = parentstack.pop();
}
}
parentstack.clear();
}
return true;
}
}
public boolean Search23(int key) {
int p;
boolean NotDone;
if (t == NIL) {
return false;
}
else {
p = t; NotDone = true;
while((NotDone) && (p != NIL))
{
if((tree[p].Ldata == key) || (tree[p].Rdata == key))
NotDone = false;
else if(tree[p].Ldata > key)
p = tree[p].left;
else if(tree[p].Ldata < key) {
if(tree[p].Rdata == 0)
p = tree[p].middle;
else {
if(tree[p].Rdata < key)
p = tree[p].right;
else
p = tree[p].middle;
}
}
else
;
}
if(NotDone == true) {
return false;
}
else
return true;
}
}
public void Split (int p, int key, int b) {
int x;
x = stackindex; stackindex++;
// 1) ۰¡ °¡ÀåŬ°æ¿ì
if (tree[p].Rdata < key) {
tree[x].Ldata = key;
tree[x].middle = b;
tree[x].left = tree[p].right;
y = tree[p].Rdata;
}
else {
tree[x].Ldata = tree[p].Rdata;
tree[x].middle = tree[p].right;
// 2) ۰¡ Áß°£°ªÀÏ °æ¿ì
if (tree[p].Ldata < key ) {
tree[x].left = b;
y = key;
}
// 3) ۰¡ Á¦ÀÏ ÀÛÀº°æ¿ì
else {
tree[x].left = tree[p].middle;
y = tree[p].Ldata;
tree[p].Ldata = key;
tree[p].middle = b;
}
}
tree[p].Rdata = 0;
tree[p].right = NIL;
a = x;
}
public void PutIn (int p, int key, int k) {
if (tree[p].Ldata < key) {
tree[p].Rdata = key;
tree[p].right = k;
}
else {
// moving element and pointer
tree[p].Rdata = tree[p].Ldata;
tree[p].right = tree[p].middle;
tree[p].Ldata = key;
tree[p].middle = k;
}
}
public int FindNode (int key) {
int p;
p = t;
while(p != NIL) {
if((tree[p].Ldata == key) || (tree[p].Rdata
== key)) {
parentstack.push(p);
return NIL;
}
if(tree[p].Ldata > key) {
parentstack.push(p); // Root¿¡¼ 'p'·ÎÀÇ °æ·Î¸¦ À¯ÁöÇÑ´Ù
p = tree[p].left;
}
else if((tree[p].Ldata < key) &&
(tree[p].Rdata == 0)) {
parentstack.push(p);
p = tree[p].middle;
}
else if((tree[p].Ldata < key) &&
(tree[p].Rdata > key)) {
parentstack.push(p);
p = tree[p].middle;
}
else {
parentstack.push(p);
p = tree[p].right;
}
}
return (parentstack.pop());
}
public void NewRoot( int x, int k, int z) {
int p;
p = stackindex; stackindex++;
tree[p].Ldata = k;
tree[p].left = x;
tree[p].middle = z;
t = p;
}
public boolean Delete23 (int key) {
int p, q, r;
boolean NotDone = true;
parentstack = new Mystack(size/2);
if((p = FindNode(key)) != NIL) {
System.out.println("Delete23(), key:"
+ key + " is not in the tree");
return false;
}
else {
p = parentstack.pop();
if(tree[p].left != NIL) {// `p' °¡ non-leaf³ëµå¸¦
°¡¸£Å´
p = FindLeafnode(p, key);// 'p'´Â ÀÌÁ¨ leaf node¸¦ Æ÷ÀÎÆÃÇÔ
if (tree[p].Rdata == 0) // ³»ºÎ³ëµå´ë½Å ¸®ÇÁ³ëµå¸¦ »èÁ¦ÇÔ
key = tree[p].Ldata;
else
key = tree[p].Rdata;
}
if(key == tree[p].Ldata)
// ¸®ÇÁ³ëµå¿¡ ÀÖ´Â ¿ø¼Ò¸¦ »èÁ¦
if(tree[p].Rdata != 0) {
tree[p].Ldata = tree[p].Rdata;
tree[p].Rdata = 0;
NotDone = false;
}
else
tree[p].Ldata = 0;
else {
tree[p].Rdata = 0;
NotDone = false;
}
if (tree[t].Ldata == 0) // ÀÌÁ¨ ºóÆ®¸®À϶§
NotDone = false;
while (NotDone == true) {
r = parentstack.pop(); // ·ÎÅ×ÀÌÆ®¿Í °áÇÕÀ»À§ÇÑ
Æ÷ÀÎÅÍ ¼ÂÆÃ
if(tree[r].middle == p)
q = tree[r].left;
else
q = tree[r].middle;
if(tree[q].Rdata != 0) {
Rotate(p, q, r);
NotDone = false;
}
else {
Combine(p, q, r);
if(tree[r].Ldata != 0)
NotDone = false;
else {
if(r == t) {
if (tree[r].left == p)
t = p;
else
t = q;
NotDone = false;
}
else
p = r;
}
}
}
parentstack.clear();
}
return true;
}
public int FindLeafnode(int ptr, int key) {
int p, q;
boolean Lnode;
p = ptr;
if(tree[ptr].Ldata == key) {
parentstack.push(p);
p = tree[p].left;
Lnode = true;
}
else {
parentstack.push(p);
p = tree[p].middle;
Lnode = false;
}
q = p;
while(p != NIL) {
if(tree[p].Rdata == 0) {
q = p;
parentstack.push(p);
p = tree[p].middle;
}
else {
q = p;
parentstack.push(p);
p = tree[p].right;
}
}
if(tree[q].Rdata != 0) {
if(Lnode)
tree[ptr].Ldata = tree[q].Rdata;
else
tree[ptr].Rdata = tree[q].Rdata;
}
else
if(Lnode)
tree[ptr].Ldata = tree[q].Ldata;
else
tree[ptr].Rdata = tree[q].Ldata;
return (parentstack.pop());
}
public void Rotate(int p, int q, int r) {
// ¼¼°¡Áö °æ¿ì¸¦ °®´Â´Ù,
// 1) `p' ´Â 'r'ÀÇ ¿ÞÂÊÀÚ½Ä ³ëµåÀÌ´Ù
// 2) `p' ´Â 'r'ÀÇ Áß¾ÓÀÚ½Ä ³ëµåÀÌ´Ù
// 3) 'p' ´Â 'r'ÀÇ ¿À¸¥ÂÊÀÚ½Ä ³ëµåÀÌ´Ù
// case #1
if(p == tree[r].left) {
tree[p].Ldata = tree[r].Ldata;
tree[p].middle = tree[q].left;
tree[r].Ldata = tree[q].Ldata;
tree[q].Ldata = tree[q].Rdata;
tree[q].left = tree[q].middle;
tree[q].middle = tree[q].right;
}
// case #2
else if(p == tree[r].middle) {
tree[p].Ldata = tree[r].Ldata;
tree[p].middle = tree[p].left;
tree[p].left = tree[q].right;
tree[r].Ldata = tree[q].Rdata;
}
// case #3
else {
tree[p].Ldata = tree[r].Rdata;
tree[p].middle = tree[p].left;
tree[p].left = tree[q].right;
tree[r].Rdata = tree[q].Rdata;
}
tree[q].Rdata = 0;
tree[q].right = NIL;
}
public void Combine(int p, int q, int r) {
// case #1
if (p == tree[r].left) {
tree[p].Ldata = tree[r].Ldata;
tree[p].Rdata = tree[q].Ldata;
tree[p].middle = tree[q].left;
tree[p].right = tree[q].middle;
Dispose(tree[r].middle);
tree[r].Ldata = tree[r].Rdata;
tree[r].middle = tree[r].right;
}
// case #2
else if (p == tree[r].middle) {
tree[q].Rdata = tree[r].Ldata;
tree[q].right = tree[p].left;
tree[r].Ldata = tree[r].Rdata;
Dispose(tree[r].middle);
tree[r].middle = tree[r].right;
}
// case #3
else {
tree[q].Rdata = tree[r].Rdata;
tree[q].right = tree[p].left;
Dispose(tree[r].right);
}
tree[r].Rdata = 0;
tree[r].right = NIL;
}
public void Dispose(int ptr) {
tree[ptr].Ldata = 0;
tree[ptr].Rdata = 0;
tree[ptr].right = NIL;
tree[ptr].middle = NIL;
tree[ptr].left = NIL;
}
public String print(int level, int ptr) {
StringBuffer tmp = new StringBuffer();
String p = "";
if(ptr == NIL){
return p;
}
for(int i = 0; i < level; i++)
tmp.append("\t.");
tmp.append("\t" + tree[ptr].Ldata + "," + tree[ptr].Rdata
+"\n");
tmp.append(print(level+1, tree[ptr].left));
tmp.append(print(level+1, tree[ptr].middle));
tmp.append(print(level+1, tree[ptr].right));
return tmp.toString();
}
public boolean isempty()
{
if (t == NIL)
{
System.out.print("true\n");
return true;
}
else
{
System.out.print("false\n");
return false;
}
}
public void empty()
{
t = NIL;
stackindex =1;
}
public void cons(int i, TwoThreetree l, TwoThreetree r)
{
int lpos = stackindex+1;
int rpos = stackindex+2;
NewRoot(lpos,i,rpos);
tree[lpos] = l.tree[l.t];
tree[rpos] = r.tree[r.t];
stackindex+=2;
}
public void cons2(int i, int j, TwoThreetree l, TwoThreetree
m, TwoThreetree r)
{
int lpos = stackindex+1;
int mpos = stackindex+2;
int rpos = stackindex+3;
NewRoot(lpos,i,mpos);
tree[t].Rdata = j;
tree[t].right = rpos;
tree[lpos] = l.tree[l.t];
tree[mpos] = m.tree[m.t];
tree[rpos] = r.tree[r.t];
stackindex+=3;
}
// pre: ·çÆ®¿¡¼ ÇÑ ItemÀ» °®´Â ÇÑÆ®¸®¸¦ ÃëÇÔ
// post: ·çÆ®¿¡¼ Data Item ¹Ýȯ
public int root()
{
if ((t == NIL) || (tree[t].Rdata > 0)) // ºñ¾îÀְųª
·çÆ®¿¡¼ µÎ°³ÀÇItemÀÏ °æ¿ì
{
System.out.print("error\n");
return -1;
}
else // ·çÆ®¿¡¼ ÇϳªÀÇ ItemÀÏ °æ¿ì
{
System.out.print(tree[t].Ldata+"\n");
return tree[t].Ldata;
}
}
// pre: ·çÆ®¿¡¼ ÇÑ ItemÀ» °®´Â ÇÑÆ®¸®¸¦ ÃëÇÔ
// post: ·çÆ®¿¡¼ Data Item ¹Ýȯ
public int first()
{
if ((t == NIL) || (tree[t].Rdata ==0)) // ºñ¾îÀְųª
·çÆ®¿¡¼ ÇѰ³ÀÇItemÀÏ °æ¿ì
{
System.out.print("error\n");
return -1;
}
else // ·çÆ®¿¡¼ µÎ°³ÀÇ ¾ÆÀÌÅÛÀϰæ¿ì
{
System.out.print(tree[t].Ldata+"\n");
return tree[t].Ldata; // ·çÆ®¿¡¼
ù¹øÂ° ¾ÆÀÌÅÛ ¹Ýȯ
}
}
// pre: ·çÆ®¿¡¼ µÎ°³ÀÇ ItemÀ» °®´Â ÇÑÆ®¸®¸¦ ÃëÇÔ
// post: ·çÆ®¿¡¼ µÎ¹ø»©Item ¹Ýȯ
public int second()
{
if ((t == NIL) || (tree[t].Rdata ==0)) // ºóÆ®¸®À̰ųª
·çÆ®¿¡¼ ÇϳªÀÇ ¾ÆÀÌÅÛ¸¸ Àִ°æ¿ì
{
System.out.print("error\n");
return -1;
}
else // two items at its root
{
System.out.print(tree[t].Rdata+"\n");
return tree[t].Rdata; // ·çÆ®¿¡¼
ù¹øÂ° ¾ÆÀÌÅÛ ¹Ýȯ
}
}
// returns the left subtree
public void left()
{
if (t == NIL) // ºóÆ®¸®ÀÌ¸é ¿¡·¯Ãâ·Â
System.out.print("error\n");
else
System.out.print(print(0,tree[t].left)); // ¿ÞÂÊ
¼ºêÆ®¸®¸¦ º¸¿©ÁÜ
}
// ¿À¸¥ÂÊ ¼ºêÆ®¸® ¹Ýȯ
public void right()
{
if (t == NIL) // eºóÆ®¸®ÀÌ¸é ¿¡·¯Ãâ·Â
System.out.print("error\n");
else if (tree[t].Rdata ==0) // ¸¸ÀÏ ºÎ¸ð¿¡¼ ÇϳªÀÇ ¾ÆÀÌÅÛÀ̶ó¸é
Áß°£Æ®¸®´Â ¿À¸¥ÂÊ Æ®¸®´Ù
System.out.print(print(0,tree[t].middle));
// ¿À¸¥ÂÊ ¼ºê¿Í »óµîÇÏ´Â ¼ºêÆ®¸® display
else
System.out.print(print(0,tree[t].right));
// ¿À¸¥ÂÊ ¼ºêÆ®¸® display
}
// returns the middle subtree
public void middle()
{
if (t == NIL || tree[t].Rdata == 0) // ºñ¾îÀְųª 1¾ÆÀÌÅÛ³ëµåÀ̸é
¿À·ùÁ¦°ø
System.out.print("error\n");
else
System.out.print(print(0,tree[t].middle));
// Áß°£ ¼ºêÆ®¸® display
}
// 1À̳ª 2¹Ýȯ
public int numvals()
{
if (t == NIL) // ºóÆ®¸®
{
System.out.print("error\n");
return -1;
}
else if (tree[t].Rdata == 0) // 1À̸é 1¸®ÅÏ
{
System.out.print(1+"\n");
return 1;
}
else // ·çÆ®¿¡¼ 2°³ÀÇ ¾ÆÀÌÅÛÀ̸é 2¸¦ ¸®ÅÏ
{
System.out.print(2+"\n");
return 2;
}
}
public static void main (String args[]) {
// 5 trees
TwoThreetree treea = new TwoThreetree(10);
TwoThreetree treeb = new TwoThreetree(10);
TwoThreetree treec = new TwoThreetree(10);
TwoThreetree treed = new TwoThreetree(10);
TwoThreetree sometree = new TwoThreetree(10);
treeb.Insert23(3); // construct a tree
treec.Insert23(12);
treed.Insert23(20);
// testing isempty, root, first, second
left rigth middle
// and testing numvals on empty
treea.empty();
System.out.print("isempty empty = ");
treea.isempty();
System.out.print("root empty = ");
treea.root();
System.out.print("first empty = ");
treea.first();
System.out.print("second empty = ");
treea.second();
System.out.print("left empty = ");
treea.left();
System.out.print("right empty = ");
treea.right();
System.out.print("middle empty = ");
treea.middle();
System.out.print("numvals empty = ");
treea.numvals();
// testing isempty, root, first, second left
rigth middle
// and testing numbals on (cons i l r)
treea.cons(5,treeb, treec);
System.out.print("\n\nDisplay of tree: cons(5,
treeb, treec)\n");
System.out.print(treea.print(0,treea.t));
System.out.print("\nisempty (cons 5 treeb
treec) = ");
treea.isempty();
System.out.print("root (cons 5 treeb treec)
= ");
treea.root();
System.out.print("first (cons 5 treeb treec)
= ");
treea.first();
System.out.print("second (cons 5 treeb treec)
= ");
treea.second();
System.out.print("left (cons 5 treeb treec)
= ");
treea.left();
System.out.print("right (cons 5 treeb treec)
= ");
treea.right();
System.out.print("middle (cons 5 treeb treec)
= ");
treea.middle();
System.out.print("numvals (cons 5 treeb treec)
= ");
treea.numvals();
// testing isempty, root, first, second left
rigth middle
// and testing numbals on (cons2 i j l m r)
treea.cons2(5,18,treeb, treec,treed);
System.out.print("\n\nDisplay of tree: cons(5,18,treeb,treec,treed)\n");
System.out.print(treea.print(0,treea.t));
System.out.print("\nisempty (cons2 5 18 treeb
treec treed) = ");
treea.isempty();
System.out.print("root (cons2 5 18 treeb treec
treed) = ");
treea.root();
System.out.print("first (cons2 5 18 treeb
treec treed) = ");
treea.first();
System.out.print("second (cons2 5 18 treeb
treec treed) = ");
treea.second();
System.out.print("left (cons2 5 18 treeb treec
treed) = ");
treea.left();
System.out.print("right (cons2 5 18 treeb
treec treed) = ");
treea.right();
System.out.print("middle (cons2 5 18 treeb
treec treed) = ");
treea.middle();
System.out.print("numvals (cons2 5 18 treeb
treec treed) = ");
treea.numvals();
}
}
class node23 {
int Ldata, Rdata;
int right, middle, left;
}