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

【数据结构】二叉树的Java实践

时间:2015-09-09 11:17:40      阅读:176      评论:0      收藏:0      [点我收藏+]

标签:

二叉树,是常用的树之一。

性质:

  • 每个节点最多有2个节点(即度最大为2)
  • 有左、右节点(或左、右子树)之分,且节点有顺序之分(即左、右不能随意调换)

 

下面对二叉树做最简单的Java实践。

> 二叉树的Java实践

树节点

技术分享
package com.nicchagil.btree;

public class TreeNode {

    private Integer value;
    private TreeNode left;
    private TreeNode right;
    
    public TreeNode(Integer value) {
        super();
        this.value = value;
    }

    public Integer getValue() {
        return value;
    }

    public void setValue(Integer value) {
        this.value = value;
    }

    public TreeNode getLeft() {
        return left;
    }

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

    public TreeNode getRight() {
        return right;
    }

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

}
View Code

 

二叉树

技术分享
package com.nicchagil.btree;

/**
 * 二叉树
 */
public class BinaryTree {
    
    // 根节点
    private TreeNode root = null;
    
    /**
     * 插入节点
     */
    public boolean put(Integer value) {
        if (value == null) {
            return false;
        }
        
        if (root == null) {
            root = new TreeNode(value);
        }
        this.putNode(root, value);
        return true;
    }
    
    /**
     * 是否存在该值
     * @param value    值
     */
    public boolean contains(Integer value) {
        return scan(root, value);
    }
    
    private void putNode(TreeNode node, Integer value) {
        int result = this.compare(node.getValue(), value);
        
        /* 放左边 */
        if (result == 1) {
            if (node.getLeft() == null) {
                node.setLeft(new TreeNode(value));
            } else {
                this.putNode(node.getLeft(), value);
            }
        }
        /* 放右边 */
        else if (result == -1) {
            if (node.getRight() == null) {
                node.setRight(new TreeNode(value));
            } else {
                this.putNode(node.getRight(), value);
            }
        }
    }
    
    private boolean scan(TreeNode node, Integer value) {
        if (node == null) {
            return false;
        }
        
        int result = this.compare(node.getValue(), value);
        boolean remoteFlag = false;
        if (result == 0) {
            return true;
        } else if (result == 1) {
            remoteFlag = this.scan(node.getLeft(), value);
        } else {
            remoteFlag = this.scan(node.getRight(), value);
        }
        
        return remoteFlag;
    }
    
    public int compare(Integer nodeValue, Integer newValue) {
        return Integer.compare(nodeValue, newValue);
    }

    public TreeNode getRoot() {
        return root;
    }
    
}
View Code

 

> 打印二叉树。这是第一次写时犯的错误的示范。不删,以作借镜。重新写的见下文

(这是错误的,不删,以作借镜。重新写的见下文这个不是业务类,用于打印整棵树的形状的,就是查看树直观点

技术分享
package com.nicchagil.btree;

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

public class BinaryTreePrinter {
    
    public static void print(BinaryTree bt) {
        if (bt == null || bt.getRoot() == null) {
            return;
        }
        
        List<StringBuffer> list = new ArrayList<StringBuffer>();
        
        /* 格式化根节点,及根节点左边树 */
        Integer level = 1;
        TreeNode node = bt.getRoot();
        StringBuffer sb = null;
        while (node != null) {
            sb = new StringBuffer();
            sb.append(node.getValue());
            list.add(sb);
            formatLeftDisplay(list, level, node.getValue());
            
            node = node.getLeft();
            level++;
        }
        
        /* 格式化根节点右边树 */
        level = 1;
        node = bt.getRoot();
        while (node != null) {
            if (node != bt.getRoot()) {
                formatRightDisplay(list, bt.getRoot(), level, node.getValue());
            }
            
            node = node.getRight();
            level++;
        }
        
        /* 将格式化好的数据打印出来 */
        for (StringBuffer temp : list) {
            System.out.println(temp);
        }
    }
    
    private static void formatLeftDisplay(List<StringBuffer> list, Integer level, Integer value) {
        if (list == null || list.size() == 0) {
            return;
        }
        
        String blank = replaceToBlank(value);
        
        for (int i = 0; i < level - 1; i++) {
            list.get(i).insert(0, blank);
        }
    }
    
    private static void formatRightDisplay(List<StringBuffer> list, TreeNode root, Integer level, Integer value) {
        if (list == null || list.size() == 0) {
            return;
        }
        
        Integer charCount = 0;
        Integer currentLevel = 2;
        TreeNode node = root.getLeft();
        while (currentLevel < level && node != null) {
            charCount += node.getValue().toString().length();
            node = node.getLeft();
            
            currentLevel++;
        }
        
        charCount += root.getValue().toString().length();
        
        currentLevel = 2;
        node = root.getRight();
        while (currentLevel < level && node != null) {
            charCount += node.getValue().toString().length();
            node = node.getRight();
            
            currentLevel++;
        }
        
        if (list.size() >= level) {
            list.get(level - 1).append(buildBlank(charCount)).append(value);
        } else {
            list.add(new StringBuffer().append(buildBlank(charCount)).append(value));
        }
    }

    private static String replaceToBlank(Integer value) {
        if (value == null) {
            return "";
        }
        return buildBlank(value.toString().length());
    }
    
    private static String buildBlank(int len) {
        StringBuffer sb = new StringBuffer();
        while (len != 0) {
            sb.append(" ");
            len--;
        }
        return sb.toString();
    }
    
}
View Code

 

测试类

技术分享
package com.nicchagil.btree;

public class Call {

    public static void main(String[] args) {
        BinaryTree bt = new BinaryTree();
        bt.put(3);
        bt.put(2);
        bt.put(1);
        bt.put(4);
        bt.put(5);
        bt.put(-28);
        bt.put(35);
        bt.put(47);
        bt.put(50);
        bt.put(65);
        bt.put(-78);
        bt.put(91);
        bt.put(99);
        bt.put(-88);
        bt.put(75);
        bt.put(67);
        bt.put(70);
        bt.put(45);
        bt.put(-38);
        bt.put(21);
        
        System.out.println("binary tree -> ");
        BinaryTreePrinter.print(bt);
        
        System.out.println("whether contains -> " + bt.contains(47));
    }

}
View Code

 

(这是错误的,不删,以作借镜。重新写的见下文)日志

技术分享
binary tree -> 
           3
          2 4
         1   5
      -28     35
   -78          47
-88               50
                    65
                      91
                        99
whether contains -> true
View Code

 

> 将二叉树打印出来看看?

发现上述打印二叉树有致命的错误,看打印出来的日志就知道了,哈哈(>_<)

换种思路重新写打印类

技术分享
package com.nicchagil.btree;

import java.util.HashMap;
import java.util.Map;

public class BinaryTreePrinter {
    
    /*
     * 程序会将tree数据转换成如下坐标
     * -n               0                n
     * ----------------------------------->
     *                  |
     *                  |
     *                  |
     *                  |
     *                  |
     *                  |
     *                  |
     *                  | h
     *                  v
     */
    
    private int leftIndexForX = 0; // 树最左节点的坐标,即-n
    private int rightIndexForX = 0; // 树最左节点的坐标,即n
    private int indexForY = 0; // 树最深节点的坐标,即h,正整数
    private Map<TreeNode, Index> map = new HashMap<TreeNode, Index>(); // key-树节点;value-x、y轴坐标
    
    public void print(BinaryTree bt) {
        if (bt == null || bt.getRoot() == null) {
            return;
        }
        
        // 根节点
        this.map.put(bt.getRoot(), new Index(0, 0));
        // 左边树遍历
        if (bt.getRoot().getLeft() != null) {
            this.getLeftest(bt.getRoot().getLeft(), -1, 1);
        }
        // 右边树遍历
        if (bt.getRoot().getRight() != null) {
            this.getRightest(bt.getRoot().getRight(), 1, 1);
        }
        
        /* 转换成数组 */
        int len = this.rightIndexForX - this.leftIndexForX;
        String[][] treeData = new String[this.indexForY + 1][len];
        
        int SHIFT = 0 - this.leftIndexForX;
        Index index = null;
        for (TreeNode node : this.map.keySet()) {
            index = this.map.get(node);
            
            treeData[index.getY()][SHIFT + index.getX()] = node.getValue().toString();
        }
        
        /* 将树以数组形式打印 */
        String[] treeRowData = null;
        String data = null;
        for (int i = 0; i < treeData.length; i++) {
            treeRowData = treeData[i];
            for (int j = 0; j < treeRowData.length; j++) {
                if (treeRowData[j] == null) {
                    data = "     ";
                } else {
                    data = this.fillBlankBeforeValue(treeRowData[j], 5);
                }
                System.out.print(data + " ");
            }
            
            /* 换两行树结构较明显 */
            System.out.println();
            System.out.println();
        }
    }
    
    /**
     * 设置最左、最深坐标
     */
    private synchronized void setMaxLeftHeightIndex(Index i) {
        if (i.getX() < leftIndexForX) {
            leftIndexForX = i.getX();
        }
        if (i.getY() > indexForY) {
            indexForY = i.getY();
        }
    }
    
    /**
     * 设置最右、最深坐标
     */
    private synchronized void setMaxRightHeightIndex(Index i) {
        if (i.getY() > rightIndexForX) {
            rightIndexForX = i.getY();
        }
        if (i.getY() > indexForY) {
            indexForY = i.getY();
        }
    }
    
    /**
     * 左边树遍历
     */
    private void getLeftest(TreeNode node, int xIndex, int yIndex) {
        Index i = new Index(xIndex, yIndex);
        map.put(node, i);
        
        if (node.getLeft() != null) {
            this.getLeftest(node.getLeft(), xIndex - 1, yIndex + 1);
        } else {
            this.setMaxLeftHeightIndex(i);
        }
        
        if (node.getRight() != null) {
            this.getLeftest(node.getRight(), xIndex + 1, yIndex + 1);
        }
    }
    
    /**
     * 右边树遍历
     */
    private void getRightest(TreeNode node, int xIndex, int yIndex) {
        Index i = new Index(xIndex, yIndex);
        map.put(node, new Index(xIndex, yIndex));
        
        if (node.getRight() != null) {
            this.getRightest(node.getRight(), xIndex + 1, yIndex + 1);
        } else {
            this.setMaxRightHeightIndex(i);
        }
        
        if (node.getLeft() != null) {
            this.getRightest(node.getLeft(), xIndex - 1, yIndex + 1);
        }
    }
    
    /**
     * 坐标类
     */
    class Index {
        int x;
        int y;
        
        public Index(int x, int y) {
            super();
            this.x = x;
            this.y = y;
        }

        public int getX() {
            return x;
        }

        public int getY() {
            return y;
        }
    }
    
    /**
     * 前补空格
     */
    private String fillBlankBeforeValue(String v, int len) {
        StringBuffer sb = new StringBuffer();
        sb.append(v);
        while (sb.length() < len) {
            sb.insert(0, " ");
        }
        return sb.toString();
    }
    
}
View Code

 

测试类

技术分享
package com.nicchagil.btree;

public class Call {

    public static void main(String[] args) {
        BinaryTree bt = new BinaryTree();
        bt.put(3);
        bt.put(2);
        bt.put(1);
        bt.put(4);
        bt.put(5);
        bt.put(-28);
        bt.put(35);
        bt.put(47);
        bt.put(50);
        bt.put(65);
        bt.put(-78);
        bt.put(91);
        bt.put(99);
        bt.put(-88);
        bt.put(75);
        bt.put(67);
        bt.put(70);
        bt.put(45);
        bt.put(-38);
        bt.put(21);
        
        System.out.println("binary tree -> ");
        new BinaryTreePrinter().print(bt);
        
        System.out.println("whether contains -> " + bt.contains(47));
    }

}
View Code

 

日志

技术分享
binary tree -> 
                                  3                                                       

                            2           4                                                 

                      1                       5                                           

              -28                                  35                                     

        -78                                  21          47                               

  -88         -38                                  45          50                         

                                                                     65                   

                                                                           91             

                                                                     75          99       

                                                               67                         

                                                                     70                   

whether contains -> true
View Code

 

【数据结构】二叉树的Java实践

标签:

原文地址:http://www.cnblogs.com/nick-huang/p/4792133.html

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