二叉树的链表存储

二叉树的链表存储,就是让每个节点都能保存指向其左右节点的信息。为每个节点添加left和right两个指向(指针),分别引用该节点的左右节点。

首先定义节点:

package my.bintree;

public class TreeNode<T> {
	private T data;
	private TreeNode<T> left;
	private TreeNode<T> right;
	
	public TreeNode(){	
	}
	
	public TreeNode(T data){
		this.data = data;
	}
	
	public TreeNode(T data, TreeNode<T> left, TreeNode<T> right){
		this.data = data;
		this.left = left;
		this.right = right;
	}

	public Object getData() {
		return data;
	}

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

	public TreeNode<T> getLeft() {
		return left;
	}

	public void setLeft(TreeNode<T> left) {
		this.left = left;
	}

	public TreeNode<T> getRight() {
		return right;
	}

	public void setRight(TreeNode<T> right) {
		this.right = right;
	}
}

然后,实现二叉树的链表存储,其中获取二叉树的深度为关键操作。

package my.bintree;

public class LinkBinTree<T> {
	private TreeNode<T> root;
	
	public LinkBinTree(TreeNode<T> root){
		this.root = root;
	}
	
	public LinkBinTree(T data){
		this.root = new TreeNode<T>(data);
	}

	public boolean isEmpty(){
		return root == null;
	}
	
	//获取根节点,如果非空
	public TreeNode<T> getRoot(){
		if(isEmpty()){
			throw new RuntimeException("tree is empty");
		}
		
		return this.root;
	}
	
	//获取指定节点(非根节点)的父节点,需要遍历整个二叉树
	public TreeNode<T> getParent(TreeNode<T> node){
		return null;
	}
	
	//返回指定节点(非叶子节点)的左节点的数据,如果左节点不在返回null
	@SuppressWarnings("unchecked")
	public T leftChild(TreeNode<T> parent){
		if(parent == null){
			throw new RuntimeException("节点为空");
		}
		
		return parent.getLeft() == null ? null : (T)parent.getLeft().getData();
	}
	
	//返回指定节点(非叶子节点)的右节点的数据,如果左节点不在返回null
	@SuppressWarnings("unchecked")
	public T rightChild(TreeNode<T> parent){
		if(parent == null){
			throw new RuntimeException("节点为空");
		}
		
		return parent.getRight() == null ? null : (T)parent.getRight().getData();
	}
	
	/**
	 * 为指定节点添加子节点
	 * @param parent 需要添加左右节点的节点
	 * @param data 子节点的数据
	 * @param isLeft 是否为左右节点:true 左节点,false 右节点
	 * @return
	 */
	public TreeNode<T> addNode(TreeNode<T> parent, T data, boolean isLeft){
		if(parent == null){
			throw new RuntimeException("节点为空,不能添加子节点");
		}
		
		if(isLeft && parent.getLeft() != null){
			throw new RuntimeException("节点也有左节点,不能添加子节点");
		}
		
		if(!isLeft && parent.getRight() != null){
			throw new RuntimeException("节点也有右节点,不能添加子节点");
		}
		
		TreeNode<T> newNode = new TreeNode<T>(data);
		if(isLeft){
			parent.setLeft(newNode);
		}else{
			parent.setRight(newNode);
		}
		
		return newNode;
	}
	
	public int getDeep(){
		return getDeep(this.root);
	}
	
	//采用递归的方式来获取节点的深度
	public int getDeep(TreeNode<T> node){
		if(node == null){
			return 0;
		}
		
		if(node.getLeft() == null && node.getRight() == null){
			return 1;
		}else{
			int leftDeep = getDeep(node.getLeft());
			int rightDeep = getDeep(node.getRight());
			int max = leftDeep > rightDeep ? leftDeep : rightDeep;
			//如果该节点有子树,必须计算一次
			return max + 1;
		}
	}
}

最后,编写一个客户端,来时测试二叉树的链表存储是否正确:

package my.bintree;

public class LinkBinTreeClient {
	public static void main(String[] args){
		LinkBinTree<String> tree = new LinkBinTree<String>("root");
		TreeNode<String> b = tree.addNode(tree.getRoot(), "left", true);
		TreeNode<String> c = tree.addNode(tree.getRoot(), "right", false);
		tree.addNode(b,"left",true);
		System.out.println(tree.toString());
		System.out.println(tree.getDeep());
	}
}

控制台输出:

my.bintree.LinkBinTree@1fc4bec
3

注:未复写toString函数

你可能感兴趣的:(object,String,tree,null,存储,Class)