public class AVLTreeNode<T>: IComparable<AVLTreeNode<T>>
{
// 节点值
public T value { get; set; }
// 相对高度
public int height { get; set; }
// 定义节点的平衡因子
public int _bf { get; set; }
// 左孩子
public AVLTreeNode<T> leftChild { get; set; }
// 右孩子
public AVLTreeNode<T> rightChild { get; set; }
// 旋转时的父节点
public AVLTreeNode<T> _parent { get; set; }
public AVLTreeNode(T value)
{
this.value = value;
}
public int CompareTo(AVLTreeNode<T>? other)
{
throw new NotImplementedException();
}
}
// 如何计算二叉树的高度
// 非递归 迭代方法
/// <summary>
/// 平衡二叉树
/// </summary>
public class AVLTree
{
// 平衡二叉树的根节点
public AVLTreeNode<int> _root = null;
/// <summary>
/// 二叉树的先序遍历
/// </summary>
/// <param name="node"></param>
public void preOrder(AVLTreeNode<int> node)
{
if (node == null)
{
return;
}
Stack<AVLTreeNode<int>> stack = new Stack<AVLTreeNode<int>>();
stack.Push(node);
while (stack.Count != 0)
{
AVLTreeNode<int> node1 = stack.Pop();
Console.WriteLine(node1.value);
if (node1.rightChild != null)
{
stack.Push(node1.rightChild);
}
if (node1.leftChild != null)
{
stack.Push(node1.leftChild);
}
}
}
/// <summary>
/// 二叉树中序遍历方法 非递归
/// </summary>
/// <param name="root"></param>
public void inOrder(AVLTreeNode<int> root)
{
// 如果根节点为空,则退出函数调用
if (root == null)
{
return;
}
// 如果根节点不为空
// 声明并初始化一个空栈
Stack<AVLTreeNode<int>> stack = new Stack<AVLTreeNode<int>>();
// cur为当前遍历节点
AVLTreeNode<int> cur = root;
while (stack.Count != 0 || cur != null)
{
// 如果当前节点不为空,继续遍历其左孩子
while (cur != null)
{
stack.Push(cur);
cur = cur.leftChild;
}
// 如果当前节点为空,则弹出栈顶元素
AVLTreeNode<int> node1 = stack.Pop();
Console.WriteLine(node1.value);
// 当前节点指栈顶的右孩子
cur = node1.rightChild;
}
}
/// <summary>
/// 二叉树后序遍历 // 双循环 + 栈
/// </summary>
/// <param name="root"></param>
public void postOrder(AVLTreeNode<int> root)
{
if (root == null)
{
return;
}
List<int> res = new List<int>();
Stack<AVLTreeNode<int>> stack = new Stack<AVLTreeNode<int>>();
AVLTreeNode<int> cur = root;
AVLTreeNode<int> prev = null;
while (stack.Count != 0 || cur != null)
{
while (cur != null)
{
stack.Push(cur);
cur = cur.leftChild;
}
// 出栈
cur = stack.Pop();
// 记录一个追溯父节点
if(cur.rightChild == null || cur.rightChild == prev)
{
res.Add(cur.value);
prev = cur;
cur = null;
}
else
{
stack.Push(cur);
cur = cur.rightChild;
}
}
foreach (var i in res)
{
Console.WriteLine($"{i}");
}
}
/// <summary>
/// 层次遍历 用来打印节点的值
/// </summary>
/// <param name="root"></param>
public void levelOrder(AVLTreeNode<int> root)
{
if (root == null)
{
return;
}
Queue<AVLTreeNode<int>> queue = new Queue<AVLTreeNode<int>>();
queue.Enqueue(root);
while (queue.Count != 0)
{
AVLTreeNode<int> cur = queue.Dequeue();
Console.WriteLine(cur.value);
if (cur.leftChild != null)
{
queue.Enqueue(cur.leftChild);
}
if (cur.rightChild != null)
{
queue.Enqueue(cur.rightChild);
}
}
}
/// <summary>
/// 使用队列计算二叉树的高度
/// </summary>
/// <param name="aVLTreeNode"></param>
/// <returns></returns>
public static int height(AVLTreeNode<int> root)
{
if (root == null)
{
return 0;
}
// 二叉树的深度
int depth = 0;
Queue<AVLTreeNode<int>> queue = new Queue<AVLTreeNode<int>>();
queue.Enqueue(root);
// 队列不为空
while (queue.Count > 0)
{
int n = queue.Count();
//
while (n > 0)
{
AVLTreeNode<int> node = queue.Dequeue();
if (node.leftChild != null)
{
queue.Enqueue(node.leftChild);
}
if (node.rightChild != null)
{
queue.Enqueue(node.rightChild);
}
n--;
}
depth++;
}
return depth;
}
/// <summary>
/// 计算平衡因子
/// </summary>
/// <param name="root"></param>
/// <returns></returns>
public int get_BF(AVLTreeNode<int> root)
{
if (root == null)
{
return 0;
}
if (root.leftChild == null && root.rightChild == null)
{
return 0;
}
else if (root.leftChild == null)
{
return -root.rightChild.height;
}
else if (root.rightChild == null)
{
return root.leftChild.height;
}
else
{
return root.leftChild.height - root.rightChild.height;
}
}
/// <summary>
/// 中序遍历来判断
/// </summary>
/// <param name="root"></param>
/// <returns></returns>
public bool isBalanced(AVLTreeNode<int> root)
{
if (root == null)
{
return true;
}
// 判断以二叉树的每个节点为根的二叉树是否符合平衡二叉树的条件
// 这里遍历二叉树的每个节点使用的是中序遍历(非递归)
Stack<AVLTreeNode<int>> stack = new Stack<AVLTreeNode<int>>();
/* while (root != null || !stack.isEmpty())
{
if (root != null)
{
stack.add(root);
root = root.left;
}
else
{
TreeNode cur = stack.pop();
if (Math.abs(maxDepth(cur.left) - maxDepth(cur.right)) > 1)
{
return false;
}
root = cur.right;
}
}*/
return true;
}
// 计算节点的平衡因子 左子树的高度与右子树高度的绝对值 <= 1
public static bool isBalanceFactor(AVLTreeNode<int> aVLTreeNode)
{
if (aVLTreeNode == null)
{
return true;
}
// 判断根节点是否平衡 以及每个子节点是否平衡?
// 左子树的高度 非递归咋实现?
int leftHeight = height(aVLTreeNode.leftChild);
int rightHeight = height(aVLTreeNode.rightChild);
return Math.Abs(leftHeight - rightHeight) <= 1 && isBalanceFactor(aVLTreeNode.leftChild) && isBalanceFactor(aVLTreeNode.rightChild);
}
// 左旋转 对应RR旋转
// 右旋转 对应LL调整
// 双旋转
// 左右旋转 对应LR调整
// 右左旋转 对应RL调整
public void leftRotat(AVLTreeNode<int> root)
{
AVLTreeNode<int> newNode = root.rightChild;
AVLTreeNode<int> q = newNode.leftChild;
root.rightChild = q;
if (q != null)
{
q._parent = root;
}
newNode._parent = root._parent;
if (newNode._parent != null)
{
if (newNode._parent.leftChild == root)
{
newNode._parent.leftChild = newNode;
}
else
{
newNode._parent.rightChild = newNode;
}
}
else
{
this._root = newNode;
}
root._parent = newNode;
newNode.leftChild = root;
// 旋转完成后更新节点高度
root.height = height(root);
newNode.height = height(newNode);
}
public void RRotat(AVLTreeNode<int> root)
{
AVLTreeNode<int> newNode = root.leftChild;
AVLTreeNode<int> q = newNode.rightChild;
root.leftChild = q;
if (q != null)
{
q._parent = root;
}
newNode._parent = root._parent;
if (newNode._parent != null)
{
if (newNode._parent.leftChild == root)
{
newNode._parent.leftChild = newNode;
}
else
{
newNode._parent.rightChild = newNode;
}
}
else
{
this._root = newNode;
}
root._parent = newNode;
newNode.rightChild = root;
// 旋转完成后更新节点高度
root.height = height(root);
newNode.height = height(newNode);
}
/// <summary>
/// 节点失衡调节
/// </summary>
/// <param name="node"></param>
/// <returns></returns>
private void refreshNodeBalance(AVLTreeNode<int> node)
{
// 重新设置结点高度
node.height = height(node);
// 判断平衡因子,如果 平衡因子 > 1,则失衡
int tmpNodeBalance = get_BF(node);
// LL型平衡旋转 (单右旋转)
if (tmpNodeBalance > 1 && get_BF(node.leftChild) > 0)
{
RRotat(node);
}
// RR型平衡旋转 (单左旋转)
if (tmpNodeBalance < -1 && get_BF(node.rightChild) < 0)
{
leftRotat(node);
}
// LR型平衡旋转 (先左后右双旋转)
if (tmpNodeBalance > 1 && get_BF(node.leftChild) < 0)
{
leftRotat(node.leftChild);
RRotat(node);
}
// RL型平衡旋转 (先右后左双旋转)
if (tmpNodeBalance < -1 && get_BF(node.rightChild) > 0)
{
RRotat(node.rightChild);
leftRotat(node);
}
}
/// <summary>
/// 插入节点 构造平衡二叉树
/// </summary>
/// <param name="data"></param>
public void Insert(int data)
{
// 如果传入的节点是空
if (_root == null)
{
_root = new AVLTreeNode<int>(data);
_root.height = 1;
return;
}
AVLTreeNode<int> cur = _root;
AVLTreeNode<int> parent;
Stack<AVLTreeNode<int>> stack = new Stack<AVLTreeNode<int>>();
stack.Push(_root);
while (cur != null)
{
if (data < cur.value)
{
if (cur.leftChild != null)
{
stack.Push(cur.leftChild);
cur = cur.leftChild;
}
else
{
AVLTreeNode<int> node1 = new AVLTreeNode<int>(data);
node1._parent = cur;
node1.height = 1;
cur.leftChild = node1;
break;
}
}
if (data > cur.value)
{
if (cur.rightChild != null)
{
stack.Push(cur.rightChild);
cur = cur.rightChild;
}
else
{
AVLTreeNode<int> node1 = new AVLTreeNode<int>(data);
node1._parent = cur;
node1.height = 1;
cur.rightChild = node1;
//cur.rightChild = new AVLTreeNode<int>(data);
break;
}
}
}
// 插入一个节点后 该节点是平衡的,所以我们要判断他的祖先节点
while (stack.Count > 0)
{
refreshNodeBalance(stack.Pop());
}
}
平衡二叉树的实现和前中后层次遍历代码实现
最新推荐文章于 2024-09-16 21:00:00 发布
本文介绍了AVL树的实现,包括AVLTreeNode类的定义,非递归遍历方法(先序、中序、后序和层次),计算高度和平衡因子,以及节点失衡调节和插入节点的处理。
摘要由CSDN通过智能技术生成