平衡二叉树相对于普通的二叉搜索树它的特点是左右孩子的高度不能超过1,一个节点的高度=max(左孩子的高度,右孩子的高度)+1。
一般来说有不平衡有四种情况‘,假设当前节点叫node,左孩子叫nodeLeft,左孩子的左孩子叫nodeLeftLeft,左孩子的右孩子nodeLeftRight,相应右边有,
nodeRight, nodeRightRight, nodeRightLeft。
1. nodeLeft的高度减去nodeRight的高度>1 ,nodeLeftLeft的高度大于nodeLeftRight的高度
2. nodeLeft的高度减去nodeRight的高度>1 ,nodeLeftLeft的高度小于nodeLeftRight的高度
’
3. nodeLeft的高度减去nodeRight的高度<-1 ,nodeRightRight的高度大于nodeRightLeft的高度
4. nodeLeft的高度减去nodeRight的高度<-1 ,nodeRightRight的高度小于nodeRightLeft的高度
只要把这四种情况处理一下,就能形成一颗平衡二叉树,另外值得注意的一点是那些点可能是不平衡的点,当插入一个节点的时候,为了找到一个合适的位置,沿途可能会经过很多节点,沿途经过的这些点都可能是不平衡的点。所以这些点在插入的时候需要收集这些点。
import java.util.ArrayList;
import java.util.Collection;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
import java.util.Stack;
public class A2AVLTree{
private AVLDataTree tree;
public A2AVLTree(){
tree = new AVLDataTree();
}
public void add(Integer e) {
tree.add(e);
}
public Iterator<Integer> iterator() {
return tree.iterator();
}
public int height() {
return tree.height();
}
public int size() {
return tree.size();
}
public class AVLDataTree {
/**
* the root node
*/
private BSTNode mRoot;
/**
* the size of all elements
*/
private int size;
public AVLDataTree(){
mRoot=null;
size=0;
}
public class BSTNode {
Integer key;
int height;
BSTNode left;
BSTNode right;
BSTNode parent;
/**
* initialize members
* @param key key value
* @param parent parent node
* @param left left child
* @param right right child
*/
public BSTNode(Integer key, BSTNode parent, BSTNode left, BSTNode right,int height) {
this.key = key;
this.parent = parent;
this.left = left;
this.right = right;
this.height=height;
}
public int getHeight() {
return height;
}
public void setHeight(int height) {
this.height = height;
}
/**
* get the key
* @return
*/
public Integer getKey() {
return key;
}
/**
* set the key
* @param key key value
*/
public void setKey(Integer key) {
this.key = key;
}
/**
* get the left child
* @return
*/
public BSTNode getLeft() {
return left;
}
/**
* set the left child
* @param left
*/
public void setLeft(BSTNode left) {
this.left = left;
if(left==null){
if(right==null){
this.height=1;
}
else{
this.height=right.height+1;
}
}
else{
this.height=Math.max(left.height+1,this.height);
}
}
/**
* get the right child
* @return
*/
public BSTNode getRight() {
return right;
}
/**
* set the right child
*/
public void setRight(BSTNode right) {
this.right = right;
if(right==null){
if(left==null){
this.height=1;
}
else{
this.height=this.left.height+1;
}
}
else{
this.height=Math.max(right.height+1,this.height);
}
}
/**
* get the parent node
* @return
*/
public BSTNode getParent() {
return parent;
}
/**
* set the parent node
* @param parent
*/
public void setParent(BSTNode parent) {
this.parent = parent;
}
}
/**
* add a node
*/
public void add(Integer key) {
if(key==null){
throw new IllegalArgumentException();
}
if(mRoot==null){
mRoot=new BSTNode(key, null, null, null,1);
size+=1;
return;
}
BSTNode temproot=mRoot;
List<BSTNode> path=new ArrayList<BSTNode>();//the passing nodes
while(true){
if(key>=temproot.key){//look to the right
if(temproot.getRight()==null){
BSTNode node=new BSTNode(key, temproot, null, null,1);
temproot.setRight(node);
size+=1;
break;
}
else{
path.add(temproot);
temproot=temproot.getRight();
}
}
else{//look to the left
if(temproot.getLeft()==null){
BSTNode node=new BSTNode(key, temproot, null, null,1);
temproot.setLeft(node);
size+=1;
break;
}
else{
path.add(temproot);
temproot=temproot.getLeft();
}
}
}
/*for(int i=path.size()-1;i>=0;i–){
BSTNode u=path.get(i);
u.height=Math.max(getHeight(u.getLeft()),getHeight(u.getRight()))+1;
}*/
//balance these Passing nodes
for(int i=path.size()-1;i>=0;i–){
BSTNode u=path.get(i);
int left=getHeight(u.getLeft());
int right=getHeight(u.getRight());
//the height of the left child is greater than the right child
if(left-right>1){
BSTNode leftChild=u.getLeft();
int leftChildleft=getHeight(leftChild.getLeft());
int leftChildright=getHeight(leftChild.getRight());
if(leftChildleft>leftChildright){
u.setLeft(leftChild.getRight());
//u.height=Math.max(getHeight(u.getLeft()),getHeight(u.getRight()))+1;
leftChild.setRight(u);
//leftChild.height=Math.max(getHeight(leftChild.getLeft()),getHeight(leftChild.getRight()))+1;
if(i>0){//not mRoot node
BSTNode parent=path.get(i-1);
if(parent.getLeft()==u){
parent.setLeft(leftChild);
}
else{
parent.setRight(leftChild);
}
//parent.height=Math.max(getHeight(parent.getLeft()),getHeight(parent.getRight()))+1;
}
else{//u is mRoot node
mRoot=leftChild;
}
}
else{
BSTNode leftChildrightChild=leftChild.getRight();
leftChild.setRight(leftChildrightChild.getLeft());
u.setLeft(leftChildrightChild.getRight());
leftChildrightChild.setLeft(leftChild);
leftChildrightChild.setRight(u);
if(i>0){//not mRoot node
BSTNode parent=path.get(i-1);
if(parent.getLeft()==u){
parent.setLeft(leftChildrightChild);
}
else{
parent.setRight(leftChildrightChild);
}
}
else{//u is mRoot node
mRoot=leftChildrightChild;
}
}
}
//the height of the right child is greater than the left child
else if(right-left>1){
BSTNode rightChild=u.getRight();
int rightChildleft=getHeight(rightChild.getLeft());
int rightChildright=getHeight(rightChild.getRight());
if(rightChildright>rightChildleft){
u.setRight(rightChild.getLeft());
rightChild.setLeft(u);
if(i>0){
BSTNode parent=path.get(i-1);
if(parent.getLeft()==u){
parent.setLeft(rightChild);
}
else{
parent.setRight(rightChild);
}
}
else{
mRoot=rightChild;
}
}
else{
BSTNode rightChildleftChild=rightChild.getLeft();
u.setRight(rightChildleftChild.getLeft());
rightChild.setLeft(rightChildleftChild.getRight());
rightChildleftChild.setLeft(u);
rightChildleftChild.setRight(rightChild);
if(i>0){
BSTNode parent=path.get(i-1);
if(parent.getLeft()==u){
parent.setLeft(rightChildleftChild);
}
else{
parent.setRight(rightChildleftChild);
}
}
else{
mRoot=rightChildleftChild;
}
}
}
}
}
/**
* all all element in the c
*/
/**
* remove o from the tree
*/
/**
*
* Inorder iterator
*
*/
private class InorderIterator implements Iterator<Integer>
{
private Stack<BSTNode> nodeStack;
private BSTNode currentNode;
public InorderIterator()
{
nodeStack=new Stack<BSTNode>();
currentNode=mRoot;
}
@Override
public boolean hasNext() {
// TODO Auto-generated method stub
return (currentNode!=null||!nodeStack.empty());
}
@Override
public Integer next() {
// TODO Auto-generated method stub
BSTNode nextNode=null;
while(currentNode!=null)
{
nodeStack.push(currentNode);
currentNode=currentNode.left;
}
if(!nodeStack.isEmpty())
{
nextNode=nodeStack.pop();
currentNode=nextNode.right;
}
return nextNode.key;
}
@Override
public void remove() {
// TODO Auto-generated method stub
throw new UnsupportedOperationException();
}
}
/**
* return the inorder iterator
*/
public Iterator<Integer> iterator() {
return new InorderIterator();
}
/**
* get the height of the tree
* @param node the current root node
* @return
*/
private int getHeight(BSTNode node){
if(node==null)return 0;
return node.height;
}
/**
* get the height of the tree
*/
public int height() {
return getHeight(mRoot);
}
/**
* get the size of all elements
*/
public int size() {
// TODO Auto-generated method stub
return size;
}
}
}
测试代码,代码中的文件输入一些插入数据和查询数据
public class Main {
public static void main(String[] args) {
FileReader fileReader=null;
BufferedReader bufferedReader=null;
File file = new File(“ops-half.txt”);
String outfile=”output.txt”;
FileOutputStream fs =null;
PrintStream p = null;
A2AVLTree avlTree=new A2AVLTree();
try {
fileReader = new FileReader(file);
bufferedReader = new BufferedReader(fileReader);
fs = new FileOutputStream(new File(outfile));
p = new PrintStream(fs);
String s;
while ((s=bufferedReader.readLine())!=null){
String[] line = s.split(“\\s+”);
if(line.length==2){
String command=line[0];
Integer num=Integer.valueOf(line[1]);
if(command.equals(“ins”)){
avlTree.add(num);
}
else if(command.equals(“qry”)){
boolean find=false;
Iterator<Integer> it=avlTree.iterator();
Integer pre=Integer.MAX_VALUE;
boolean notHasPre=true;
while(it.hasNext()){
Integer b=it.next();
if(notHasPre&&b==num){
p.println(“”+num);
find=true;
break;
}
else if(notHasPre&&num<b){
p.println(num+” have no predecessor !”);
break;
}
else if(notHasPre==false&&num<=b){
p.println(“”+pre);
find=true;
break;
}
pre=b;
notHasPre=false;
}
if(find==false){
if(num>=pre){
p.println(“”+pre);
}
else{
p.println(num+” have no predecessor !”);
}
}
}
}
}
}
catch (Exception e) {
e.printStackTrace();
}
finally{
try {
if(bufferedReader!=null)
bufferedReader.close();
if(fileReader!=null)
fileReader.close();
if(p!=null){
p.close();
}
if(fs!=null){
fs.close();
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.println(“over”);
}
}