小伙伴们,你们好呀,我是老寇
1. 二叉搜索树
二叉搜索树就是树上的每一个节点总是比该节点的左节点大,比该节点的右节点小
public class BinarySearchTreeTest {
public static void main(String[] args) {
BinarySearchTree tree = new BinarySearchTree();
tree.add(new Tree(6));
tree.add(new Tree(3));
tree.add(new Tree(8));
tree.add(new Tree(2));
tree.add(new Tree(4));
tree.add(new Tree(7));
tree.add(new Tree(9));
System.out.print("前序遍历:");
tree.pre(tree.rootNode);
System.out.println();
System.out.print("中序遍历:");
tree.mid(tree.rootNode);
System.out.println();
System.out.print("后序遍历:");
tree.pos(tree.rootNode);
}
}
class BinarySearchTree {
public Tree rootNode;
public void add(Tree tree) {
if (rootNode == null) {
rootNode = tree;
} else {
Tree tempNode = rootNode;
while (tempNode != null) {
//插到左节点
if (tempNode.value > tree.value) {
if (tempNode.left != null) {
tempNode = tempNode.left;
} else {
tempNode.left = new Tree(tree.value);
break;
}
}
//插到右节点
if (tempNode.value < tree.value) {
if (tempNode.right != null) {
tempNode = tempNode.right;
} else {
tempNode.right = new Tree(tree.value);
break;
}
}
}
}
}
public void pre(Tree tree) {
if (tree != null) {
System.out.print(tree.value + " ");
pre(tree.left);
pre(tree.right);
}
}
public void mid(Tree tree) {
if (tree != null) {
mid(tree.left);
System.out.print(tree.value + " ");
mid(tree.right);
}
}
public void pos(Tree tree) {
if (tree != null) {
pos(tree.left);
pos(tree.right);
System.out.print(tree.value + " ");
}
}
}
class Tree {
/**
* 左节点
*/
public Tree left;
/**
* 右节点
*/
public Tree right;
/**
* 值
*/
public int value;
public Tree(int value) {
this.value = value;
}
}
/**
* 前序遍历:6 3 2 4 8 7 9
* 中序遍历:2 3 4 6 7 8 9
* 后序遍历:2 4 3 7 9 8 6
*/
2.红黑树
二叉搜索树的升级版,解决顺序插入时,不会像二叉搜索树那样形成链式结构,增加左旋右旋机制,使二叉树基于平衡
public class RedBlackTreeTest {
public static void main(String[] args) {
RedBlackTree redBlackTree = new RedBlackTree();
redBlackTree.add(7);
redBlackTree.add(2);
redBlackTree.add(8);
redBlackTree.add(1);
redBlackTree.add(4);
redBlackTree.add(3);
redBlackTree.add(5);
redBlackTree.add(6);
redBlackTree.pre(redBlackTree.rootNode);
System.out.println();
redBlackTree.mid(redBlackTree.rootNode);
System.out.println();
redBlackTree.pos(redBlackTree.rootNode);
}
}
class RedBlackTree {
public TreeNode rootNode;
public void pre(TreeNode treeNode) {
if (null != treeNode) {
System.out.print(treeNode.value + "-" + (treeNode.color == TreeNode.RED ? "红" : "黑") + " ");
pre(treeNode.left);
pre(treeNode.right);
}
}
public void mid(TreeNode tree) {
if (tree != null) {
mid(tree.left);
System.out.print(tree.value + "-" + (tree.color == TreeNode.RED ? "红" : "黑") + " ");
mid(tree.right);
}
}
public void pos(TreeNode tree) {
if (tree != null) {
pos(tree.left);
pos(tree.right);
System.out.print(tree.value + "-" + (tree.color == TreeNode.RED ? "红" : "黑") + " ");
}
}
public void add(int value) {
TreeNode treeNode = new TreeNode(value, TreeNode.RED);
if (rootNode == null) {
rootNode = treeNode;
rootNode.color = TreeNode.BLACK;
} else {
TreeNode tempNode = rootNode;
do {
if (value > tempNode.value) {
if (tempNode.right != null) {
tempNode = tempNode.right;
} else {
tempNode.right = treeNode;
break;
}
} else {
if (tempNode.left != null) {
tempNode = tempNode.left;
} else {
tempNode.left = treeNode;
break;
}
}
} while (tempNode != null);
treeNode.parent = tempNode;
colorConvert(treeNode);
}
}
/**
* 颜色变换,使整体符合红黑树规则
*/
public void colorConvert(TreeNode node) {
TreeNode parent;
TreeNode grandpa;
//当父结点不为空且颜色为红色
while ((parent = node.parent) != null && parent.color == TreeNode.RED) {
grandpa = parent.parent;
//如果父亲是爷爷的左子树
if (grandpa.left == parent) {
//获取叔叔结点
TreeNode uncle = grandpa.right;
//如果叔叔结点不为空且颜色为红色
if (uncle != null && uncle.color == TreeNode.RED) {
parent.color = TreeNode.BLACK;
uncle.color = TreeNode.BLACK;
grandpa.color = TreeNode.RED;
continue;
}
if (node == parent.right) {
//左旋
leftRotate(parent);
//左旋后父子身份互换
TreeNode temp = node;
node = parent;
parent = temp;
}
parent.color = TreeNode.BLACK;
grandpa.color = TreeNode.RED;
//右旋
rightRotate(grandpa);
}else {
//如果父亲是爷爷的右子树
TreeNode uncle = grandpa.left;
if (uncle != null && uncle.color == TreeNode.RED) {
parent.color = TreeNode.BLACK;
uncle.color = TreeNode.BLACK;
grandpa.color = TreeNode.RED;
node = grandpa;
continue;
}
if (node == parent.left) {
//右旋
rightRotate(parent);
//右旋后父子身份互换
TreeNode temp = node;
node = parent;
parent = temp;
}
parent.color = TreeNode.BLACK;
grandpa.color = TreeNode.RED;
//左旋
leftRotate(grandpa);
}
}
rootNode.color = TreeNode.BLACK;
}
/**
* p p
* / /
* x y
* \ /
* y -> x
* / \
* z z
* 左旋
*/
private void leftRotate(TreeNode node) {
TreeNode right = node.right;
TreeNode parent = node.parent;
if (parent == null) {
rootNode = right;
right.parent = null;
}else {
if (parent.left != null && parent.left == node) {
parent.left = right;
}else {
parent.right = right;
}
right.parent = parent;
}
node.parent = right;
node.right = right.left;
if (right.left != null) {
right.left.parent = node;
}
right.left = node;
}
/**
* p p
* / /
* y x
* / \
* x -> y
* \ /
* z z
* 右旋
*/
private void rightRotate(TreeNode node) {
TreeNode left = node.left;
TreeNode parent = node.parent;
if (parent == null) {
rootNode = left;
left.parent = null;
} else {
if (parent.left != null && parent.left == node) {
parent.left = left;
} else {
parent.right = left;
}
}
node.parent = left;
node.left = left.right;
if (left.right != null) {
left.right.parent = node;
}
left.right = node;
}
}
class TreeNode {
public int value;
public static final boolean RED = true;
public static final boolean BLACK = false;
public boolean color;
public TreeNode left;
public TreeNode right;
public TreeNode parent;
public TreeNode(int value,boolean color) {
this.value = value;
this.color = color;
}
}
/**
* 4-黑 2-红 1-黑 3-黑 7-红 5-黑 6-红 8-黑
* 1-黑 2-红 3-黑 4-黑 5-黑 6-红 7-红 8-黑
* 1-黑 3-黑 2-红 6-红 5-黑 8-黑 7-红 4-黑
*/