二叉树的链表存储

来源:互联网 发布:公司域名邮箱收费标准 编辑:程序博客网 时间:2024/06/09 18:36

二叉树的链表存储,就是让每个节点都能保存指向其左右节点的信息。为每个节点添加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函数