/* *************************************************************************
*** Filename:TreeGUI.java
Associated java files: NodeGUI.java, TwoThreetree.java,
Mystack.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.applet.*;
import java.awt.*;
import java.lang.*;
import java.util.Random;
public class TreeGUI extends Applet
{
// Constant variables
// 넓이(WIDTH)와 높이(HEIGHT)를 변형할수 있다
static final int TREESIZE = 40;
static final int WIDTH = 30;
static final int HEIGHT = 20;
static final int X_POS = WIDTH+4;
static final int Y_POS = HEIGHT+40;
// Global variables
private Font font;
Button insButton, delButton, clearButton, randTreeButton,
srchButton;
TextField number; // 사용자에게 삽입 삭제키를 입력할수
있도록 함
NodeGUI tree[];
TextArea comment;
TwoThreetree k = new TwoThreetree(100);
int nodearray[];
int MAXLEVEL = 20;
int nodepos[] = new int[MAXLEVEL];
int index = 0;
int thekey = -1; // 검색이나 삭제를 위한 사용자의 key선택
int hi_key = -1; // 키를 잘 보이도록 표시함
Random randGen = new Random();
public void init()
{
// 표시영역의 크기
resize(X_POS*27, Y_POS*7);
int i;
// 객체의 포트 초기화
font = new Font("Helvetica", Font.PLAIN,
10);
// 사용자 인터페이스를 위한 그래픽인터페이스
초기화
randTreeButton = new Button(" 마구잡이
");
insButton = new Button(" 삽입 ");
delButton = new Button(" 삭제 ");
clearButton = new Button(" 깨끗히 ");
srchButton = new Button(" 검색 ");
number = new TextField(15);
number.setText("");
comment = new TextArea("",7,35);
add(randTreeButton);
add(insButton);
add(delButton);
add(number);
add(srchButton);
add(clearButton);
add(comment);
// 트리를 포기화 하고 노드를 균형있도록
할당함
tree = new NodeGUI[TREESIZE];
tree[0] = new NodeGUI(13*X_POS, 3*Y_POS,
WIDTH, HEIGHT, false);
tree[1] = new NodeGUI(4*X_POS, 4*Y_POS,
WIDTH, HEIGHT, false);
tree[2] = new NodeGUI(13*X_POS, 4*Y_POS,
WIDTH, HEIGHT, false);
tree[3] = new NodeGUI(22*X_POS, 4*Y_POS,
WIDTH, HEIGHT, false);
tree[4] = new NodeGUI(1*X_POS, 5*Y_POS,
WIDTH, HEIGHT, false);
tree[5] = new NodeGUI(4*X_POS, 5*Y_POS,
WIDTH, HEIGHT, false);
tree[6] = new NodeGUI(7*X_POS, 5*Y_POS,
WIDTH, HEIGHT, false);
tree[7] = new NodeGUI(10*X_POS, 5*Y_POS,
WIDTH, HEIGHT, false);
tree[8] = new NodeGUI(13*X_POS, 5*Y_POS,
WIDTH, HEIGHT, false);
tree[9] = new NodeGUI(16*X_POS, 5*Y_POS,
WIDTH, HEIGHT, false);
tree[10] = new NodeGUI(19*X_POS, 5*Y_POS,
WIDTH, HEIGHT, false);
tree[11] = new NodeGUI(22*X_POS, 5*Y_POS,
WIDTH, HEIGHT, false);
tree[12] = new NodeGUI(25*X_POS, 5*Y_POS,
WIDTH, HEIGHT, false);
for (i=0; i<27; i++)
tree[i+13] = new NodeGUI(i*X_POS,
6*Y_POS, WIDTH, HEIGHT, false);
// 증가될 노드숫자를 저장하고있는 노드 배열을 초기화함
nodearray = new int[TREESIZE];
comment.appendText("File Structure\n");
comment.appendText("B-Tree\n");
comment.appendText("MungJi University.\n");
comment.appendText("Dep. of Computer
enginerring.\n");
comment.appendText("By JungSig Min,
3th\n");
comment.appendText("-----------------------------\n");
ReInit();
}
public void paint(Graphics g)
{
int node;
String val1;
String val2;
g.setColor(this.getBackground());
g.fillRect(0, 3*Y_POS, X_POS*27, Y_POS*7);
g.setColor(Color.black);
for (int j = 0; nodearray[j]>-1; j++)
{
g.setColor(Color.black);
node=nodearray[j];
if (node ==
0)
g.drawRect(tree[0].x, tree[0].y, tree[0].width, tree[0].height);
else
{
g.drawRect(tree[node].x, tree[node].y,
tree[node].width, tree[node].height);
//
g.setColor(Color.green);
g.drawLine(tree[(node+2)/3-1].x + WIDTH/2, tree[(node+2)/3-1].y + HEIGHT,
tree[node].x + WIDTH/2, tree[node].y);
}
// 노드에 저장된
정수형변수 표시
g.setFont(font);
g.setColor(Color.blue);
val1 = String.valueOf(tree[node].lvalue);
if(tree[node].lvalue
<= 9) val1 = " "+val1;
if (tree[node].rvalue
== 0)
val2="-";
else
val2 = String.valueOf(tree[node].rvalue);
if(tree[node].rvalue <= 9) val2 = " "+val2;
if(tree[node].lvalue
== hi_key) // 왼쪽값을 강조 표시함
{
g.drawString(" ,"+val2, tree[node].x+2,tree[node].y+HEIGHT*2/3);
g.setColor(Color.red);
g.drawString(val1, tree[node].x+2, tree[node].y+HEIGHT*2/3);
hi_key = -1;
}
else if(tree[node].rvalue
== hi_key) // 오른쪽값을 강조 표시함
{
g.setColor(Color.red);
g.drawString("
"+val2, tree[node].x+2,tree[node].y+HEIGHT*2/3);
g.setColor(Color.blue);
g.drawString(val1+",", tree[node].x+2, tree[node].y+HEIGHT*2/3);
hi_key = -1;
}
else
g.drawString(val1+","+val2,tree[node].x+2,tree[node].y+HEIGHT*2/3);
}
}
public boolean action(Event event, Object arg)
{
if (event.target == clearButton)
{
Graphics g = this.getGraphics();
g.setColor(this.getBackground());
g.fillRect(0, 3*Y_POS,
X_POS*27, Y_POS*7);
comment.setText("");
comment.appendText("File
Structure\n");
comment.appendText("B-Tree\n");
comment.appendText("MungJi
University.\n");
comment.appendText("Dep.
of Computer enginerring.\n");
comment.appendText("By
JungSig Min, 3th\n");
comment.appendText("-----------------------------\n");
comment.appendText("Clear
tree\n");
ReInit();
return true;
}
else if (event.target == randTreeButton)
{
comment.appendText("Create
random tree\n");
RandomInsert();
return true;
}
else if (event.target == insButton)
{
if (!number.getText().equals("")){
thekey = Integer.parseInt(number.getText());
if (thekey > 99)
comment.appendText("Key over 99 (1-99 only)\n");
else{
comment.appendText("Insert " + number.getText()+"\n");
Insert();
}
number.setText(""); // 텍스트필드 깨끗히 지움
}
else // 만일 키가
선택되지 않았다면 랜덤값을 삽입
{
thekey = Math.abs(randGen.nextInt())%99+1;
comment.appendText("Insert Random key
"+String.valueOf(thekey)+"\n");
Insert();
}
return true;
}
else if (event.target == delButton)
{
if (!number.getText().equals("")){
thekey = Integer.parseInt(number.getText());
comment.appendText("Delete " + number.getText()+"\n");
Delete();
number.setText(""); // 텍스트필드 깨끗히 지움
}
else
comment.appendText("Enter key for Del\n");
return true;
}
else if (event.target == srchButton)
{
if (!number.getText().equals("")){
thekey = Integer.parseInt(number.getText());
comment.appendText("Search for " + number.getText()+"\n");
if(k.Search23(thekey)) // 찾는 키값이 발견되었다면..
{
comment.appendText(number.getText()+" FOUND in tree\n");
hi_key = thekey;
repaint();
}
else
comment.appendText(number.getText()+"
NOT FOUND in tree\n");
number.setText(""); // 텍스트필드 깨끗히 지움
}
else
comment.appendText("Enter search key!\n");
return true;
}
else
return super.action(event,
arg);
}
public boolean keyDown (Event evt, int key)
{
if ((key >= '0') && (key <= '9'))
return false;
else
return true;
}
// 35키값까지 랜덤 트리를 삽입
public void RandomInsert()
{
int randomkey;
ReInit();
randomkey = Math.abs(randGen.nextInt())%99+1;
k.Insert23(randomkey);
for (int i = 1; i <35 ; i++)
{
while(k.Search23(randomkey = Math.abs(randGen.nextInt())%99+1));
k.Insert23(randomkey);
}
for (int j = 0; j<MAXLEVEL; j++) //
모든 노드위치를 0으로 초기화
nodepos[j]=0;
index = 0;
NodeInfo(0, k.t);
repaint();
}
// 다시그려질 모든노드들을 위한 위치계산
public void NodeInfo(int level, int ptr)
{
int nodenum=-1; // B트리에 상대적인 노드번호의 실제적인
위치
if(ptr == -1){
nodepos[level]++;
nodepos[level+1]+=3;
return;
}
nodepos[level]++;
switch(level){
case 0:
nodenum=0;
break;
case 1:
nodenum=1+nodepos[level]-1;
break;
case 2:
nodenum=4+nodepos[level]-1;
break;
case 3:
nodenum=13+nodepos[level]-1;
break;
}
if (nodenum >-1){
nodearray[index]=nodenum;
tree[nodenum].lvalue=k.tree[ptr].Ldata;
tree[nodenum].rvalue=k.tree[ptr].Rdata;
index++;
}
else{ // 4단계가 넘어가면 에플릿에서
맞추지 않고 노드를 지운다
if ((k.tree[ptr].Ldata == thekey) ||
(k.tree[ptr].Rdata == thekey))
{
comment.appendText("CAN'T
INSERT!!!!!\n");
comment.appendText("Over
Display Limit!!!!!\n");
comment.appendText("Click
the clear tree button\n");
}
k.tree[ptr].Ldata = 0;
k.tree[ptr].Rdata = 0;
k.tree[ptr].left= -1;
k.tree[ptr].middle= -1;
k.tree[ptr].right= -1;
}
NodeInfo(level+1, k.tree[ptr].left);
NodeInfo(level+1, k.tree[ptr].middle);
NodeInfo(level+1, k.tree[ptr].right);
}
// 모든것을 다시 초기화한다,(빈트리)
public void ReInit()
{
for (int i = 0; i < TREESIZE; i++)
{
tree[i].lvalue = 0;
tree[i].rvalue = 0;
nodearray[i] = -1;
ReInitTree(0, k.t);
k.t = -1;
k.stackindex = 1;
}
}
// 모든 트리를 비운다
public void ReInitTree(int level, int ptr)
{
if(ptr == -1)
return;
k.tree[ptr].Ldata = 0;
k.tree[ptr].Rdata = 0;
ReInitTree(level+1, k.tree[ptr].left);
k.tree[ptr].left= -1;
ReInitTree(level+1, k.tree[ptr].middle);
k.tree[ptr].middle= -1;
ReInitTree(level+1, k.tree[ptr].right);
k.tree[ptr].right= -1;
}
// 정의된 키를 삽입
public void Insert()
{
if (k.Search23(thekey)) // 만일 키가 발견되면
아무것도 하지 않음
comment.appendText(String.valueOf(thekey)+"
ALREADY IN TREE\n");
else // 만일 키가 발견되면 트리에 삽입
{
hi_key = thekey; // set this key to be highlighted
k.Insert23(thekey);
for (int j = 0; j<MAXLEVEL; j++)
// 모든 노드위치를 0으로 초기화함
nodepos[j]=0;
for (int i = 0; i < TREESIZE; i++) // 모든
노드배열을 -1으로 초기화함
nodearray[i] = -1;
index = 0;
NodeInfo(0, k.t);
repaint();
thekey = -1; // reset thekey
}
}
// 정의된 키를 삭제
public void Delete()
{
if(k.Search23(thekey)) // 키값이 발견되면 삭제
{
k.Delete23(thekey);
for (int j = 0; j<MAXLEVEL; j++)
// 모든 노드위치를 0으로 초기화함
nodepos[j]=0;
for (int i = 0; i < TREESIZE; i++)
// 모든 노드배열을 -1으로 초기화함
nodearray[i] = -1;
index = 0; // 인텍스를 0으로 초기화
if (k.tree[k.t].Ldata == 0) //
트리가 비었다면
ReInit();
else
NodeInfo(0, k.t);
// 에플릿 표시를위한 노드정보의 재계산
repaint();
}
else
comment.appendText(String.valueOf(thekey)+"
NOT FOUND!\n");
thekey = -1; // reset thekey
}
}