1. 程式人生 > >資料結構之多叉樹的定義

資料結構之多叉樹的定義

利用List<?>構建樹

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

/**
 * 樹節點
 * 
 * @author Oliver
 * 
 */
public class TreeNode {
	private String data;
	private TreeNode parentNode;
	private List<TreeNode> childList;

	public TreeNode() {
		initChildList();
	}

	public TreeNode(String data) {
		this.data = data;
	}

	/**
	 * 返回當前節點的孩子節點,也可得到當前節點的兄弟節點
	 * 
	 * @return List<TreeNode>
	 */
	public List<TreeNode> getChildList() {
		return childList;
	}

	public void setChildList(List<TreeNode> childList) {
		this.childList = childList;
	}

	/**
	 * 判斷節點是否為葉子,是返回true,否則返回false
	 * 
	 * @return
	 */
	public boolean isLeaf() {
		if (this.childList == null)
			return true;
		else {
			if (this.childList.isEmpty())
				return true;
			else
				return false;
		}
	}
	/**
	 * 判斷兩個節點是否含有相同的data
	 * @param node
	 * @return
	 */
	protected boolean equals(TreeNode node) {
		if (this.getData().equals(node.getData()))
			return true;
		return false;
	}
	
	/**
	 * 返回此節點的孩子節點列表中首次出現的指定元素的索引,或如果不包含元素,則返回-1
	 * @param node
	 * @return
	 */
	protected int indexOf(TreeNode node) {
		List<TreeNode> list = this.getChildList();
		int length = list.size();
		for (int i = 0; i < length; i++) {
			if (list.get(i).equals(node))
				return i;
		}
		return -1;
	}

	/***
	 * 新增一個孩子節點
	 */
	public void addChild(TreeNode childNode) {
		initChildList();
		// 如果存在該子節點,退出
		if (this.indexOf(childNode) >= 0)
			return;
		else {
			// 設定父親節點
			childNode.setParentNode(this);
			this.childList.add(childNode);
		}
	}

	private void initChildList() {
		if (this.childList == null)
			this.childList = new ArrayList<TreeNode>();
	}

	/**
	 * 返回當前節點的所有父輩節點
	 */
	public List<TreeNode> getElders() {
		List<TreeNode> elders = new ArrayList<TreeNode>();
		TreeNode parentNode = this.parentNode;
		if (parentNode == null) {
			return elders;
		} else {
			// 倒序插入
			elders.add(0, parentNode);
			elders.addAll(0, parentNode.getElders());
			return elders;
		}
	}

	/**
	 * 返回當前節點的所有晚輩節點
	 */
	public List<TreeNode> getJuniors() {
		List<TreeNode> juniors = new ArrayList<TreeNode>();
		List<TreeNode> childList = this.getChildList();
		if (childList == null) {
			return juniors;
		} else {
			int length = childList.size();
			for (int i = 0; i < length; i++) {
				TreeNode junior = childList.get(i);
				juniors.add(junior);
				juniors.addAll(junior.getJuniors());
			}
			return juniors;
		}
	}

	/**
	 * 層次遍歷
	 * 
	 * @param times
	 */
	public void traverse(int times) {
		print(this, times);
		// 如果是葉子則返回
		if (this.isLeaf())
			return;
		int length = this.getChildList().size();
		times = times + 1;
		for (int i = 0; i < length; i++) {
			this.getChildList().get(i).traverse(times);
		}

	}

	private void print(TreeNode node, int times) {
		for (int i = 0; i < times; i++) {
			System.out.print("\t");
		}
		System.out.println(node.getData());
	}
	
	/**
	 * 合併子節點
	 */
	public void mergeChildNode() {
		// 僅只有一個根節點或者是葉子節點
		if (this.isLeaf())
			return;
		List<TreeNode> childList = this.getChildList();
		int length = childList.size();
		if (length == 1) {
			TreeNode child = childList.get(0);
			// 合併data
			String mergedData = this.getData() + child.getData();
			this.setData(mergedData);
			// 如果此時child已經是葉子節點了,即表示沒有後代節點
			if (child.isLeaf()) {
				this.getChildList().clear();
			} else {
				// 修改節點的childList
				List<TreeNode> grandchildrenList = child.getChildList();

				this.getChildList().clear();
				for (TreeNode t : grandchildrenList) {
					t.setParentNode(this);
					this.getChildList().add(t);
				}
				this.mergeChildNode();
			}
		} else {
			for (int i = 0; i < length; i++) {
				childList.get(i).mergeChildNode();
			}
		}
	}

	/**
	 * 刪除合併後的子節點
	 * 
	 * protected void deleteNode() { this.childList.clear(); }
	 */
	public String getData() {
		return data;
	}

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

	public TreeNode getParentNode() {
		return parentNode;
	}

	public void setParentNode(TreeNode parentNode) {
		this.parentNode = parentNode;
	}

}