public class Node
{
public Node Parent;
public Node LeftTree;
public Node RigthTree;
public int data;
public bool IsDelete;
public int BalanceValue;
public Node(int data)
{
this.data = data;
}
}
public class AVLtree
{
private Node Head;
private int count;
public int Count { get => count; private set => count = value; }
/// <summary>
/// AVL树插入方法
/// </summary>
/// <param name="data"></param>
public void Insert(int data)
{
#region 找到插入点(这里和正常二叉搜索树查找方式相同不多做讲解)
Node tempNode = new Node(data);
if(Head==null)
{
Head = tempNode;
return;
}
Node parent=Head;
Node currentNode=Head;
while(currentNode!=null)
{
parent = currentNode;
if(currentNode.data>data)
{
currentNode = currentNode.LeftTree;
}
else
{
currentNode = currentNode.RigthTree;
}
}
currentNode = tempNode;
currentNode.Parent = parent;
if (parent.data>data)
{
parent.LeftTree = currentNode;
}
else
{
parent.RigthTree = currentNode;
}
#endregion
//插入每一个节点的时候都要计算平衡因子
//当平衡因子等于2表示当前右子树比左子树高2(或者-2时右子树比左子树低2)
while (parent!=null)
{
//更新平衡因子
if (parent.LeftTree == currentNode)
{
//当左边插入值的时候父节点由于左子树高度上升了1,平衡因子减少1
parent.BalanceValue--;
}
else
{
//当右边插入值的时候父节点由于右子树高度上升了1,平衡因子增加1
parent.BalanceValue++;
}
//当父节点的平衡因子等于0的时候表示当前是平衡的不需要平衡树
if (parent.BalanceValue == 0) break;
//当父节点的平衡因子为1或者-1时同时父节点的平衡因子也会变更
else if(parent.BalanceValue==1||parent.BalanceValue==-1)
{
// 回溯上升 更新祖父节点的平衡因子并检验合法性
currentNode = parent;
parent = currentNode.Parent;
}
else //平衡因子不合法需要重新平衡二叉树
{
if(parent.BalanceValue==2)
{
if(currentNode.BalanceValue==1)
{
//TODO 右旋转
RotateL(parent);
}
else
{
//TODO 左右旋转
RotateRL(parent);
}
}
else if (parent.BalanceValue == -2)
{
if (currentNode.BalanceValue == -1)
{
//TODO 左旋转
RotateR(parent);
}
else
{
//TODO 右左旋转
RotateLR(parent);
}
}
break;
}
}
Count++;
}
public void RotateRL(Node parent)
{
Node pNode = parent;
Node subR = parent.RigthTree;
Node subRL = subR.LeftTree;
int bv = subRL.BalanceValue;
RotateR(parent.RigthTree);
RotateL(parent);
if (bv == 1)
{
pNode.BalanceValue = 0;
subR.BalanceValue = -1;
}
else if (bv == -1)
{
pNode.BalanceValue = 1;
subR.BalanceValue = 0;
}
else
{
pNode.BalanceValue = 0;
subR.BalanceValue = 0;
}
}
public void RotateLR(Node parent)
{
Node pNode = parent;
Node subL = parent.LeftTree;
Node subLR = subL.RigthTree;
int bv = subLR.BalanceValue;
RotateL(parent.LeftTree);
RotateR(parent);
if (bv == 1)
{
pNode.BalanceValue = 0;
subL.BalanceValue = -1;
}
else if (bv == -1)
{
pNode.BalanceValue = 1;
subL.BalanceValue = 0;
}
else
{
pNode.BalanceValue = 0;
subL.BalanceValue = 0;
}
}
public void RotateL(Node parent)
{
Node subR = parent.RigthTree;
Node subRL = subR.LeftTree;
Node grandparent = parent.Parent;
parent.RigthTree = subRL;
if (subRL != null)
{
subRL.Parent = parent;
}
subR.LeftTree = parent;
parent.Parent = subR;
if(grandparent==null)
{
subR.Parent = null;
Head = subR;
}
else
{
if (grandparent.LeftTree == parent)
{
grandparent.LeftTree = subR;
}
else
{
grandparent.RigthTree = subR;
}
}
parent.BalanceValue = 0;
subR.BalanceValue = 0;
parent = subR;
}
public void RotateR(Node parent)
{
Node subL = parent.LeftTree;
Node subLR = subL.RigthTree;
Node grandparent = parent.Parent;
subL.RigthTree = parent;
parent.Parent = subL;
parent.LeftTree = subLR;
if (subLR != null)
{
subLR.Parent = parent;
}
if(grandparent==null)
{
subL.Parent = null;
Head = subL;
}
else
{
if(grandparent.LeftTree==parent)
{
grandparent.LeftTree = subL;
}
else
{
grandparent.RigthTree = subL;
}
}
parent.BalanceValue = 0;
subL.BalanceValue = 0;
parent = subL;
}
public void InOrder()
{
DebugOrder(Head);
}
private void DebugOrder(Node tree)
{
if (tree != null)
{
DebugOrder(tree.LeftTree);
Console.WriteLine(tree.data);
DebugOrder(tree.RigthTree);
}
}
}
```
C# AVL树实现
最新推荐文章于 2024-06-10 20:39:17 发布