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