有关平衡二叉树的概念以及平衡二叉树的旋转操作:平衡二叉树
下边看java代码的实现。其实原来人家用c#已经实现过了,我只是改成java版的(说实话,刚开始看他写的代码的时候,我以为是java)
class Node {
int data;//数据
int BF;//平衡因子
Node leftChild;//左娃娃
Node rightChild;//右娃娃
public Node(int data) {
super();
this.data = data;
}
}
public class 平衡二叉树的建立 {
private static Node head;//表示头节点
private static Node[] path = new Node[32];//记录访问路径上的节点
private static int p ;//表示当前访问到的节点在path中的索引
public static boolean addNode(int value){
if(head == null){
head = new Node(value);
//不要忘了平衡因子的修改
head.BF = 0;//刚开始head的平衡因子为0
return true;
}
p = 0;
Node prev = null;//上一次访问到的节点
Node current = head;//当前访问的节点
//寻找插入位置
while(current != null){
path[p++] = current;
if(current.data == value){
return false;//若value与当前数据相同,则返回false,无需插入
}
prev = current;
//当前值小于左孩子,继续访问左孩子
//否则访问右孩子
current = (value < prev.data) ? prev.leftChild : prev.rightChild;
}
current = new Node(value);
//不要忘了平衡因子的修改current.BF = 0
current.BF = 0;
if(value < prev.data){
prev.leftChild = current;
}else{
prev.rightChild = current;
}
path[p] = current;//将当前节点插入到path中的最后
int bf = 0;
//修改插入节点至根节点路径上的各个节点的平衡因子
while( p > 0){
bf = (value < path[p-1].data) ? 1 : -1;
path[--p].BF += bf;
bf = path[p].BF;//取出当前的平衡因子
//若当前平衡因子为0,则表示该子树已平衡,无需递归了
//若为2或者-2,表示要对改子树进行旋转操作
if( bf == 0){
return true;
}
else if(bf == 2 || bf == -2){
旋转(bf);
return true;
}
}
return true;
}
//对树的旋转操作
private static boolean 旋转(int bf) {
Node root = path[p];
Node newRoot = null;
boolean tallChange = true;
if(bf == 2){
if(root.leftChild.BF == 1){//进行LL旋转操作()
newRoot = LL(root);
}else if(root.leftChild.BF == -1){//进行LR旋转操作
newRoot = LR(root);
}
}else if(bf == -2){
if(root.rightChild.BF == -1){//进行RR旋转操作
newRoot = RR(root);
}else if(root.rightChild.BF == 1){
newRoot = RL(root);
}
}
//更改新的子树
if(p > 0){
if(root.data < path[p-1].data){
path[p-1].leftChild = newRoot;
}else{
path[p-1].rightChild = newRoot;
}
}else{
head = newRoot;
}
return tallChange;
}
private static Node RL(Node root) {
Node rootNext = root.rightChild;
Node newRoot = rootNext.leftChild;
root.rightChild = newRoot.leftChild;
rootNext.leftChild = newRoot.rightChild;
newRoot.leftChild = root;
newRoot.rightChild = rootNext;
switch (newRoot.BF) {
case 1:
root.BF = 0;
rootNext.BF = -1;
break;
case -1:
root.BF = 1;
rootNext.BF=0;
break;
}
return newRoot;
}
private static Node RR(Node root) {//RR型旋转操作
Node rootNext = root.rightChild;
root.rightChild = rootNext.leftChild;
rootNext.leftChild = root;
//不要忘了平衡因子的修改
if(rootNext.BF == -1){
rootNext.BF = 0;
root.BF = 0;
}
return rootNext;
}
private static Node LR(Node root) {
Node rootNext = root.leftChild;
Node newRoot = rootNext.rightChild;
root.leftChild = newRoot.rightChild;
rootNext.rightChild = newRoot.leftChild;
newRoot.leftChild = rootNext;
newRoot.rightChild = root;
//改变平衡因子
switch (newRoot.BF) {
case 1:
root.BF = -1;
rootNext.BF = 0;
break;
case -1:
root.BF = 0;
rootNext.BF = 1;
break;
}
newRoot.BF = 0;
return newRoot;
}
private static Node LL(Node root) {//LL型旋转操作
Node rootNext = root.leftChild;
root.leftChild = rootNext.rightChild;
rootNext.rightChild = root;
//旋转后不要忘了平衡因子的修改
if(rootNext.BF == 1){
rootNext.BF = 0;
root.BF = 0;
}
return rootNext;
}
public static void main(String[] args) {
addNode(1);
addNode(2);
addNode(3);
addNode(4);
addNode(5);
addNode(6);
addNode(7);
print(head);
}
private static void print(Node root) {//按照先序遍历 肯定是顺序输出,即为1,2,3,4,5,6,7
if(root.leftChild !=null){
print(root.leftChild);
}
System.out.println(root.data);
if(root.rightChild!=null){
print(root.rightChild);
}
}
}