072459a055
Reviewed-by: erikj, ihse, ehelin
405 lines
7.3 KiB
Java
405 lines
7.3 KiB
Java
/*
|
|
* Copyright (c) 2002, 2018, Oracle and/or its affiliates. All rights reserved.
|
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
|
*
|
|
* This code is free software; you can redistribute it and/or modify it
|
|
* under the terms of the GNU General Public License version 2 only, as
|
|
* published by the Free Software Foundation.
|
|
*
|
|
* This code is distributed in the hope that it will be useful, but WITHOUT
|
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
* version 2 for more details (a copy is included in the LICENSE file that
|
|
* accompanied this code).
|
|
*
|
|
* You should have received a copy of the GNU General Public License version
|
|
* 2 along with this work; if not, write to the Free Software Foundation,
|
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
*
|
|
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
|
* or visit www.oracle.com if you need additional information or have any
|
|
* questions.
|
|
*/
|
|
|
|
package gc.gctests.gctest03;
|
|
|
|
class DataNodeException extends Exception
|
|
{
|
|
}
|
|
|
|
|
|
class DataNode {
|
|
int key;
|
|
int buf[];
|
|
static int dataNodeCount = 0;
|
|
static int dataNodeLimit;
|
|
|
|
static synchronized void incDataNodeCount()
|
|
{
|
|
dataNodeCount++;
|
|
}
|
|
|
|
static synchronized int getDataNodeCount()
|
|
{
|
|
return dataNodeCount;
|
|
}
|
|
|
|
static synchronized void setDataNodeLimit(int newLimit)
|
|
{
|
|
dataNodeLimit = newLimit;
|
|
}
|
|
|
|
static synchronized int getDataNodeLimit()
|
|
{
|
|
return dataNodeLimit;
|
|
}
|
|
|
|
static synchronized void clearDataNodeCount()
|
|
{
|
|
dataNodeCount = 0;
|
|
}
|
|
DataNode(int key) throws DataNodeException
|
|
{
|
|
|
|
incDataNodeCount();
|
|
if (getDataNodeCount() > getDataNodeLimit())
|
|
{
|
|
throw (new DataNodeException());
|
|
}
|
|
|
|
this.key = key;
|
|
try {
|
|
buf = new int[key];
|
|
}
|
|
catch ( OutOfMemoryError e )
|
|
{
|
|
System.out.println(Thread.currentThread().getName() + " : outofmemory");
|
|
}
|
|
}
|
|
|
|
public void print()
|
|
{
|
|
System.out.println(key);
|
|
}
|
|
|
|
public boolean equals(DataNode d)
|
|
{
|
|
int k = d.getkey();
|
|
|
|
return ( key == k);
|
|
}
|
|
|
|
public boolean large(DataNode d)
|
|
{
|
|
int k = d.getkey();
|
|
|
|
return ( key > k);
|
|
}
|
|
|
|
public boolean less(DataNode d)
|
|
|
|
{
|
|
int k = d.getkey();
|
|
|
|
return ( key < k);
|
|
}
|
|
|
|
public int getkey()
|
|
{ return key; }
|
|
}
|
|
|
|
|
|
class TreeNode {
|
|
DataNode data;
|
|
TreeNode parent;
|
|
TreeNode left;
|
|
TreeNode right;
|
|
|
|
TreeNode(DataNode key)
|
|
{
|
|
this.data = key;
|
|
parent = null;
|
|
left = null;
|
|
right = null;
|
|
}
|
|
|
|
public void print()
|
|
{
|
|
data.print();
|
|
}
|
|
|
|
public TreeNode getleft()
|
|
{
|
|
return left;
|
|
}
|
|
|
|
public TreeNode getright()
|
|
{
|
|
return right;
|
|
}
|
|
|
|
public TreeNode getparent()
|
|
{
|
|
return parent;
|
|
}
|
|
|
|
public synchronized void setleft(TreeNode left)
|
|
{
|
|
this.left = left;
|
|
}
|
|
|
|
public synchronized void setright(TreeNode right)
|
|
{
|
|
this.right = right;
|
|
}
|
|
|
|
public synchronized void setparent(TreeNode parent)
|
|
{
|
|
this.parent = parent;
|
|
}
|
|
|
|
public DataNode getData()
|
|
{
|
|
return data;
|
|
}
|
|
|
|
// print it out in order of a large one first
|
|
public void sprint()
|
|
{
|
|
//print itself
|
|
if ( left != null ) left.sprint();
|
|
System.out.println(data.getkey());
|
|
if ( right != null ) right.sprint();
|
|
}
|
|
|
|
// print it out in order of a small one first
|
|
public void lprint()
|
|
{
|
|
if (right != null ) right.lprint();
|
|
System.out.println(data.getkey());
|
|
if ( left != null ) left.lprint();
|
|
}
|
|
|
|
public synchronized TreeNode duplicate()
|
|
{
|
|
TreeNode tp = new TreeNode(data);
|
|
|
|
if ( left != null )
|
|
{
|
|
tp.left = left.duplicate();
|
|
}
|
|
if ( right != null )
|
|
{
|
|
tp.right = right.duplicate();
|
|
}
|
|
return tp;
|
|
}
|
|
|
|
public TreeNode search(DataNode d)
|
|
{
|
|
TreeNode tp = this;
|
|
DataNode k;
|
|
|
|
while ( tp != null )
|
|
{
|
|
k = tp.getData();
|
|
if ( k.equals(d) )
|
|
{
|
|
return tp;
|
|
}
|
|
else
|
|
if ( d.large(k) )
|
|
tp = tp.getright();
|
|
else
|
|
tp = tp.getleft();
|
|
}
|
|
return null;
|
|
}
|
|
|
|
public synchronized void insert(TreeNode t)
|
|
{
|
|
DataNode d = t.getData();
|
|
|
|
TreeNode tp = this;
|
|
TreeNode tp1 = tp;
|
|
DataNode d0;
|
|
|
|
while ( true )
|
|
{
|
|
d0 = tp.getData();
|
|
|
|
if ( d.large(d0) )
|
|
{
|
|
tp1 = tp;
|
|
tp = tp.getright();
|
|
if ( tp == null )
|
|
{
|
|
tp1.setright(t);
|
|
t.setparent(tp1);
|
|
break;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
tp1 = tp;
|
|
tp = tp.getleft();
|
|
if (tp == null )
|
|
{
|
|
tp1.setleft(t);
|
|
t.setparent(tp1);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
class Tree {
|
|
TreeNode root = null;
|
|
|
|
Tree()
|
|
{
|
|
root = null;
|
|
}
|
|
|
|
Tree(TreeNode root)
|
|
{
|
|
this.root = root;
|
|
}
|
|
|
|
public synchronized void insert(TreeNode t)
|
|
{
|
|
if ( root == null )
|
|
{
|
|
root = t;
|
|
return;
|
|
}
|
|
|
|
root.insert(t);
|
|
}
|
|
|
|
|
|
public void sort1()
|
|
{
|
|
root.sprint();
|
|
}
|
|
|
|
public void sort2()
|
|
{
|
|
root.lprint();
|
|
}
|
|
|
|
public TreeNode search(DataNode d)
|
|
{
|
|
if ( root == null ) return null;
|
|
else return root.search(d);
|
|
}
|
|
|
|
public synchronized boolean remove(DataNode d)
|
|
{
|
|
if ( root == null ) return false;
|
|
|
|
TreeNode t = root.search(d);
|
|
|
|
// data is not in a heap
|
|
if ( t == null ) return false;
|
|
|
|
/*
|
|
if ( d.equals(t.getData()) == false )
|
|
{
|
|
System.out.println("failed");
|
|
return false;
|
|
}
|
|
*/
|
|
|
|
TreeNode p = t.getparent();
|
|
TreeNode l = t.getleft();
|
|
TreeNode r = t.getright();
|
|
|
|
// the removed node is a root
|
|
if ( p == null )
|
|
{
|
|
if ( l == null && r != null )
|
|
{
|
|
r.setparent(null);
|
|
root = r;
|
|
return true;
|
|
}
|
|
if ( l != null && r == null )
|
|
{
|
|
l.setparent(null);
|
|
root = l;
|
|
return true;
|
|
}
|
|
if ( l == null && r == null )
|
|
{
|
|
root = null;
|
|
return true;
|
|
}
|
|
|
|
if ( l != null && r != null )
|
|
{
|
|
r.setparent(null);
|
|
r.insert(l);
|
|
root = r;
|
|
return true;
|
|
}
|
|
}
|
|
|
|
// a leaf
|
|
if ( r == null && l == null )
|
|
{
|
|
if ( p.getright() == t )
|
|
{
|
|
/* right child */
|
|
p.setright(null);
|
|
}
|
|
else
|
|
p.setleft(null);
|
|
return true;
|
|
}
|
|
|
|
// a node without left child
|
|
if ( r != null && l == null )
|
|
{
|
|
r.setparent(p);
|
|
if ( t == p.getright() ) p.setright(r);
|
|
if ( t == p.getleft() ) p.setleft(r);
|
|
return true;
|
|
}
|
|
|
|
if ( r == null && l != null )
|
|
{
|
|
l.setparent(p);
|
|
if ( t == p.getright() ) p.setright(l);
|
|
if ( t == p.getleft() ) p.setleft(l);
|
|
return true;
|
|
}
|
|
|
|
// a node with two children
|
|
r.insert(l);
|
|
r.setparent(p);
|
|
if ( t == p.getright() ) p.setright(r);
|
|
if ( t == p.getleft() ) p.setleft(r);
|
|
return true;
|
|
}
|
|
|
|
public synchronized Tree copy()
|
|
{
|
|
if ( root == null ) return null;
|
|
|
|
return(new Tree(root.duplicate()));
|
|
}
|
|
|
|
public synchronized boolean isempty()
|
|
{
|
|
return ( root == null );
|
|
}
|
|
|
|
|
|
}
|