📄 tree.java
字号:
System.arraycopy(children, 0, elements, off, children.length);
System.arraycopy(buffer, 0, elements, off+children.length, len);
int[] dbuffer = new int[len];
System.arraycopy(depths, off, dbuffer, 0, len);
for (int i=off; i<off+children.length; i++)
depths[i] = depth+1;
System.arraycopy(dbuffer, 0, depths, off+children.length, len);
nelements += children.length;
nchildren[p] += children.length;
}
}
// Returns the depth of an object in the tree
private int depth(Object object) {
Object parent = parentOf(object);
if (parent==null)
return 1;
else
return depth(parent)+1;
}
/**
* Removes the specified object and all its children from the tree.
* Computationally pretty expensive.
*/
public void remove(Object object) {
if (object==null)
return; // i mean, really...
synchronized (LOCK) {
int e = elementIndex(object);
if (e>-1)
removeElement(e);
}
}
void removeElement(int e) {
int len = 0;
// does this element have children?
for (int p=0; p<nparents; p++) {
if (parents[p]==elements[e]) {
int nc = nchildren[p];
// remove the children of this parent first
Object[] pchildren = new Object[nc];
System.arraycopy(children[p], 0, pchildren, 0, nc);
for (int c=0; c<nc; c++) {
int ce = elementIndex(pchildren[c]);
if (ce>-1)
removeElement(ce);
}
// remove the parent
if ((len = nparents-p-1)>0) {
System.arraycopy(parents, p+1, parents, p, len);
System.arraycopy(children, p+1, children, p, len);
System.arraycopy(nchildren, p+1, nchildren, p, len);
}
nparents--; p--;
} else {
// is this element a child of another parent?
for (int c=0; c<nchildren[p]; c++) {
if (children[p][c]==elements[e]) {
// remove this element from the children array
if ((len = nchildren[p]-c-1)>0) {
System.arraycopy(children[p], c+1, children[p], c, len);
}
nchildren[p]--; c--;
}
}
}
}
if ((len = nelements-e-1)>0) {
System.arraycopy(elements, e+1, elements, e, len);
System.arraycopy(depths, e+1, depths, e, len);
}
nelements--;
}
/**
* Removes the specified objects and all their children from the tree.
* @throws NullPointerException if an object does not exist in the tree.
*/
public void remove(Object[] objects) {
for (int i=0; i<objects.length; i++)
remove(objects[i]);
}
/**
* Recursively removes the specified object's children from the tree.
* @throws NullPointerException if the object does not exist in the tree.
*/
public void removeChildren(Object parent) {
synchronized (LOCK) {
removeChildrenImpl(parent);
}
}
void removeChildrenImpl(Object parent) {
int p = parentIndex(parent);
if (p>-1) {
for (int c=0; c<nchildren[p]; c++)
removeChildrenImpl(children[p][c]);
children[p] = new Object[increment];
nchildren[p] = 0;
}
}
/**
* Removes all objects from the tree.
*/
public void clear() {
synchronized (LOCK) {
parents = new Object[increment];
nparents = 0;
nchildren = new int[increment];
for (int i=0; i<increment; i++)
nchildren[i] = 0;
children = new Object[increment][increment];
elements = new Object[increment];
depths = new int[increment];
nelements = 0;
}
}
/**
* Returns the depth of the specified object in the tree.
* Roots have a depth of 1.
*/
public int getDepth(Object object) {
synchronized (LOCK) {
int e = elementIndex(object);
if (e==-1) {
//System.out.println("Warning: "+object+" not found");
//new Throwable().printStackTrace();
return -1;
}
return depths[e];
}
}
/**
* Returns the roots in this tree.
*/
public Object[] getRoots() {
synchronized (LOCK) {
Vector v = new Vector();
for (int i=0; i<nelements; i++) {
if (depths[i]==1)
v.addElement(elements[i]);
}
Object[] roots = new Object[v.size()];
v.copyInto(roots);
return roots;
}
}
/**
* Returns the number of roots in this tree.
*/
public int getRootCount() {
synchronized (LOCK) {
Vector v = new Vector();
for (int i=0; i<nelements; i++) {
if (depths[i]==1)
v.addElement(elements[i]);
}
return v.size();
}
}
/**
* Returns all the objects in this tree in depth-first order.
*/
public Object[] getTree() {
synchronized (LOCK) {
Object[] objects = new Object[nelements];
System.arraycopy(elements, 0, objects, 0, nelements);
return objects;
}
}
/**
* Returns the number of objects in this tree.
*/
public int getTreeCount() {
return nelements;
}
/**
* Indicates whether there are any children in this tree.
*/
public boolean hasChildren() {
synchronized (LOCK) {
for (int p=0; p<nparents; p++)
if (nchildren[p]>0)
return true;
}
return false;
}
/**
* Sorts the objects in the tree according to the specified object collator.
* This has no effect if a collator has not been defined.
*/
public void sort(ObjectCollator collator) {
if (collator==null) throw new NullPointerException("null collator");
synchronized (LOCK) {
Sorter sorter = this.new Sorter(collator);
elements = sorter.newelements;
depths = sorter.newdepths;
}
}
class Sorter {
Object[] newelements;
int[] newdepths;
int count = 0;
Sorter(ObjectCollator collator) {
// first sort the roots
Vector v = new Vector();
for (int i=0; i<nelements; i++) {
if (depths[i]==1)
v.addElement(elements[i]);
}
Object[] roots = new Object[v.size()];
v.copyInto(roots);
sort(roots, 0, roots.length-1, collator);
// now sort the children of each parent
for (int p=0; p<nparents; p++)
sort(children[p], 0, nchildren[p]-1, collator);
// now create a new elements array positioning the elements according to the new order
newelements = new Object[elements.length];
newdepths = new int[elements.length];
for (int r=0; r<roots.length; r++) {
newelements[count] = roots[r];
newdepths[count] = depths[elementIndex(roots[r])];
count++;
appendChildren(roots[r]);
}
}
void appendChildren(Object parent) {
for (int p=0; p<nparents; p++) {
if (parent==parents[p]) {
for (int c=0; c<nchildren[p]; c++) {
newelements[count] = children[p][c];
newdepths[count] = getDepth(children[p][c]);
count++;
appendChildren(children[p][c]);
}
break;
}
}
}
}
// Quicksort algorithm.
static void sort(Object[] objects, int first, int last, ObjectCollator collator) {
int lo = first, hi = last;
Object mid;
if (last>first) {
mid = objects[(first+last)/2];
while (lo<=hi) {
while (lo<last && collator.compare(objects[lo], mid)<0)
lo += 1;
while (hi>first && collator.compare(objects[hi], mid)>0)
hi -= 1;
if (lo<=hi) { // swap
Object tmp = objects[lo];
objects[lo] = objects[hi];
objects[hi] = tmp;
lo += 1;
hi -= 1;
}
}
if (first<hi)
sort(objects, first, hi, collator);
if (lo<last)
sort(objects, lo, last, collator);
}
}
public void printArray(String name, Object[] array, int count) {
System.out.println(name+": length="+array.length+", count="+count);
for (int i=0; i<count; i++)
System.out.println("\t"+array[i]);
}
public void printElements() {
System.out.println("elements=");
for (int i=0; i<nelements; i++) {
StringBuffer buffer = new StringBuffer();
buffer.append(Integer.toString(depths[i]));
for (int j=0; j<depths[i]; j++)
buffer.append(" ");
buffer.append(elements[i]);
System.out.println(buffer.toString());
}
System.out.println("tree=");
for (int p=0; p<nparents; p++) {
System.out.println(parents[p]);
for (int c=0; c<nchildren[p]; c++)
System.out.println(" "+children[p][c]);
}
}
// -- Utility methods --
public String toString() {
StringBuffer buffer = new StringBuffer();
buffer.append(getClass().getName());
buffer.append("[");
buffer.append("nelements="+nelements);
buffer.append(",elements.length="+elements.length);
buffer.append(",depths.length="+depths.length);
buffer.append(",nparents="+nparents);
buffer.append(",parents.length="+parents.length);
buffer.append("]");
return buffer.toString();
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -