⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tree.java

📁 这是个JAVA开发的WEB邮箱
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
/* * Tree.java * Copyright (C) 1999 dog <dog@dog.net.uk> *  * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. *  * This library 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 * Lesser General Public License for more details. *  * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA *  * You may retrieve the latest version of this library from * http://www.dog.net.uk/knife/ */package dog.util;import java.util.Vector;/** * A utility class for manipulating objects in a tree structure. * <p> * This class provides a way to associate arbitrary objects with one another in a hierarchy. * * @author dog@dog.net.uk * @version 1.0 */public final class Tree {	int nparents = 0;	Object[] parents;	int[] nchildren;	Object[][] children;	int nelements = 0;	Object[] elements;	int[] depths;	int increment;	Object LOCK = new Object();	/**	 * Constructs an empty tree.	 */	public Tree() {		this(10);	}		/**	 * Constructs an empty tree with the specified capacity increment.	 * @param increment the amount by which the capacity is increased when an array overflows.	 */	public Tree(int increment) {		super();		this.increment = (increment>0) ? increment : 1;		clear();	}	// Returns the elements index of the specified object, or -1 if no such element exists.	private int elementIndex(Object object) {		for (int i=0; i<nelements; i++)			if (elements[i]==object)				return i;		return -1;	}	// Returns the parents index of the specified object, or -1 if no such parent exists.	private int parentIndex(Object object) {		for (int i=0; i<nparents; i++)			if (parents[i]==object)				return i;		return -1;	}	/**	 * Returns the parent of the specified object,	 * or null if the object is a root or not a child in the tree.	 */	public Object getParent(Object child) {		synchronized (LOCK) {			return parentOf(child);		}	}	private Object parentOf(Object child) {		for (int p = 0; p<nparents; p++) {			for (int c = 0; c<nchildren[p]; c++)				if (children[p][c]==child)					return parents[p];		}		return null;	}	/**	 * Returns an array of children of the specified object,	 * or an empty array if the object is not a parent in the tree.	 */	public Object[] getChildren(Object parent) {		synchronized (LOCK) {			int p = parentIndex(parent);			if (p>-1) {				Object[] c = new Object[nchildren[p]];				System.arraycopy(children[p], 0, c, 0, nchildren[p]);				return c;			}		}		return new Object[0];	}	/**	 * Returns the number of children of the specified object.	 */	public int getChildCount(Object parent) {		synchronized (LOCK) {			int p = parentIndex(parent);			if (p>-1)				return nchildren[p];		}		return 0;	}	/**	 * Indicates whether the specified object is contained in the tree.	 */	public boolean contains(Object object) {		synchronized (LOCK) {			return (elementIndex(object)>-1);		}	}	private void ensureRootCapacity(int amount) {		// calculate the amount by which to increase arrays		int block = ((int)(Math.max(Math.ceil((double)amount/(double)increment), 1)))*increment;		// ensure capacity of elements		if (elements.length<nelements+amount) {			int len = elements.length;			Object[] newelements = new Object[len+block];			System.arraycopy(elements, 0, newelements, 0, nelements);			elements = newelements;			int[] newdepths = new int[len+block];			System.arraycopy(depths, 0, newdepths, 0, nelements);			depths = newdepths;		}	}	private void ensureParentCapacity(int amount) {		// calculate the amount by which to increase arrays		int block = ((int)(Math.max(Math.ceil((double)amount/(double)increment), 1)))*increment;		// ensure capacity of parents (and hence children in parent dimension)		if (parents.length<nparents+1) {			Object[] newparents = new Object[parents.length+increment];			System.arraycopy(parents, 0, newparents, 0, nparents);			parents = newparents;			Object[][] newchildren = new Object[parents.length+increment][];			System.arraycopy(children, 0, newchildren, 0, nparents);			children = newchildren;			int[] newnchildren = new int[parents.length+increment];			System.arraycopy(nchildren, 0, newnchildren, 0, nparents);			nchildren = newnchildren;		}		// ensure capacity of elements		if (elements.length<nelements+amount) {			int len = elements.length;			Object[] newelements = new Object[len+block];			System.arraycopy(elements, 0, newelements, 0, nelements);			elements = newelements;			int[] newdepths = new int[len+block];			System.arraycopy(depths, 0, newdepths, 0, nelements);			depths = newdepths;		}	}	private void ensureChildCapacity(int amount, int parent) {		// calculate the amount by which to increase arrays		int block = ((int)(Math.max(Math.ceil((double)amount/(double)increment), 1)))*increment;		// ensure capacity of children for this parent		if (children[parent].length<nchildren[parent]+amount) {			Object[] newchildren = new Object[children[parent].length+block];			System.arraycopy(children[parent], 0, newchildren, 0, nchildren[parent]);			children[parent] = newchildren;		}		// ensure capacity of elements		if (elements.length<nelements+amount) {			int len = elements.length;			Object[] newelements = new Object[len+block];			System.arraycopy(elements, 0, newelements, 0, nelements);			elements = newelements;			int[] newdepths = new int[len+block];			System.arraycopy(depths, 0, newdepths, 0, nelements);			depths = newdepths;		}	}	/**	 * Adds a root to the tree.	 * Returns the root if it was added.	 */	public void add(Object object) {		if (object==null)			throw new NullPointerException("cannot add null to a tree");		synchronized (LOCK) {			int e;			if ((e = elementIndex(object))>-1) // if we already have the object				removeElement(e); // remove it			ensureRootCapacity(1);			elements[nelements] = object;			depths[nelements] = 1;			nelements++;		}	}	/**	 * Adds roots to the tree.	 */	public void add(Object[] objects) {		synchronized (LOCK) {			for (int i=0; i<objects.length; i++) {				if (objects[i]==null)					throw new NullPointerException("cannot add null to a tree");				int e;				if ((e = elementIndex(objects[i]))>-1) // if we already have the object					removeElement(e); // remove it			}			ensureRootCapacity(objects.length);			System.arraycopy(objects, 0, elements, nelements, objects.length);			for (int i=nelements; i<nelements+objects.length; i++)				depths[i] = 1;			nelements += objects.length;		}	}	/**	 * Adds a child to the specified parent in the tree.	 * @throws IllegalArgumentException if the parent does not exist in the tree or the child is the parent.	 */	public void add(Object parent, Object child) {		if (parent==null)			throw new NullPointerException("null parent specified");		if (child==null)			throw new NullPointerException("cannot add null to a tree");		if (child==parent)			throw new IllegalArgumentException("cannot add child to itself");		synchronized (LOCK) {			int p = parentIndex(parent), pe = -1;			if (p<0) { // does it exist in the tree?				if ((pe = elementIndex(parent))<0)					throw new IllegalArgumentException("parent does not exist");			} // so we'll add it to parents			int e;			if ((e = elementIndex(child))>-1) // if the child is already an element				removeElement(e);			if (p<0) { // add the parent to parents				p = nparents;				ensureParentCapacity(1);				parents[p] = parent;				children[p] = new Object[increment];				nchildren[p] = 0;				nparents++;			}			ensureChildCapacity(1, p);			children[p][nchildren[p]] = child;			// insert the child into elements and set its depth			int depth = depth(parent);			int off = pe+nchildren[p]+1;			int len = nelements-off;			Object[] buffer = new Object[len];			System.arraycopy(elements, off, buffer, 0, len);			elements[off] = child;			System.arraycopy(buffer, 0, elements, off+1, len);			int[] dbuffer = new int[len];			System.arraycopy(depths, off, dbuffer, 0, len);			depths[off] = depth+1;			System.arraycopy(dbuffer, 0, depths, off+1, len);			nelements++;			nchildren[p]++;		}	}	/**	 * Adds children to the specified parent in the tree.	 * @throws IllegalArgumentException if the parent does not exist in the tree or one of the children is the parent.	 */	public void add(Object parent, Object[] children) {		if (parent==null)			throw new NullPointerException("null parent specified");		synchronized (LOCK) {			int p = parentIndex(parent), pe = -1;			if (p<0) { // does it exist in the tree?				if ((pe = elementIndex(parent))<0)					throw new IllegalArgumentException("parent does not exist");			} // so we'll add it to parents			for (int i=0; i<children.length; i++) {				if (children[i]==null)					throw new NullPointerException("cannot add null to a tree");				if (children[i]==parent)					throw new IllegalArgumentException("cannot add child to itself");				int e;				if ((e = elementIndex(children[i]))>-1) // if we already have the object					removeElement(e); // remove it			}			if (p<0) { // add the parent to parents				p = nparents;				ensureParentCapacity(1);				parents[p] = parent;				this.children[p] = new Object[Math.max(increment, (children.length/increment)*increment)];				nchildren[p] = 0;				nparents++;			}			ensureChildCapacity(children.length, p);			System.arraycopy(children, 0, this.children[p], nchildren[p], children.length);			// insert the children into elements and set their depths			int depth = depth(parent);			int off = pe+nchildren[p]+1;			int len = nelements-off;			Object[] buffer = new Object[len];			System.arraycopy(elements, off, buffer, 0, len);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -