思路:在增加数据时,保持此树为顺序存储二叉树,然后判断此二叉树是否为平衡二叉树,如果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());
}
}