Java笔记1-常用数据结构和算法

小伙伴们,你们好呀,我是老寇

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

评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值