1、排序二叉树特点
1)根节点的值大于等于左子树的节点。
2)根节点的值小于等于它右子树的节点。

2、遍历二叉树的方法
1)先序遍历:先遍历根节点,然后遍历左子树,再遍历右子树
2)中序遍历:先遍历左子树,然后遍历根节点,再遍历右子树
3)后续遍历

如果要保证节点从小到大排序,采用 中序遍历;
目前代码中,已经实现 新增单个元素、删除单个元素、中序遍历整颗树。

package persistent.prestige.study.datastructures.tree;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;


/**
 * 二叉树学习
 * 
 在数据结构里,
就是对一棵二叉树所有结点的访问
前序遵循“根左右”
中序遵循“左根右”
后序遵循“左右根”
根:根节点
左:左子女
右:右子女
如:一棵二叉树 :
           A
          / \
         B   C
        / \ 
       D   E
前序访问顺序就是:ABDEC(根一定第一个)
中序访问顺序就是:DBEAC(根一定在中间)
后序访问顺序就是:DEBCA(根一定在最后)


 * 
 * 
 * 
 * @author prestigeding@126.com
 *
 */
public class BinaryTree<E> implements Serializable {

    /**
     * 
     */
    private static final long serialVersionUID = -3970337667739333043L;

    private Comparator<E> comparator;

    private TreeNode<E> root;

    public BinaryTree() {
    }

    public BinaryTree(Comparator<E> comparator) {
        super();
        this.comparator = comparator;
    }

    /**
     * 增加元素
     * @param e
     * @return
     */
    public boolean add(E e) {
        if(e == null) return false;

        if(root == null ) {
            root = new TreeNode<E>(e, null);
            return true;
        }

        add0(root, e);
        return true;
    }


    /**
     * 
     * 
     *                          10
     *                     /          \
     *                    3           18
     *                  /   \        /   \               
     *                 2     4      13    21       
     *                         \
     *                          9
     *                        /   \
     *                       8     9 
     * 
     * 
     * @param root
     * @param e
     */
    private TreeNode<E> add0(TreeNode<E> root, E e) {
        final TreeNode<E> curNode = root;

        int cmp = compare(e, curNode.value);
        if(cmp < 0 ) { //表示待插入的节点值,比当前节点值小
            if(curNode.left == null) {
                //创建当前节点的左节点
                TreeNode<E> newNode = new TreeNode<E>(e, curNode);
                curNode.left = newNode;
                return newNode;
            } else {
                return add0(curNode.left, e);//遍历左子树
            }
        } else { // 大于等于0,右子树
            if(curNode.right == null ) {
                //创建当前节点的右节点
                TreeNode<E> newNode = new TreeNode<E>(e, curNode);
                curNode.right = newNode;
                return newNode;
            } else {
                return add0(curNode.right, e);//遍历右子树
            }

        }
    }

    /**
     * 比较两个元素的大小
     * @param e1
     * @param e2
     * @return
     */
    @SuppressWarnings("unchecked")
    private int compare(E e1, E e2) {
        return comparator == null ?  ((Comparable<E>) e1 ).compareTo(e2) : comparator.compare(e1, e2);  
    }


    /**
     * 
     * 删除元素
     * @param e  
     * @return  如果返回ture,表示删除成功,如果返回false,表示删除失败,没有找到元素
     */
    public boolean remove(E e) {
        if( e == null ) return false;

        TreeNode<E> cur = root;
        int cmp;
        while (cur != null ) {
            if(e.equals(cur.value)) {
                break;
            }
            cmp = compare(e, root.value);
            if(cmp < 0 ) { //表示待删除的节点值,比当前节点值小
                cur = cur.left;
            } else {
                cur = cur.right;
            }

        }

        if(cur != null ) { //找到了元素,需要删除该元素
            TreeNode<E> cLeft = cur.left;
            TreeNode<E> cRight = cur.right;

            if(cLeft != null ) { //如果被删除节点的左子树不为空,则将左子树放入当前节点的位置
                remove0(cLeft, cur);
                if(cLeft.right != null &&  cur.right != null) { //需要移动相应节点
                    TreeNode<E> wNode = cLeft.right;
                    cLeft.right = cur.right;
                    wNode.parent = null;
                    TreeNode<E> newNode = add0(cLeft, wNode.value);
                    newNode.left = wNode.left;
                    newNode.right = wNode.right;
                    wNode = null;
                }

            } else {
                remove0(cRight, cur);
            }

            //将当前节点释放,,help GC
            cur.value = null;
            cur.right = null;
            cur.left = null;
            cur.parent = null;
            cur = null;

            return true;

        }
        return false;



    }

    private void remove0(TreeNode<E> newNode, TreeNode<E> cur) {
        TreeNode<E> parent = cur.parent;
        newNode.parent = parent;
        if(cur.parent.left == cur) {
            cur.parent.left = newNode;
        } else {
            cur.parent.right = newNode;
        }
    }

    /**
     * 中序遍历
     */
    public void middleOrderTraversal() {
        System.out.println("----------中序遍历开始---------\n");
        if (root == null) {
            System.out.print("二叉树");
            System.out.println("----------中序遍历结束---------\n");
            return;
        }

        middleOrderTraversal0(root);

        System.out.println("\n----------中序遍历结束---------\n");

    }

    /**
     * 中序遍历
     */
    private void middleOrderTraversal0(TreeNode<E> root) {
        if (root == null)
            return;

        final TreeNode<E> cur = root;
        if (cur.left != null) {
            middleOrderTraversal0(cur.left);
            System.out.print(toObjectString(cur.value) + ",");
            middleOrderTraversal0(cur.right);
        } else if (cur.right != null) {
            System.out.print(cur.value + ",");
            middleOrderTraversal0(cur.right);
        } else {
            // 此时输出节点
            System.out.print(cur.value + ",");
        }

    }

    public TreeNode<E> getRoot() {
        return root;
    }

    public void setRoot(TreeNode<E> root) {
        this.root = root;
    }

    private String toObjectString(E value) {
        return value == null ? "" : value.toString();
    }

    /**
     * 二叉数
     * 
     * @author Administrator
     *
     * @param <E>
     */
    @SuppressWarnings("unused")
    private final static class TreeNode<E> implements Serializable {

        private static final long serialVersionUID = 6540618639489225256L;

        public E value;
        public TreeNode<E> left;
        public TreeNode<E> right;

        public TreeNode<E> parent;

        public TreeNode(E value, TreeNode<E> parent) {
            super();
            this.value = value;
            this.parent = parent;
        }

        public TreeNode(E value, TreeNode<E> left, TreeNode<E> right, TreeNode<E> parent) {
            super();
            this.value = value;
            this.left = left;
            this.right = right;
            this.parent = parent;
        }

        @Override
        public String toString() {
            if(value != null)
                return value.toString();

            return super.toString();
        }



    }

    /** *******************测试 start ***************************/
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        System.out.println("测试开始");

//      BinaryTree<Integer> t = new BinaryTree<Integer>();
//      t.setRoot(t.initTree());
//      t.middleOrderTraversal();

        //先研究一下 Comparator o1 > o2 的排序逻辑
        //testSort();

/*       *                          10
         *                     /              \
         *                    3                18
         *                  /   \            /   \               
         *                 2     4          13    21       
         *                         \       /  \  
         *                          9     11    15  
         *                        /   \
         *                       8     9 
*/

        // add 方法测试
        BinaryTree<Integer> t = new BinaryTree<Integer>();

//      t.add(new Integer(10));
//      t.add(new Integer(18));
//      t.add(new Integer(3));
//      t.add(new Integer(2));
//      t.add(new Integer(4));
//      t.add(new Integer(8));
//      t.add(new Integer(9));
//      t.add(new Integer(9));
//      t.add(new Integer(21));
//      t.add(new Integer(13));


        t.add(new Integer(10));
        t.add(new Integer(18));
        t.add(new Integer(3));
        t.add(new Integer(9));
        t.add(new Integer(8));
        t.add(new Integer(2));
        t.add(new Integer(21));
        t.add(new Integer(4));
        t.add(new Integer(9));
        t.add(new Integer(13));
        t.add(new Integer(11));
        t.add(new Integer(15));

        //查看数结构,中序遍历
        t.middleOrderTraversal();


        //测试删除
        System.out.println("删除节点18");
        t.remove(new Integer(18));
        System.err.println("删除节点18号的排序二叉树");
        t.middleOrderTraversal();

        System.out.println("测试结束");
    }

    /**
     * 当用升序排序时,则 o1 > o2 时要返回大于0的数
     */
    public static void testSort() {

        List<Integer> a = new ArrayList<Integer>();
        a.add(1);
        a.add(8);
        a.add(9);
        a.add(3);
        a.add(5);

        Collections.sort(a, new Comparator<Integer>() {

            @Override
            public int compare(Integer o1, Integer o2) {

                return o1.intValue() > o2.intValue() ? 1 : -1;
            }

        });

        System.out.println(a);

    }

    /**
     * 用来测试的,后续会完善 加入元素
     * 
     * 
     *                          
     *                          10
     *                     /          \
     *                    3           18
     *                  /   \        /   \               
     *                 2     4      13    21       
     *                         \
     *                          9
     *                        /   \
     *                       8     9 
     *                       
     *                       

     * @return
     */
    @Deprecated
    public TreeNode<Integer> initTree() {
        TreeNode<Integer> _root = new TreeNode<Integer>(new Integer(10), null); // 根节点

        TreeNode<Integer> l3 = new TreeNode<Integer>(new Integer(3), _root);
        _root.left = l3;

        TreeNode<Integer> l2 = new TreeNode<Integer>(new Integer(2), l3);
        l3.left = l2;

        TreeNode<Integer> l4 = new TreeNode<Integer>(new Integer(4), l3);
        l3.right = l4;

        TreeNode<Integer> l91 = new TreeNode<Integer>(new Integer(9), l4);
        l4.right = l91;

        TreeNode<Integer> l8 = new TreeNode<Integer>(new Integer(8), l91);
        l91.left = l8;

        TreeNode<Integer> l92 = new TreeNode<Integer>(new Integer(9), l91);
        l91.right = l92;

        TreeNode<Integer> l18 = new TreeNode<Integer>(new Integer(18), _root);
        _root.right = l18;

        TreeNode<Integer> l13 = new TreeNode<Integer>(new Integer(13), l18);
        l18.left = l13;

        TreeNode<Integer> l21 = new TreeNode<Integer>(new Integer(21), l18);
        l18.right = l21;

        return _root;


    }

    /** *******************测试 end ***************************/

}