某度复制过来的:平衡二叉树(Balanced Binary Tree)又被称为AVL树(有别于AVL算法),且具有以下性质:它是一 棵空树或它的左右两个子树的高度差的绝对值不超过1,并且左右两个子树都是一棵平衡二叉树。平衡二叉树的常用实现方法有红黑树、AVL、替罪羊树、Treap、伸展树等。 最小二叉平衡树的节点的公式如下 F(n)=F(n-1)+F(n-2)+1 这个类似于一个递归的数列,可以参考Fibonacci(斐波那契)数列,1是根节点,F(n-1)是左子树的节点数量,F(n-2)是右子树的节点数量。
下面代码是我自己编写 写的代码比较简单应该大多数都看的懂 “吧”本章主要旋转思想:一共4种情况。第3、4种一定是先旋转成第1、2种。第1、2种情况在旋转成平衡。(左边4种情况、右边4种情况,其实是一样的,我这里就说是4种、一共8种)
(图片网上下载的)
<script>
function Tree(){
// 根
var root = null;
var Node = function (key){
this.key = key;
this.left = null;
this.right = null;
}
// 添加节点
/*
* 第3个数指 left || right 用于辨别 左边不平衡还是右边不平衡
*/
var insertNode = function (node,newDode,direction){
if( newDode.key < node.key ){
if( node.left == null ){
// 左边为空添加
node.left = newDode;
// 判断 是否平衡 取出那个不平衡的节点,下面旋转
var balanceNode = new isBalance(root);
if( balanceNode.key ){
console.log( balanceNode.key , '节点 -- 不平衡' );
// 旋转平衡
rotate(balanceNode,direction);
}
}else{
// 左边存在的话就递归到为 node.left = null 为止
// 递归 left
var left = direction || 'left';
insertNode(node.left,newDode,left);
}
}else{
if( node.right == null ){
// 添加
node.right = newDode;
// 判断 是否平衡
var balanceNode = new isBalance(root);
if( balanceNode.key ){
console.log( balanceNode.key , '节点 -- 不平衡' );
// 旋转平衡
rotate(balanceNode,direction);
}
}else{
// 递归 right
var right = direction || 'right';
insertNode(node.right,newDode,right);
}
}
}
// 旋转 方式 逆时针旋转 顺时
var rotate = function(balanceNode,direction){
var nextNode = balanceNode[direction];
var nextNodeLeft = nextNode.left;
var nextNodeRight = nextNode.right;
if( direction == 'right' ){
// 第三、四种情况,先转成 第一、二种情况
if( nextNodeLeft && !nextNodeRight ){
nextNode.left = null;
balanceNode[direction] = nextNodeLeft;
nextNodeLeft.right = nextNode;
}else if( nextNodeLeft && nextNodeRight && getNodeHeight(nextNodeLeft) > getNodeHeight(nextNodeRight) ){
nextNode.left = null;
balanceNode[direction] = nextNodeLeft;
nextNodeRight.right = nextNode;
}
// 将根节点下面一个节点更新位置
nextNode = balanceNode[direction];
if( nextNode.left == null ){
nextNode.left = balanceNode;
balanceNode.right = null;
}else{
balanceNode.right = nextNode.left;
nextNode.left = balanceNode;
}
}else if( direction == 'left' ){
// 第三、四种情况,先转成 第一、二种情况
if( !nextNodeLeft && nextNodeRight ){
nextNode.right = null;
balanceNode[direction] = nextNodeRight;
nextNodeRight.left = nextNode;
}else if( nextNodeLeft && nextNodeRight && getNodeHeight(nextNodeLeft) < getNodeHeight(nextNodeRight) ){
nextNode.right = null;
balanceNode[direction] = nextNodeRight;
nextNodeRight.left = nextNode;
}
// 将根节点下面一个节点更新位置
nextNode = balanceNode[direction];
if( nextNode.right == null ){ // 第一种情况
nextNode.right = balanceNode;
balanceNode.left = null;
}else{ // 第二种情况
balanceNode.left = nextNode.right;
nextNode.right = balanceNode;
}
}
// 设置成根节点
if( root == balanceNode ){
root = nextNode;
}else{
var BeforeNode = findBeforeNode(root,balanceNode);
BeforeNode[direction] = nextNode;
}
// 判断是否还存在不平衡
var twoBalanceNode = new isBalance(root);
if( twoBalanceNode.key ){
console.log( twoBalanceNode.key , '节点第2次 -- 不平衡' );
rotate(twoBalanceNode,direction);
}
}
// 当前节点 找到上面一个节点 ->先序算法
var findBeforeNode = function (Root,node){
if( Root.left == node || Root.right == node ){
return Root;
}else{
if( Root.left ){
var resultL = findBeforeNode(Root.left,node);
if( resultL != null ){
return resultL;
}
}
if( Root.right ){
var resultR = findBeforeNode(Root.right,node);
if( resultR != null ){
return resultR;
}
}
return null;
}
}
// 判断 是否平衡 返回那个不平衡节点 ( >=2则不平衡)
var isBalance = function(node){
var leftTree = getNodeHeight(node.left);
var rightTree = getNodeHeight(node.right);
var remainder = leftTree - rightTree;
if( remainder == -2 ){
// 右子树不平衡
console.log('右子树不平衡');
return node;
}else if( remainder == 2 ){
// 左子树不平衡
console.log('左子树不平衡');
return node;
}else{
// 平衡
var balanceLeft = !node.left ? null : isBalance(node.left);
var balanceRight = !node.right ? null : isBalance(node.right);
if( balanceLeft ){
return balanceLeft;
}else if( balanceRight ){
return balanceRight;
}else{
return null;
}
}
}
// 求出一个节点的高度
var getNodeHeight = function (node){
if( node == null ){
return 0;
}
var oLeft = getNodeHeight(node.left);
var oRight = getNodeHeight(node.right);
return 1+Math.max(oLeft,oRight);
}
this.insert = function (key){
var newNode = new Node(key);
if( root == null ){
root = newNode;
}else{
insertNode(root,newNode);
}
}
// 中
this.inOrderTraverse = function(callback){
inOrderTraverseNode(root,callback);
}
var inOrderTraverseNode = function (node,callback){
if( node != null ){
inOrderTraverseNode(node.left,callback);
callback(node);
//callback(node);
inOrderTraverseNode(node.right,callback);
}
}
this.printRoot = function (){
console.log("根节点为");
console.log( root );
console.log( "left Tree -- "+getNodeHeight(root.left) ,'层 right Tree -- '+getNodeHeight(root.right) +"层");
}
}
// Tree 结束
var tree = new Tree();
//console.log(tree);
/*tree.insert(1);
tree.insert(2);
tree.insert(3);
tree.insert(4);
tree.insert(5);
tree.insert(6);
tree.insert(7);
tree.insert(8);
tree.insert(9);
tree.insert(10);
tree.insert(11);*/
/*tree.insert(50);
tree.insert(40);
tree.insert(45);*/
/*tree.insert(50);
tree.insert(40);
tree.insert(60);
tree.insert(30);
tree.insert(45);
tree.insert(47);*/
var arr = [50,40,60,30,45,47,5,60,2,334,434,21,32,43,434,367,43];
for( var i = 0 ; i < arr.length; ++i ){
tree.insert(arr[i]);
}
var printNode = function(value){
console.log(value,'中序输出');
}
//tree.inOrderTraverse(printNode);
tree.printRoot();
</script>
结果:
算法大神请绕道!!!!,本人小白一个