AVL树:
public class AVLTreeNode<T> : IComparable<AVLTreeNode<T>> where T : IComparable<T> // 定义一个名为 AVLTreeNode<T> 的类,泛型 T 必须实现 IComparable<T> 接口。
{
public T Data { get; set; }// 节点存储的数据值属性。
public AVLTreeNode<T> Left { get; set; }// 左子节点的引用属性。
public AVLTreeNode<T> Right { get; set; }// 右子节点的引用属性。
public int Height { get; set; } = 1;// 节点的高度属性,默认初始化为1。
public AVLTreeNode(T data)// 构造函数,接收数据值参数,并将左右子节点初始化为空。
{
Data = data;
Left = null;
Right = null;
}
public int CompareTo(AVLTreeNode<T> other) // 实现 IComparable<AVLTreeNode<T>> 接口的方法
{
return Data.CompareTo(other.Data);
}
}
public class AVLTree<T> where T : IComparable<T>//实现 IComparable<T> 接口。
{
private AVLTreeNode<T> _root;
public void Insert(T value) //插入方法
{
_root = InsertNode(_root, new AVLTreeNode<T>(value));
}
private AVLTreeNode<T> InsertNode(AVLTreeNode<T> node, AVLTreeNode<T> newNode)// 递归地将新节点插入到树
{
// 如果当前节点为空,则直接返回新节点作为新的子节点。
if (node == null)
return newNode;
// 比较新节点与当前节点数据的大小关系。
int compareResult = newNode.Data.CompareTo(node.Data);
// 如果新节点小于当前节点,则在左子树中递归插入。
if (compareResult < 0)
{
node.Left = InsertNode(node.Left, newNode);
}
// 如果新节点大于当前节点,则在右子树中递归插入。
else if (compareResult > 0)
{
node.Right = InsertNode(node.Right, newNode);
}
// 如果新节点等于当前节点(不允许重复值),则不进行任何操作,直接返回当前节点。
else
{
return node;
}
// 更新当前节点的高度(取左右子树最大高度加1)。
node.Height = 1 + Math.Max(GetHeight(node.Left), GetHeight(node.Right));
// 计算当前节点的平衡因子(左子树高度 - 右子树高度)。
int balanceFactor = GetBalance(node);
// 处理失衡情况(平衡因子绝对值大于1时需要旋转调整平衡)。
if (balanceFactor > 1)
{
// 左子树过深,需判断新节点是在左子树的左边还是右边。
if (newNode.Data.CompareTo(node.Left.Data) < 0)
// 新节点在左子树的左边,执行一次右旋。
return RightRotate(node);
// 新节点在左子树的右边,先对左子树执行一次左旋,再对当前节点执行一次右旋。
node.Left = LeftRotate(node.Left);
return RightRotate(node);
}
if (balanceFactor < -1)
{
// 右子树过深,需判断新节点是在右子树的左边还是右边。
if (newNode.Data.CompareTo(node.Right.Data) > 0)
// 新节点在右子树的右边,执行一次左旋。
return LeftRotate(node);
// 新节点在右子树的左边,先对右子树执行一次右旋,再对当前节点执行一次左旋。
node.Right = RightRotate(node.Right);
return LeftRotate(node);
}
// 若无需旋转调整平衡,则返回当前节点。
return node;
}
public AVLTreeNode<T> FindNode(T value) // 查找具有给定值的节点的方法
{
return FindNodeRecursive(_root, value);
}
private AVLTreeNode<T> FindNodeRecursive(AVLTreeNode<T> node, T value) // 查找递归辅助方法
{
// 如果节点为空或者找到匹配值,则返回当前节点
if (node == null || value.CompareTo(node.Data) == 0)
return node;
// 根据比较结果决定在左子树还是右子树中继续查找
if (value.CompareTo(node.Data) < 0)
return FindNodeRecursive(node.Left, value);
else
return FindNodeRecursive(node.Right, value);
}
public bool Contains(T value)// 检查是否包含给定值
{
return FindNode(value) != null;
}
public bool UpdateValue(T oldValue, T newValue)// 修改节点值的方法
{
return UpdateNodeValueHelper(_root, oldValue, newValue);
}
private bool UpdateNodeValueHelper(AVLTreeNode<T> node, T oldValue, T newValue)// 更新节点值的递归
{
// 如果节点为空,则说明未找到旧值,直接返回 false
if (node == null)
return false;
// 当找到与旧值相等的节点时,更新其值
if (node.Data.CompareTo(oldValue) == 0)
{
node.Data = newValue;
// 更新节点值后需要重新计算高度并进行平衡调整
Rebalance(node);
return true;
}
// 继续在左子树或右子树中查找旧值
else if (node.Data.CompareTo(oldValue) > 0)
return UpdateNodeValueHelper(node.Left, oldValue, newValue);
else
return UpdateNodeValueHelper(node.Right, oldValue, newValue);
}
public bool Delete(T value)//删除值
{
_root = DeleteHelper(_root, value);
return _root != null;
}
private AVLTreeNode<T> DeleteHelper(AVLTreeNode<T> node, T value)
{
if (node == null)
return null;
int compareResult = value.CompareTo(node.Data);
if (compareResult < 0)
node.Left = DeleteHelper(node.Left, value);
else if (compareResult > 0)
node.Right = DeleteHelper(node.Right, value);
else // 找到要删除的节点
{
if (node.Left == null && node.Right == null) // 要删除的是叶子节点
return null;
if (node.Left == null)
{
AVLTreeNode<T> rightNode = node.Right;
node.Right = null;
return BalanceAfterDeletion(rightNode);
}
else if (node.Right == null)
{
AVLTreeNode<T> leftNode = node.Left;
node.Left = null;
return BalanceAfterDeletion(leftNode);
}
else // 节点有两个子节点
{
AVLTreeNode<T> successor = GetSuccessor(node.Right);
node.Data = successor.Data;
node.Right = DeleteHelper(node.Right, successor.Data);
}
}
return BalanceAfterDeletion(node);
}
private AVLTreeNode<T> BalanceAfterDeletion(AVLTreeNode<T> node)
{
int balanceFactor = GetBalance(node);
// 失衡处理:根据平衡因子进行相应的旋转操作
if (balanceFactor > 1) // 左高
{
if (GetBalance(node.Left) >= 0) // 左左失衡
return RightRotate(node);
else // 左右失衡
return LeftRightRotate(node);
}
else if (balanceFactor < -1) // 右高
{
if (GetBalance(node.Right) <= 0) // 右右失衡
return LeftRotate(node);
else // 右左失衡
return RightLeftRotate(node);
}
return node;
}
private AVLTreeNode<T> GetSuccessor(AVLTreeNode<T> node)// 获取后继节点(右子树中的最小节点)
{
while (node.Left != null)
node = node.Left;
return node;
}
private void Rebalance(AVLTreeNode<T> node)// 重新平衡AVL树的方法
{
// 更新当前节点的高度(取左右子树最大高度加1)
node.Height = 1 + Math.Max(GetHeight(node.Left), GetHeight(node.Right));
// 计算当前节点的平衡因子(左子树高度 - 右子树高度)
int balanceFactor = GetBalance(node);
// 根据平衡因子处理失衡情况:进行相应的旋转操作
if (balanceFactor > 1) // 左子树比右子树高
{
if (GetBalance(node.Left) < 0) // 左子树中存在“左高”失衡,即“左左”失衡
node = LeftLeftRotate(node); // 对该节点执行右旋
else // 左子树中存在“右高”失衡,即“左右”失衡
node = LeftRightRotate(node); // 先对左子节点左旋,再对当前节点右旋
}
else if (balanceFactor < -1) // 右子树比左子树高
{
if (GetBalance(node.Right) > 0) // 右子树中存在“右高”失衡,即“右右”失衡
node = RightRightRotate(node); // 对该节点执行左旋
else // 右子树中存在“左高”失衡,即“右左”失衡
node = RightLeftRotate(node); // 先对右子节点右旋,再对当前节点左旋
}
// 如果当前节点是根节点,则更新整个树的根节点引用
if (_root == node)
_root = node;
}
private int GetHeight(AVLTreeNode<T> node)// 获取给定节点的高度
{
return node == null ? 0 : node.Height;
}
private int GetBalance(AVLTreeNode<T> node)// 计算给定节点的平衡因子
{
return node == null ? 0 : GetHeight(node.Left) - GetHeight(node.Right);
}
private AVLTreeNode<T> LeftRotate(AVLTreeNode<T> node)// 左旋操作
{
// 获取右子节点并暂存
AVLTreeNode<T> rightChild = node.Right;
// 将右子节点的左子节点设置给当前节点的右子节点
node.Right = rightChild.Left;
// 将当前节点设置给原右子节点的左子节点
rightChild.Left = node;
// 更新旋转后两个节点的高度
node.Height = 1 + Math.Max(GetHeight(node.Left), GetHeight(node.Right));
rightChild.Height = 1 + Math.Max(GetHeight(rightChild.Left), GetHeight(rightChild.Right));
// 返回新的父节点(原右子节点)
return rightChild;
}
private AVLTreeNode<T> RightRotate(AVLTreeNode<T> node) // 右旋操作
{
AVLTreeNode<T> leftChild = node.Left;
node.Left = leftChild.Right;
leftChild.Right = node;
node.Height = 1 + Math.Max(GetHeight(node.Left), GetHeight(node.Right));
leftChild.Height = 1 + Math.Max(GetHeight(leftChild.Left), GetHeight(leftChild.Right));
return leftChild;
}
// “左左”失衡时的旋转策略(相当于右旋)
private AVLTreeNode<T> LeftLeftRotate(AVLTreeNode<T> node)
{
return RightRotate(node);
}
// “左右”失衡时的旋转策略(先左旋再右旋)
private AVLTreeNode<T> LeftRightRotate(AVLTreeNode<T> node)
{
node.Left = LeftRotate(node.Left);
return RightRotate(node);
}
// “右右”失衡时的旋转策略(相当于左旋)
private AVLTreeNode<T> RightRightRotate(AVLTreeNode<T> node)
{
return LeftRotate(node);
}
// “右左”失衡时的旋转策略(先右旋再左旋)
private AVLTreeNode<T> RightLeftRotate(AVLTreeNode<T> node)
{
node.Right = RightRotate(node.Right);
return LeftRotate(node);
}
public void PreOrderTraversal(Action<T> printAction) // 前序遍历
{
PreOrderTraversalHelper(_root, printAction);
}
private void PreOrderTraversalHelper(AVLTreeNode<T> node, Action<T> printAction)
{
if (node != null)
{
printAction(node.Data);
PreOrderTraversalHelper(node.Left, printAction);
PreOrderTraversalHelper(node.Right, printAction);
}
}
public void InOrderTraversal(Action<T> printAction) // 中序遍历
{
InOrderTraversalHelper(_root, printAction);
}
private void InOrderTraversalHelper(AVLTreeNode<T> node, Action<T> printAction)
{
if (node != null)
{
InOrderTraversalHelper(node.Left, printAction);
printAction(node.Data);
InOrderTraversalHelper(node.Right, printAction);
}
}
public void PostOrderTraversal(Action<T> printAction) // 后序遍历
{
PostOrderTraversalHelper(_root, printAction);
}
private void PostOrderTraversalHelper(AVLTreeNode<T> node, Action<T> printAction)
{
if (node != null)
{
PostOrderTraversalHelper(node.Left, printAction);
PostOrderTraversalHelper(node.Right, printAction);
printAction(node.Data);
}
}
public void LevelOrderTraversal(Action<T> printAction)// 层次遍历
{
var queue = new Queue<AVLTreeNode<T>>();
if (_root != null)
{
queue.Enqueue(_root);
}
while (queue.Count > 0)
{
var currentNode = queue.Dequeue();
printAction(currentNode.Data);
if (currentNode.Left != null)
queue.Enqueue(currentNode.Left);
if (currentNode.Right != null)
queue.Enqueue(currentNode.Right);
}
}
public void PrintTreeRecursive() // 1. 以树状结构打印二叉树
{
PrintTreeHelper(_root, "");
}
private void PrintTreeHelper(AVLTreeNode<T> node, string indent)
{
if (node != null)
{
Console.WriteLine($"{indent}——{node.Data}");
PrintTreeHelper(node.Left, indent + " ");
PrintTreeHelper(node.Right, indent + " ");
}
}
public void PrintAsGeneralizedList() // 2. 以广义表形式打印二叉树
{
PrintAsGeneralizedListHelper(_root);
}
private void PrintAsGeneralizedListHelper(AVLTreeNode<T> node)
{
if (node != null)
{
Console.Write($"({node.Data}");
if (node.Left != null || node.Right != null)
Console.Write(", ");
PrintAsGeneralizedListHelper(node.Left);
PrintAsGeneralizedListHelper(node.Right);
if (node.Left != null && node.Right != null)
Console.Write(",");
Console.Write(")");
}
}
public void PrintLevelOrder()// 3. 按层次打印二叉树
{
var queue = new Queue<AVLTreeNode<T>>();
if (_root != null)
queue.Enqueue(_root);
while (queue.Count > 0)
{
var currentNode = queue.Dequeue();
Console.Write(currentNode.Data + " ");
if (currentNode.Left != null)
queue.Enqueue(currentNode.Left);
if (currentNode.Right != null)
queue.Enqueue(currentNode.Right);
}
Console.WriteLine();
}
public int CountNodes() // 统计节点个数
{
return CountNodesHelper(_root);
}
private int CountNodesHelper(AVLTreeNode<T> node)
{
if (node == null)
return 0;
else
return 1 + CountNodesHelper(node.Left) + CountNodesHelper(node.Right);
}
public T FindMaxValue() // 求最大值
{
if (_root == null)
throw new InvalidOperationException("树为空,无法找到最大值");
return FindMaxValueHelper(_root).Data;
}
private AVLTreeNode<T> FindMaxValueHelper(AVLTreeNode<T> node)
{
if (node == null)
return null;
// 递归地找到左子树的最大值
AVLTreeNode<T> leftMaxValue = (node.Left != null) ? FindMaxValueHelper(node.Left) : null;
// 递归地找到右子树的最大值
AVLTreeNode<T> rightMaxValue = (node.Right != null) ? FindMaxValueHelper(node.Right) : null;
// 比较当前节点、左子树最大值和右子树最大值
if (leftMaxValue != null && leftMaxValue.Data.CompareTo(node.Data) > 0)
return leftMaxValue;
if (rightMaxValue != null && rightMaxValue.Data.CompareTo(node.Data) > 0)
return rightMaxValue;
// 如果当前节点是最大值或者没有子节点,返回当前节点
return node;
}
public T FindMinValue() // 求最小值
{
if (_root == null)
throw new InvalidOperationException("树为空,无法找到最小值");
return FindMinValueHelper(_root).Data;
}
private AVLTreeNode<T> FindMinValueHelper(AVLTreeNode<T> node)
{
if (node == null)
return null;
// 优先检查左子树,因为最小值通常在左子树
AVLTreeNode<T> leftMinValue = (node.Left != null) ? FindMinValueHelper(node.Left) : node;
// 如果右子树存在,且其最小值小于左子树的最小值,则更新最小值
if (node.Right != null && leftMinValue.Data.CompareTo(((node.Right.Left != null) ? FindMinValueHelper(node.Right.Left) : node.Right).Data) > 0)
{
leftMinValue = (node.Right.Left != null) ? FindMinValueHelper(node.Right.Left) : node.Right;
}
// 返回找到的最小值节点
return leftMinValue;
}
public void DestroyTree()//销毁二叉树
{
DestroyTreeRecursive(_root);
_root = null;
}
private void DestroyTreeRecursive(AVLTreeNode<T> node)
{
if (node == null) return;
DestroyTreeRecursive(node.Left);
DestroyTreeRecursive(node.Right);
node.Left = null;
node.Right = null;
}
}
public class AVLTreeDemo//用于简单测试
{
public AVLTreeDemo()
{
AVLTree<int> tree = new AVLTree<int>();
for (int i = 1; i < 29; i++)
{
tree.Insert(i);
}
Console.WriteLine("前序遍历:");
tree.PreOrderTraversal(node => Console.Write($"{node} "));
Console.WriteLine();
Console.WriteLine("以树状结构打印二叉树:\n");
tree.PrintTreeRecursive();
Console.WriteLine();
Console.WriteLine("以广义表形式打印二叉树:\n");
tree.PrintAsGeneralizedList();
Console.WriteLine(" \n\n按层次打印二叉树:\n");
tree.PrintTreeRecursive();
Console.WriteLine();
Console.WriteLine("层次遍历:");
tree.LevelOrderTraversal(node => Console.Write($"{node} "));
Console.WriteLine();
var node = tree.FindNode(15);
Console.WriteLine($"\n\n查找节点:{node.Data}");
var data1 = tree.UpdateValue(12, 200);
Console.WriteLine($"\n修改值是:{data1}");
Console.WriteLine("\n\n中序遍历:\n");
tree.InOrderTraversal(node => Console.Write($"{node} "));
Console.WriteLine();
Console.WriteLine($"\n\n删除值20:{tree.Delete(20)}");
Console.WriteLine("\n后序遍历:\n");
tree.PostOrderTraversal(node => Console.Write($"{node} "));
Console.WriteLine();
Console.WriteLine($"\n\n统计节点个数: {tree.CountNodes()}\n");
Console.WriteLine($"\n最大值:{tree.FindMaxValue()}\n");
Console.WriteLine($"\n最小值: {tree.FindMinValue()}\n");
}
}
简单测试:
AVLTreeDemo aVLTreeDemo = new AVLTreeDemo(); //简单测试,不要加别的代码,就是一行。