上一篇:平衡二叉树-c语言实现
概要说明
算法:定义一平衡因子(BF)
当最小不平衡树根结点的平衡因子BF是大于1时,就右旋,小于-1时就左旋。插入结点后,最小不平衡子树的BF与它的子树的BF符号相反时,就需要对结点先进行一次旋转以使得符号相同后,再反向旋转一次才能够完成平衡操作。
第二版代码
using System;
namespace 平衡二叉树2
{
class Program
{
static readonly int forNum = 7;
static void Main(string[] args)
{
Console.WriteLine("Hello World!");
Program p = new Program();
p.mian();
Console.ReadLine();
}
private void mian()
{
Node.genNode = new Node(1);
for (int i = 2; i < forNum;i++)
{
if (i == 4)
{
Node node = Node.genNode;
}
Node.genNode.insert(new Node(i));
}
Node.genNode.display();
}
}
class Node
{
public static Node genNode;
public Node parent;
public Node left;
public Node right;
public int data=0;
public int bf = 0;
public Node(int value)
{
data = value;
parent = null;
left = null;
right = null;
bf = 0;
}
// 把父控件我的位置换了
public void tihuanParrentThis(Node node)
{
if(parent == null)
{
genNode = node;
node.parent = null;
}
else
{
if (parent.left == this)
{
parent.left = node;
}
else
{
parent.right = node;
}
node.parent = parent;
}
}
/// <summary>
/// 我的左向上提,我的左空出来,
/// 左的右变成了我,左的右连接到我的左边
/// </summary>
// 左旋
public void tunLeft()
{
// 左 左的右 我 变换
// 左:右 左的右:父 我:左
// 把我的父控件变成右的父控件
tihuanParrentThis(this.right);
// 我的右变成右的左
Node oldeRight = right;
Node rightLeft = right.left;
if (rightLeft != null)
{
right = rightLeft;
right.parent = this;
}
else
{
right = null;
}
// 右的左变成了我
oldeRight.left = this;
this.parent = oldeRight;
oldeRight.gaoduCha();
this.gaoduCha();
}
// 右旋
public void tunRight()
{
//right.bf--;
//this.bf--;
tihuanParrentThis(this.left);
// 左的右变成我的左
Node leftRight = left.right;
Node oldeLeft = left;
if (leftRight != null)
{
left = leftRight;
left.parent = this;
}
else
{
left = null;
}
// 我变成了左的右
oldeLeft.right = this;
this.parent = oldeLeft;
//oldeLeft.gaoduCha();
//this.gaoduCha();
}
public void insert(Node node)
{
// 向左侧插入
if (node.data < data)
{
if (left == null)
{
insertLeft(node);
}
else
{
left.insert(node);
}
}
else
{
if (right == null)
{
insertRight(node);
}
else
{
right.insert(node);
}
}
}
//左侧插入
public void insertLeft(Node node)
{
left = node;
left.parent = this;
if (right == null)
{
gaoZhengJia(node);
}
}
//在右侧插入
public void insertRight(Node node)
{
right = node;
right.parent = this;
if (left == null)
{
gaoZhengJia(node);
}
}
// 高度增加
public void gaoZhengJia(Node chdiled)
{
if (chdiled == left)
{
bf++;
}
else
{
bf--;
}
if (bf > 1 || bf < -1)
{
//平衡处理
if (bf > 1)
{
if (left.bf < 0)
{
//left.bf++;
// 统一方向(left先左旋)
left.tunLeft();
}
//右旋
tunRight();
}
else
{
if (right.bf > 0)
{
// 统一方向(right先右旋)
right.tunRight();
}
//左旋
tunLeft();
}
}
else
{
if (parent != null)
{
parent.gaoZhengJia(this);
}
}
}
public void display()
{
Console.WriteLine(data);
if (left != null)
{
left.display();
}
if (right != null)
{
right.display();
}
}
// 计算高度
private int gaodu()
{
int leftGaoduo = 0;
int rightGaodu = 0;
if (left != null)
{
leftGaoduo = 1 + left.gaodu();
}
if (right != null)
{
rightGaodu = 1 + right.gaodu();
}
if (leftGaoduo > rightGaodu)
{
return leftGaoduo;
}
else
{
return rightGaodu;
}
}
// 计算高度差
private void gaoduCha()
{
//bf = left.gaodu() - right.gaodu();
int lg = 0;
int rg = 0;
if (left != null)
{
lg = left.gaodu();
}
if(right != null)
{
rg = right.gaodu();
}
bf = lg - rg;
}
}
}
运行效果
生成的二叉树
第一版代码
using System;
namespace 平衡二叉树2
{
class Program
{
static readonly int forNum = 50;
static void Main(string[] args)
{
Console.WriteLine("Hello World!");
Program p = new Program();
p.mian();
Console.ReadLine();
}
private void mian()
{
Node.genNode = new Node(1);
for (int i = 2; i < forNum;i++)
{
Node.genNode.insert(new Node(i));
}
Node.genNode.display();
}
}
class Node
{
public static Node genNode;
public Node parent;
public Node left;
public Node right;
public int data=0;
public int bf = 0;
public Node(int value)
{
data = value;
parent = null;
left = null;
right = null;
bf = 0;
}
// 把父控件我的位置换了
public void tihuanParrentThis(Node node)
{
node.parent = parent;
if(parent == null)
{
genNode = node;
}
else
{
if (parent.left == this)
{
parent.left = node;
}
else
{
parent.right = node;
}
}
}
/// <summary>
/// 我的左向上提,我的左空出来,
/// 左的右变成了我,左的右连接到我的左边
/// </summary>
// 左旋
public void tunLeft()
{
// 左 左的右 我 变换
// 左:右 左的右:父 我:左
// 把我的父控件变成右的父控件
tihuanParrentThis(this.right);
// 我的右变成右的左
this.right = right.left;
right.left.parent = this;
// 右的左变成了我
right.left = this;
this.parent = this.right;
}
// 右旋
public void tunRight()
{
tihuanParrentThis(this.left);
// 左的右变成我的左
this.left = left.right;
left.right.parent = this;
// 我变成了左的右
left.right = this;
this.parent = left;
}
public void insert(Node node)
{
// 向左侧插入
if (node.data < data)
{
if (left == null)
{
insertLeft(node);
}
else
{
left.insert(node);
}
}
else
{
if (right == null)
{
insertRight(node);
}
else
{
right.insert(node);
}
}
}
//左侧插入
public void insertLeft(Node node)
{
left = node;
left.parent = this;
if (right == null)
{
if (parent != null)
{
parent.gaoZhengJia(this);
}
}
}
//在右侧插入
public void insertRight(Node node)
{
right = node;
right.parent = this;
if (left == null)
{
if (parent != null)
{
parent.gaoZhengJia(this);
}
}
}
// 高度增加
public void gaoZhengJia(Node chdiled)
{
if (chdiled == left)
{
bf++;
}
else
{
bf--;
}
if (bf > 1 || bf < -1)
{
//平衡处理
if (bf > 1)
{
if (left.bf < 0)
{
// 统一方向(left先左旋)
}
//右旋
}
else
{
if (right.bf > 1)
{
// 统一方向(right先右旋)
}
//左旋
}
}
else
{
if (parent != null)
{
parent.gaoZhengJia(this);
}
}
}
public void display()
{
Console.WriteLine(data);
if (left != null)
{
left.display();
}
if (right != null)
{
right.display();
}
}
}
}