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 ***************************/
}