平衡二叉树的相关操作
结点的相关代码
public class Node implements Comparable<Node> {
Node left;
Node right;
int value;
public Node() {
super();
}
// public int height() {
// return Math.max(left == null ? 0 : left.height(), right == null ? 0 : right.height()) + 1;
// }
public Node(int value) {
super();
this.value = value;
}
@Override
public String toString() {
return "Node [value=" + value + "]";
}
@Override
public int compareTo(Node node) {
// 从小到大排
return this.value - node.value;
}
}
下面是二叉树的相关操作
package avl;
import java.util.Arrays;
public class AVLTree {
Node root;
int count = 0;// 统计结点个数
/**
* 获取当前树的高度
*
* @param node
* @return
*/
public int getHight(Node node) {
if (node == null) {
return 0;
}
int l = 0, r = 0;
l = getHight(node.left);
r = getHight(node.right);
return (l > r) ? l + 1 : r + 1;
}
public void add(int i) {
if (root == null) {
this.root = new Node(i);
} else {
addNode(this.root, new Node(i));
}
count++;// 计算结点个数
}
/**
*
* @param mid 中序遍历的结点的数组
* @param aft 后序遍历的结点的数组
* @return 返回根节点
*/
public Node rebuild(int[] mid, int[] aft) {
int len = mid.length, index = 0;
if (mid == null || aft == null || len == 0) {
return null;
}
for (int i = 0; i < len; i++) {
if (mid[i] == aft[len - 1]) {
index = i;
break;
}
}
Node node = new Node(mid[index]);
if (index == len) {
return null;
}
if (index > 0) {
System.out.println(index);
int[] arr1 = Arrays.copyOfRange(mid, 0, index);
int[] arr2 = Arrays.copyOfRange(aft, 0, index);
node.left = rebuild(arr1, arr2);
}
if (len - index - 1 > 0) {
int[] arr1 = Arrays.copyOfRange(mid, index + 1, len);
int[] arr2 = Arrays.copyOfRange(mid, index + 1, len);
node.right = rebuild(arr1, arr2);
}
return node;
}
/**
* 添加结点
*
* @param node1 原树中的结点
* @param node2 待添加的结点
*/
public void addNode(Node node1, Node node2) {
if (node2 == null || node1 == null) {
System.out.println("空结点不可以插入数据");
return;
}
if (node1.value > node2.value) {
if (node1.left == null) {
node1.left = node2;
} else {
addNode(node1.left, node2);
}
} else {
if (node1.right == null) {
node1.right = node2;
} else {
addNode(node1.right, node2);
}
}
//
// node1的左子树长度与右子树的长度差大于1 node1需要右旋
if (getHight(node1.left) - getHight(node1.right) > 1) {
// node1左子树的右子树与其左子树的长度差大于0 node1左子树需要左旋,再进行右旋
if (node1.left != null && getHight(node1.left.right) > getHight(node1.left.left)) {
leftRotate(node1.left);
rightRotate(node1);
} else {// 直接进行右旋
rightRotate(node1);
}
// node1的右子树长度与左子树的长度差大于1 node1需要左旋
} else if (getHight(node1.right) - getHight(node1.left) > 1) {
// node1右子树的右子树与其左子树的长度差大于0 node1左子树需要右旋,再进行左旋
if (node1.right != null && getHight(node1.right.left) > getHight(node1.right.right)) {
rightRotate(node1.right);// 先对其子结点进行右旋
leftRotate(node1);
} else {// 直接进行左旋
leftRotate(node1);
}
}
}
public Node searchParent(int value) {
return searchParent(root, value);
}
/**
* 搜索值为value 的结点的父结点
*
* @param node 从node 结点开始检索
* @param value 要检索父结点的结点的值
* @return
*/
public Node searchParent(Node node, int value) {
// 表示当前结点就是此结点,该值所在的结点没有父结点
if (node != null && node.value == value) {
return null;
}
// 判断该node 的子结点的值是否和value 相等,相等则表示
if ((node.left != null && node.left.value == value) || (node.right != null && node.right.value == value)) {
return node;
} else {
if (node.left != null && node.value > value) {
return searchParent(node.left, value);
} else if (node.right != null && node.value <= value) {
return searchParent(node.right, value);
} else {
System.out.println("没有这个结点");
return null;
}
}
}
public Node search(int value) {
return search(root, value);
}
/**
* 收索结点
*
* @param node 从node结点开始向下搜索
* @param value 置为value 的结点
* @return
*/
public Node search(Node node, int value) {
if (node == null) {
System.out.println("根节点为空");
return null;
}
if (node.value == value) {
return node;
} else if (node.value > value) {
return search(node.left, value);
} else if (node.value <= value) {
return search(node.right, value);
} else {
System.out.println("没有该结点");
return null;
}
}
/**
* 删除结点
*
* @param value
*/
public void deleteNode(int value) {
Node node = search(value);
if (node == null || root == null) {
return;
}
// 就一个结点的情况
if (root.left == null && root.right == null) {
root = null;
return;
}
// 删除叶子结点
Node paNode = searchParent(value);
if (node.left == null && node.right == null) {
if (paNode.left != null && paNode.left.value == value) {
paNode.left = null;
}
if (paNode.right != null && paNode.right.value == value) {
paNode.right = null;
}
} else if (node.left != null && node.right != null) {// 删除的结点有两个结点
Node tempNode = node.right;
while (tempNode.left != null) {
tempNode = tempNode.left;
}
int k = tempNode.value;
deleteNode(tempNode.value);
node.value = k;
} else {// 删除只有一个结点的结点
if (node.left != null) {// 左节点不为空
if (paNode == null) {
root = node;
} else {
if (paNode.left.value == value) {// 该结点为父结点的左子树
paNode.left = node.left;
} else if (paNode.right.value == value) {// 该结点为父结点的右子树
paNode.right = node.left;
}
}
} else {// 右结点不为空
if (paNode == null) {
root = node;
} else {
if (paNode.left.value == value) {// 该结点为父结点的左子树
paNode.left = node.right;
} else if (paNode.right.value == value) {// 该结点为父结点的右子树
paNode.right = node.right;
}
}
}
}
}
// 左旋
public void leftRotate(Node node) {
if (node == null) {
System.out.println("结点为空不可以旋转");
return;
}
// 以当前结点的值新建一个结点
Node newNode = new Node(node.value);
// 新结点的左子结点连接当前结点的左孩子
newNode.left = node.left;
// 新结点的右子结点连接当前结点的右子结点的左子结点
newNode.right = node.right.left;
// 让当前结点的值等于当前结点的右子结点的值
node.value = node.right.value;
// 当前结点的右子结点等于当前结点的右子结点的右结点
node.right = node.right.right;
// 当前结点的左子结点连接新结点
node.left = newNode;
}
//右旋
public void rightRotate(Node node) {
if (node == null) {
System.out.println("结点为空不可以旋转");
return;
}
// 以当前结点的值新建一个结点
Node newNode = new Node(node.value);
// 新结点的右子结点连接当前结点的右孩子
newNode.right = node.right;
// 新结点的左子结点连接当前结点的左子结点的右子结点
newNode.left = node.left.right;
// 让当前结点的值等于当前结点的左子结点的值
node.value = node.left.value;
// 当前结点的左子结点等于当前结点的左子结点的左子结点
node.left = node.left.left;
// 当前结点的右子结点连接新结点
node.right = newNode;
}
// 前序遍历
public void preOrder(Node node) {
if (node == null) {
return;
}
System.out.println(node);
preOrder(node.left);
preOrder(node.right);
}
// 中序遍历
public void inOrder(Node node) {
if (node == null) {
return;
}
inOrder(node.left);
System.out.println(node);
inOrder(node.right);
}
// 后序遍历
public void postOrder(Node node) {
if (node == null) {
return;
}
postOrder(node.left);
postOrder(node.right);
System.out.println(node);
}
// 层序遍历
public void levelOrder(Node node) {
Node[] nodes = new Node[count];
int front = 0;// 数组的前标
int rear = 0;// 数组的后标
if (node == null) {
return;
}
nodes[rear++] = node;// 先把根节点放进去
while (front != rear) {
Node node2 = nodes[front++];// 取出来
System.out.println(node2);
if (node2.left != null) {// 判断左子树,然后把子树放进去
nodes[rear++] = node2.left;
}
if (node2.right != null) {// 判断左子树,然后把子树放进去
nodes[rear++] = node2.right;
}
}
}
}