平衡二叉树的实现:
程序输出结果为:
前序遍历结果:
8 5 2 7 6 9 69
中序遍历结果
2 5 6 7 8 9 69
两种遍历结果可以唯一确定一颗二叉树,从而得出二叉树如下图所示:为一颗平衡二叉树。
代码如下所示:
package AlgorithmTest;
/**
* Created by dell on 2016/12/14.
*/
import java.util.ArrayList;
import java.util.Collections;
/**
*
* 平衡二叉树编写的有两个突破口,
* 1、一个假设这颗二叉树已经是一个平衡二叉树,加入一个节点之后,不平衡了需要调整的也只有最末的那颗不平衡的树
* 2、插入一个节点时如果这个节点,只有这个节点经过的节点有影响平衡因子,
* 如果这个节点应该插入某个节点的左子树则,平衡因子+1,假设平衡因为=左子树高度-右子数高度
* 3、最末的各个不平衡书的所有节点,要记录,调整完之后,这些节点的平衡因子要减一;
* @author liyiwen1
* @date 2016/12/11
*/
public class AVLTree {
public static void main(String[] args) {
AVLTree avlTree = new AVLTree();
Integer[] integers = new Integer[]{ 8, 9, 2, 7, 5, 2, 69, 7, 2, 6};
for (Integer i : integers){
avlTree.insert(i);
}
System. out.println( "前序遍历结果:");
avlTree.preOrder(avlTree.getRoot());
System. out.println();
System. out.println( "中序遍历结果");
avlTree.midOrder(avlTree.getRoot());
}
private static class AVLTreeNode implements Comparable<AVLTreeNode>{
private Comparable value;
private int balanceUnit = 0;
private AVLTreeNode left;
private AVLTreeNode rigtht;
@Override
public int compareTo(AVLTreeNode a){
return value.compareTo(a.getValue());
}
public Comparable getValue() {
return value;
}
public void setValue(Comparable value) {
this. value = value;
}
public int getBalanceUnit() {
return balanceUnit;
}
public void setBalanceUnit( int balanceUnit) {
this. balanceUnit = balanceUnit;
}
public AVLTreeNode getLeft() {
return left;
}
public void setLeft(AVLTreeNode left) {
this. left = left;
}
public AVLTreeNode getRigtht() {
return rigtht;
}
public void setRigtht(AVLTreeNode rigtht) {
this. rigtht = rigtht;
}
public AVLTreeNode(Comparable value) {
this. value = value;
}
}
private AVLTreeNode root;
public AVLTree() {
}
private void insert(Comparable value){
if ( root == null){
root = new AVLTreeNode(value);
root.setBalanceUnit( 0);
root.setLeft( null);
root.setRigtht( null);
return;
}
if (find(value)){
return; //如果相等则直接返回,不存储value相同的节点
}
AVLTreeNode needRotationTreeRoot = null;
AVLTreeNode treeNode = this. root;
ArrayList<AVLTreeNode> avlTreeNodes = new ArrayList<AVLTreeNode>();
while ( true){
avlTreeNodes.add(treeNode); //所经过的父节点都保存起来
if (value.compareTo(treeNode.getValue()) > 0){
treeNode. balanceUnit--; //如果插入值大于父节点则平衡因子减一
if (treeNode. balanceUnit >= 2 || treeNode. balanceUnit <= - 2 ){
needRotationTreeRoot = treeNode; //记录最后一个不平衡的节点
}
if (treeNode.getRigtht() == null){
treeNode.setRigtht( new AVLTreeNode(value));
break;
} else{
treeNode = treeNode.getRigtht(); //继续往右边走
}
} else if (value.compareTo(treeNode.getValue()) < 0){
treeNode. balanceUnit++; //如果插入的值小于父节点的值,则父节点的平衡因子加一
if (treeNode. balanceUnit >= 2 || treeNode. balanceUnit <= - 2){
needRotationTreeRoot = treeNode; //记录最后一个不平衡的节点
}
if (treeNode.getLeft() == null){
treeNode.setLeft( new AVLTreeNode(value));
break;
} else{
treeNode = treeNode.getLeft();
}
}
}
if (needRotationTreeRoot == null){
return ; //没有半个失去平衡的节点,则返回
} else{
for ( int i = 0; i < avlTreeNodes.size() - 2 ; i++){ //后两个父节点由于处于调节的范畴,不进行平衡因子绝对值的调整
if (avlTreeNodes.get(i). balanceUnit > 0){
avlTreeNodes.get(i). balanceUnit--;
} else if (avlTreeNodes.get(i). balanceUnit < 0){
avlTreeNodes.get(i). balanceUnit++;
}
}
if (avlTreeNodes.size() >= 3){
rotation(needRotationTreeRoot, avlTreeNodes.get(avlTreeNodes.size() - 3)); //父节点只有3个已上
} else{
rotation(needRotationTreeRoot, null); //父节点只有两个
}
}
}
public boolean find(Comparable value){
AVLTreeNode node = getRoot();
while (node != null){
if (node.getValue().compareTo(value) == 0){
return true;
} else if (node.getValue().compareTo(value) > 0){
node = node.getLeft();
} else{
node = node.getRigtht();
}
}
return false;
}
public void preOrder(AVLTreeNode node){
if (node != null){
System. out.print(node.getValue() + " ");
preOrder(node.getLeft());
preOrder(node.getRigtht());
}
}
public void midOrder(AVLTreeNode node){
if (node != null){
midOrder(node.getLeft());
System. out.print(node.getValue() + " ");
midOrder(node.getRigtht());
}
}
//needRotationTreeRootFather表示最末端的不平衡二叉树的根节点的父节点,这里有个特例即needRotationTreeRootFather为null
private void rotation(AVLTreeNode needRotationTreeRoot, AVLTreeNode needRotationTreeRootFather){
ArrayList<AVLTreeNode> nodes = new ArrayList<AVLTreeNode>();
transase(needRotationTreeRoot, nodes);
Collections. sort(nodes);
for (AVLTreeNode node: nodes){
node.setLeft( null);
node.setRigtht( null);
node.setBalanceUnit( 0);
}
nodes.get( 1).setLeft(nodes.get( 0));
nodes.get( 1).setRigtht(nodes.get( 2));
if (needRotationTreeRootFather == null){
this. root = nodes.get( 1);
return ; //处理needRotationTreeRootFather为null的情况
}
if (needRotationTreeRootFather.getLeft() == needRotationTreeRoot){
needRotationTreeRootFather.setLeft(nodes.get( 1));
} else if (needRotationTreeRootFather.getRigtht() == needRotationTreeRoot){
needRotationTreeRootFather.setRigtht(nodes.get( 1));
} else{
throw new RuntimeException();
}
}
private void transase(AVLTreeNode root, ArrayList<AVLTreeNode> nodes){
if (root != null){
nodes.add(root);
transase(root.getLeft(), nodes);
transase(root.getRigtht(), nodes);
}
}
private AVLTreeNode getRoot() {
return root;
}
private void setRoot(AVLTreeNode root) {
this. root = root;
}
}
/**
* Created by dell on 2016/12/14.
*/
import java.util.ArrayList;
import java.util.Collections;
/**
*
* 平衡二叉树编写的有两个突破口,
* 1、一个假设这颗二叉树已经是一个平衡二叉树,加入一个节点之后,不平衡了需要调整的也只有最末的那颗不平衡的树
* 2、插入一个节点时如果这个节点,只有这个节点经过的节点有影响平衡因子,
* 如果这个节点应该插入某个节点的左子树则,平衡因子+1,假设平衡因为=左子树高度-右子数高度
* 3、最末的各个不平衡书的所有节点,要记录,调整完之后,这些节点的平衡因子要减一;
* @author liyiwen1
* @date 2016/12/11
*/
public class AVLTree {
public static void main(String[] args) {
AVLTree avlTree = new AVLTree();
Integer[] integers = new Integer[]{ 8, 9, 2, 7, 5, 2, 69, 7, 2, 6};
for (Integer i : integers){
avlTree.insert(i);
}
System. out.println( "前序遍历结果:");
avlTree.preOrder(avlTree.getRoot());
System. out.println();
System. out.println( "中序遍历结果");
avlTree.midOrder(avlTree.getRoot());
}
private static class AVLTreeNode implements Comparable<AVLTreeNode>{
private Comparable value;
private int balanceUnit = 0;
private AVLTreeNode left;
private AVLTreeNode rigtht;
@Override
public int compareTo(AVLTreeNode a){
return value.compareTo(a.getValue());
}
public Comparable getValue() {
return value;
}
public void setValue(Comparable value) {
this. value = value;
}
public int getBalanceUnit() {
return balanceUnit;
}
public void setBalanceUnit( int balanceUnit) {
this. balanceUnit = balanceUnit;
}
public AVLTreeNode getLeft() {
return left;
}
public void setLeft(AVLTreeNode left) {
this. left = left;
}
public AVLTreeNode getRigtht() {
return rigtht;
}
public void setRigtht(AVLTreeNode rigtht) {
this. rigtht = rigtht;
}
public AVLTreeNode(Comparable value) {
this. value = value;
}
}
private AVLTreeNode root;
public AVLTree() {
}
private void insert(Comparable value){
if ( root == null){
root = new AVLTreeNode(value);
root.setBalanceUnit( 0);
root.setLeft( null);
root.setRigtht( null);
return;
}
if (find(value)){
return; //如果相等则直接返回,不存储value相同的节点
}
AVLTreeNode needRotationTreeRoot = null;
AVLTreeNode treeNode = this. root;
ArrayList<AVLTreeNode> avlTreeNodes = new ArrayList<AVLTreeNode>();
while ( true){
avlTreeNodes.add(treeNode); //所经过的父节点都保存起来
if (value.compareTo(treeNode.getValue()) > 0){
treeNode. balanceUnit--; //如果插入值大于父节点则平衡因子减一
if (treeNode. balanceUnit >= 2 || treeNode. balanceUnit <= - 2 ){
needRotationTreeRoot = treeNode; //记录最后一个不平衡的节点
}
if (treeNode.getRigtht() == null){
treeNode.setRigtht( new AVLTreeNode(value));
break;
} else{
treeNode = treeNode.getRigtht(); //继续往右边走
}
} else if (value.compareTo(treeNode.getValue()) < 0){
treeNode. balanceUnit++; //如果插入的值小于父节点的值,则父节点的平衡因子加一
if (treeNode. balanceUnit >= 2 || treeNode. balanceUnit <= - 2){
needRotationTreeRoot = treeNode; //记录最后一个不平衡的节点
}
if (treeNode.getLeft() == null){
treeNode.setLeft( new AVLTreeNode(value));
break;
} else{
treeNode = treeNode.getLeft();
}
}
}
if (needRotationTreeRoot == null){
return ; //没有半个失去平衡的节点,则返回
} else{
for ( int i = 0; i < avlTreeNodes.size() - 2 ; i++){ //后两个父节点由于处于调节的范畴,不进行平衡因子绝对值的调整
if (avlTreeNodes.get(i). balanceUnit > 0){
avlTreeNodes.get(i). balanceUnit--;
} else if (avlTreeNodes.get(i). balanceUnit < 0){
avlTreeNodes.get(i). balanceUnit++;
}
}
if (avlTreeNodes.size() >= 3){
rotation(needRotationTreeRoot, avlTreeNodes.get(avlTreeNodes.size() - 3)); //父节点只有3个已上
} else{
rotation(needRotationTreeRoot, null); //父节点只有两个
}
}
}
public boolean find(Comparable value){
AVLTreeNode node = getRoot();
while (node != null){
if (node.getValue().compareTo(value) == 0){
return true;
} else if (node.getValue().compareTo(value) > 0){
node = node.getLeft();
} else{
node = node.getRigtht();
}
}
return false;
}
public void preOrder(AVLTreeNode node){
if (node != null){
System. out.print(node.getValue() + " ");
preOrder(node.getLeft());
preOrder(node.getRigtht());
}
}
public void midOrder(AVLTreeNode node){
if (node != null){
midOrder(node.getLeft());
System. out.print(node.getValue() + " ");
midOrder(node.getRigtht());
}
}
//needRotationTreeRootFather表示最末端的不平衡二叉树的根节点的父节点,这里有个特例即needRotationTreeRootFather为null
private void rotation(AVLTreeNode needRotationTreeRoot, AVLTreeNode needRotationTreeRootFather){
ArrayList<AVLTreeNode> nodes = new ArrayList<AVLTreeNode>();
transase(needRotationTreeRoot, nodes);
Collections. sort(nodes);
for (AVLTreeNode node: nodes){
node.setLeft( null);
node.setRigtht( null);
node.setBalanceUnit( 0);
}
nodes.get( 1).setLeft(nodes.get( 0));
nodes.get( 1).setRigtht(nodes.get( 2));
if (needRotationTreeRootFather == null){
this. root = nodes.get( 1);
return ; //处理needRotationTreeRootFather为null的情况
}
if (needRotationTreeRootFather.getLeft() == needRotationTreeRoot){
needRotationTreeRootFather.setLeft(nodes.get( 1));
} else if (needRotationTreeRootFather.getRigtht() == needRotationTreeRoot){
needRotationTreeRootFather.setRigtht(nodes.get( 1));
} else{
throw new RuntimeException();
}
}
private void transase(AVLTreeNode root, ArrayList<AVLTreeNode> nodes){
if (root != null){
nodes.add(root);
transase(root.getLeft(), nodes);
transase(root.getRigtht(), nodes);
}
}
private AVLTreeNode getRoot() {
return root;
}
private void setRoot(AVLTreeNode root) {
this. root = root;
}
}