C#AVL二叉树

 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(); //简单测试,不要加别的代码,就是一行。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值