平衡二叉树的实现 java
2016-12-15 00:17
405 查看
平衡二叉树的实现:
程序输出结果为:
前序遍历结果:
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;
}
}
程序输出结果为:
前序遍历结果:
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;
}
}
相关文章推荐
- 平衡二叉树(AVL)--查找、删除、插入(Java实现)
- 平衡二叉树平衡二叉树(AVL)--查找、删除、插入(Java实现)
- 平衡二叉树的Java实现——插入操作【无泛型】
- 平衡二叉树(Java实现)
- 平衡二叉树(AVL)的插入、删除、查找的java实现
- java --平衡二叉树实现
- Java实现判断二叉树是否为平衡二叉树
- 平衡二叉树(AVL)java实现
- java实现 二叉树的深度&判断二叉树是否是平衡二叉树
- java数据结构与算法之平衡二叉树(AVL树)的设计与实现
- 平衡二叉树的java实现
- Java实现平衡二叉树(AVLTree)的构建
- Java实现平衡二叉树(AVLTree)的构建
- java数据结构与算法之平衡二叉树(AVL树)的设计与实现
- 【LeetCode-面试算法经典-Java实现】【110-Balanced Binary Tree(平衡二叉树)】
- 平衡二叉树(AVL)--查找、删除、插入(Java实现)
- 平衡二叉树Java实现
- 树——平衡二叉树插入和查找的JAVA实现(2):增加删除方法
- 平衡二叉树(AVL树)算法 Java实现
- 用java实现一颗平衡二叉树ADT