码迷,mamicode.com
首页 > 编程语言 > 详细

(java)树-双亲表示法

时间:2014-12-13 23:27:30      阅读:421      评论:0      收藏:0      [点我收藏+]

标签:des   blog   http   io   ar   os   sp   for   java   

//数据类型

package org.mo.common.structure.tree;

public class Student implements java.io.Serializable {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	private int id;

	private String name;

	private int age;

	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}

	@Override
	public String toString() {
		return "Student [id=" + id + ", name=" + name + ", age=" + age + "]";
	}

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + age;
		result = prime * result + id;
		result = prime * result + ((name == null) ? 0 : name.hashCode());
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Student other = (Student) obj;
		if (age != other.age)
			return false;
		if (id != other.id)
			return false;
		if (name == null) {
			if (other.name != null)
				return false;
		} else if (!name.equals(other.name))
			return false;
		return true;
	}

}

//结点类型

package org.mo.common.structure.tree;

public class PNode<T> implements java.io.Serializable {
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	private T data;// 结点数据

	private int parent;// 双亲位置

	public PNode() {
		super();
	}

	public PNode(T data) {
		this.data = data;
	}

	public PNode(T data, int parent) {
		this.data = data;
		this.parent = parent;
	}

	public T getData() {
		return data;
	}

	public void setData(T data) {
		this.data = data;
	}

	public int getParent() {
		return parent;
	}

	public void setParent(int parent) {
		this.parent = parent;
	}

	@Override
	public String toString() {
		return "PNode [data=" + data + ", parent=" + parent + "]";
	}

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + ((data == null) ? 0 : data.hashCode());
		result = prime * result + parent;
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		@SuppressWarnings("unchecked")
		PNode<T> other = (PNode<T>) obj;
		if (data == null) {
			if (other.data != null)
				return false;
		} else if (!data.equals(other.data))
			return false;
		if (parent != other.parent)
			return false;
		return true;
	}

}

//树类型

package org.mo.common.structure.tree;

import java.util.ArrayList;
import java.util.List;

/**
 * 双亲表示法
 * 
 * @author moziqi
 * 
 */
public class PTree<E> {

	private final int DEFAULT_TREE_SIZE = 100;

	private PNode<E>[] pNodes; // 结点数组

	private int treeSize;

	private int nodeNums;// 结点数

	/**
	 * 以指定根结点创建树
	 * 
	 * @param data
	 */
	@SuppressWarnings("unchecked")
	public PTree(E data) {
		treeSize = DEFAULT_TREE_SIZE;
		pNodes = new PNode[treeSize]; // 这样写法虽然能通过,但是不好,有兴趣自己去了解为什么
		pNodes[0] = new PNode<E>(data, -1);// -1表示根结点
		nodeNums++;
	}

	/**
	 * 以指定根结点、指定treeSize创建树
	 * 
	 * @param data
	 * @param treeSize
	 */
	@SuppressWarnings("unchecked")
	public PTree(E data, int treeSize) {
		this.treeSize = treeSize;
		pNodes = new PNode[treeSize];
		pNodes[0] = new PNode<E>(data, -1);
		nodeNums++;
	}

	/**
	 * 为指定结点添加子结点
	 * 
	 * @param data
	 * @param parent
	 */
	public void addNode(E data, PNode<E> parent) {
		for (int i = 0; i < treeSize; i++) {
			if (pNodes[i] == null) {
				pNodes[i] = new PNode<E>(data, getPos(parent));
				nodeNums++;
				return;
			}
		}
		throw new RuntimeException("该树已满,无法添加新结点");
	}

	/**
	 * 判断树是否为空
	 * 
	 * @return
	 */
	public boolean isEmpty() {
		return pNodes[0] == null;
	}

	/**
	 * 返回根结点
	 * 
	 * @return
	 */
	public PNode<E> getRoot() {
		if (isEmpty()) {
			return null;
		} else {
			return pNodes[0];
		}
	}

	/**
	 * 返回指定结点(非叶子结点)的所有子结点。
	 * 
	 * @param parent
	 * @return
	 */
	public List<PNode<E>> getChildren(PNode<E> parent) {
		List<PNode<E>> list = new ArrayList<PNode<E>>();
		for (int i = 0; i < treeSize; i++) {
			if (pNodes[i] != null && pNodes[i].getParent() != getPos(parent)) {
				list.add(pNodes[i]);
			}
		}
		return list;
	}

	/**
	 * 返回指定结点(非根结点)的父结点
	 * 
	 * @param pNode
	 * @return
	 */
	public PNode<E> getParent(PNode<E> pNode) {
		if (pNode != null) {
			return pNodes[pNode.getParent()];
		}
		return null;
	}

	/**
	 * 返回包含指定值的结点
	 * 
	 * @param node
	 * @return
	 */
	public int getPos(PNode<E> node) {
		for (int i = 0; i < treeSize; i++) {
			// 找到指定结点
			if (pNodes[i].equals(node)) {
				return i;
			}
		}
		return -1;
	}

	/**
	 * 返回该树的深度
	 * 
	 * @return
	 */
	public int getDeep() {
		// 用于记录结点的最大深度
		int max = 0;
		for (int i = 0; i < treeSize && pNodes[i] != null; i++) {
			// 初始化本结点的深度
			int def = 1;
			// m记录当前结点的父结点的位置
			int m = pNodes[i].getParent();
			// 如果其父结点存在
			while (m != -1 && pNodes[m] != null) {
				// 向上继续搜索父结点
				m = pNodes[m].getParent();
				def++;
			}
			if (max < def) {
				max = def;
			}
		}
		// 返回最大深度
		return max;
	}
}

//测试

package org.mo.common.structure.tree;

import java.util.List;

import org.junit.Test;

public class PTreeTest {

	@Test
	public void testPTree() {
		// 构建一棵树
		Student data = new Student();
		data.setId(1);
		data.setName("test1");
		data.setAge(19);
		PTree<Student> pTree = new PTree<Student>(data);
		// 拿到父结点
		PNode<Student> parent = new PNode<Student>(data);
		parent.setParent(-1);
		// 遍历所有结点
		List<PNode<Student>> children = pTree.getChildren(parent);
		System.out.println("所有结点:");
		for (PNode<Student> node : children) {
			System.out.println(node.toString());
		}
		System.out.print("深度:");
		int deep = pTree.getDeep();
		System.out.println(deep);
		// 添加多一个结点
		Student data2 = new Student();
		data2.setId(2);
		data2.setName("test1" + 2);
		data2.setAge(19 + 2);
		pTree.addNode(data2, parent);
		PNode<Student> parent2 = new PNode<Student>(data2);
		List<PNode<Student>> children2 = pTree.getChildren(parent2);
		System.out.println("所有结点:");
		for (PNode<Student> node : children2) {
			System.out.println(node.toString());
		}
		System.out.print("深度:");
		int deep2 = pTree.getDeep();
		System.out.println(deep2);
	}

}

//参考:

http://justsee.iteye.com/blog/1097166


(java)树-双亲表示法

标签:des   blog   http   io   ar   os   sp   for   java   

原文地址:http://my.oschina.net/moziqi/blog/355867

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!