思路:在增加数据时,保持此树为顺序存储二叉树,然后判断此二叉树是否为平衡二叉树,如果bf >1 就右旋 bf<-1左旋。在右旋或左旋时,右旋要判断旋转点的右子树高度是否大于左子树高度,如果大于先左旋。左旋要判断旋转点的左子树高度是否大于右子树高度,如果大于先右旋。下一步,将手撕23树,234树,B树,B+树,B*树,红黑树。
class AvlTree { Node root; /** * 增加数值 * @param data */ public void insert(Integer data) { if (root == null) { root = new Node(data); } else { insert(data, null, root, false); } //二叉树如果失去平衡 if (this.bf() > 1) {//右旋 bnm,./ //要判断旋转点的右子树高度是否大于左子树高度,如果大于先左旋 if (this.bf(root.left) < 0) { root.left = leftRotate(root.left, root.left.right); } root = rightRotate(root, root.left); } if (this.bf() < -1) {//右旋 bnm,./ //要判断旋转点的左子树高度是否大于右子树高度,如果大于先右旋 if (this.bf(root.right) > 0) { root.right = rightRotate(root.right, root.right.left); } root = leftRotate(root, root.right); } } public Node rightRotate(Node root, Node rotateNode) { Node tmp = root; root = rotateNode; Node tmp1 = root.right; root.right = tmp; root.right.left = tmp1; return root; } public Node leftRotate(Node root, Node rotateNode) { Node tmp = root; root = rotateNode; Node tmp1 = root.left; root.left = tmp; root.left.right = tmp1; return root; } public void insert(Integer data, Node pre, Node now, boolean isLeft) { if (now == null) { if (isLeft) { Node node = new Node(data); node.setParentLeft(true); node.parent = pre; pre.setLeft(node); } else { Node node = new Node(data); node.setParentRright(true); node.parent = pre; pre.setRight(node); } return; } if (now.data > data) { insert(data, now, now.getLeft(), true); } if (now.data < data) { insert(data, now, now.getRight(), false); } } /** * 获取树的高度 * @return */ public int height() { return height(root); } public int height(Node root) { if (root == null) { return 0; } return Math.max(height(root.left), height(root.right)) + 1; } /** * 是否为平衡二叉树 * @return */ public boolean isBalance() { return isBalance(root); } public boolean isBalance(Node root) { if (root == null) { return true; } if (Math.abs(height(root.left) - height(root.right)) > 1) { return false; } return isBalance(root.left) && isBalance(root.right); } //>1 右旋 <-1左旋 public int bf(Node root) { if (root == null) { return 999; } return height(root.left) - height(root.right); } //>1 右旋 <-1左旋 public int bf() { return bf(root); } /** * 是否为相同的树 * @param avlTree */ public boolean isSame(AvlTree avlTree) { Node otherRoot = avlTree.root; return isSame(root, otherRoot); } public boolean isSame(Node node, Node otherNode) { if (node == null && otherNode == null) { return true; } else if ((node == null && otherNode != null) || (node != null && otherNode == null) ) { return false; } else { if (node.data == otherNode.data) return isSame(node.left, otherNode.right) && isSymmetry(node.right, otherNode.left); else return false; } } /** * 是否为对称的树 * @param avlTree */ public boolean isSymmetry (AvlTree avlTree) { Node otherRoot = avlTree.root; return isSymmetry(root, otherRoot); } public boolean isSymmetry(Node node, Node otherNode) { if (node == null && otherNode == null) { return true; } else if ((node == null && otherNode != null) || (node != null && otherNode == null) ) { return false; } else { if (node.data == otherNode.data) return isSymmetry(node.left, otherNode.right) && isSymmetry(node.right, otherNode.left); else return false; } } } class Node { //节点数值 int data; //左节点 Node left; //右节点 Node right; //父节点 Node parent; //位于父节点的左边 boolean isParentLeft; //位于父节点的右边 boolean isParentRright; public Node(int data) { this.data = data; } public Node getLeft() { return left; } public void setLeft(Node left) { this.left = left; } public Node getRight() { return right; } public void setRight(Node right) { this.right = right; } public Node getParent() { return parent; } public void setParent(Node parent) { this.parent = parent; } public boolean isParentLeft() { return isParentLeft; } public void setParentLeft(boolean parentLeft) { isParentLeft = parentLeft; } public boolean isParentRright() { return isParentRright; } public void setParentRright(boolean parentRright) { isParentRright = parentRright; } }
public class Demo1 { public static void main(String[] args) { AvlTree avlTree = new AvlTree(); avlTree.insert(5); avlTree.insert(2); avlTree.insert(8); avlTree.insert(7); avlTree.insert(6); System.out.println(avlTree.bf()); } }