赞
踩
本节课在线学习视频(网盘地址,保存后即可免费观看):
https://pan.quark.cn/s/06d5ed47e33b
AVL树是平衡二叉搜索树的一种,它通过旋转操作来保持树的平衡。AVL树的特点是,任何节点的两个子树的高度最大差别为1。本文将详细介绍AVL树中的旋转操作及其实现过程,并通过多个代码案例来说明这些操作的应用。
AVL树是一种自平衡二叉搜索树,其核心思想是通过旋转操作来维持树的平衡。旋转操作有四种:左旋、右旋、左右旋和右左旋。旋转操作的目的是调整树的结构,使其保持平衡,从而保证二叉搜索树的性能。
平衡因子是指某个节点的左子树高度减去右子树高度的值。AVL树的每个节点的平衡因子只能是-1、0或1。
右旋是对某个节点进行的单次旋转,使得该节点的左子树成为其父节点。
- class AVLNode {
- int val;
- int height;
- AVLNode left;
- AVLNode right;
-
- AVLNode(int val) {
- this.val = val;
- this.height = 1;
- }
- }
-
- public class AVLTree {
- private int height(AVLNode node) {
- if (node == null) return 0;
- return node.height;
- }
-
- private AVLNode rightRotate(AVLNode y) {
- AVLNode x = y.left;
- AVLNode T2 = x.right;
-
- x.right = y;
- y.left = T2;
-
- y.height = Math.max(height(y.left), height(y.right)) + 1;
- x.height = Math.max(height(x.left), height(x.right)) + 1;
-
- return x;
- }
-
- public static void main(String[] args) {
- AVLTree tree = new AVLTree();
- AVLNode root = new AVLNode(30);
- root.left = new AVLNode(20);
- root.left.left = new AVLNode(10);
-
- root = tree.rightRotate(root);
- System.out.println("After right rotation, root is: " + root.val);
- }
- }
在这个例子中,我们对根节点进行了右旋操作,使其左子树成为新的根节点。
左旋是对某个节点进行的单次旋转,使得该节点的右子树成为其父节点。
- class AVLTree {
- // 同上
-
- private AVLNode leftRotate(AVLNode x) {
- AVLNode y = x.right;
- AVLNode T2 = y.left;
-
- y.left = x;
- x.right = T2;
-
- x.height = Math.max(height(x.left), height(x.right)) + 1;
- y.height = Math.max(height(y.left), height(y.right)) + 1;
-
- return y;
- }
-
- public static void main(String[] args) {
- AVLTree tree = new AVLTree();
- AVLNode root = new AVLNode(10);
- root.right = new AVLNode(20);
- root.right.right = new AVLNode(30);
-
- root = tree.leftRotate(root);
- System.out.println("After left rotation, root is: " + root.val);
- }
- }
在这个例子中,我们对根节点进行了左旋操作,使其右子树成为新的根节点。
左右旋是对某个节点进行的两次旋转:先对其左子树进行左旋,再对该节点进行右旋。
- class AVLTree {
- // 同上
-
- private AVLNode leftRightRotate(AVLNode node) {
- node.left = leftRotate(node.left);
- return rightRotate(node);
- }
-
- public static void main(String[] args) {
- AVLTree tree = new AVLTree();
- AVLNode root = new AVLNode(30);
- root.left = new AVLNode(10);
- root.left.right = new AVLNode(20);
-
- root = tree.leftRightRotate(root);
- System.out.println("After left-right rotation, root is: " + root.val);
- }
- }
在这个例子中,我们对根节点进行了左右旋操作,先对其左子树进行左旋,再对根节点进行右旋。
右左旋是对某个节点进行的两次旋转:先对其右子树进行右旋,再对该节点进行左旋。
- class AVLTree {
- // 同上
-
- private AVLNode rightLeftRotate(AVLNode node) {
- node.right = rightRotate(node.right);
- return leftRotate(node);
- }
-
- public static void main(String[] args) {
- AVLTree tree = new AVLTree();
- AVLNode root = new AVLNode(10);
- root.right = new AVLNode(30);
- root.right.left = new AVLNode(20);
-
- root = tree.rightLeftRotate(root);
- System.out.println("After right-left rotation, root is: " + root.val);
- }
- }
在这个例子中,我们对根节点进行了右左旋操作,先对其右子树进行右旋,再对根节点进行左旋。
AVL树的插入操作需要在插入新节点后,检查节点的平衡因子,并根据平衡因子进行相应的旋转操作,以保持树的平衡。
- public class AVLTree {
- // 同上
-
- private int balanceFactor(AVLNode node) {
- if (node == null) return 0;
- return height(node.left) - height(node.right);
- }
-
- public AVLNode insert(AVLNode node, int val) {
- if (node == null) return new AVLNode(val);
-
- if (val < node.val) node.left = insert(node.left, val);
- else if (val > node.val) node.right = insert(node.right, val);
- else return node;
-
- node.height = 1 + Math.max(height(node.left), height(node.right));
- int balance = balanceFactor(node);
-
- if (balance > 1 && val < node.left.val) return rightRotate(node);
- if (balance < -1 && val > node.right.val) return leftRotate(node);
- if (balance > 1 && val > node.left.val) {
- node.left = leftRotate(node.left);
- return rightRotate(node);
- }
- if (balance < -1 && val < node.right.val) {
- node.right = rightRotate(node.right);
- return leftRotate(node);
- }
-
- return node;
- }
-
- public static void main(String[] args) {
- AVLTree tree = new AVLTree();
- AVLNode root = null;
- int[] values = {10, 20, 30, 40, 50, 25};
-
- for (int val : values) {
- root = tree.insert(root, val);
- }
-
- System.out.println("AVL Tree constructed successfully.");
- }
- }
在这个例子中,我们实现了AVL树的插入操作。每次插入新节点后,我们检查平衡因子,并通过旋转操作保持树的平衡。
本文详细介绍了AVL树中的旋转操作及其实现过程,包括右旋、左旋、左右旋和右左旋。通过多个代码案例,我们展示了这些旋转操作的应用和效果。在实际开发中,AVL树通过旋转操作保持平衡,从而保证二叉搜索树的高效性能。希望这些示例和注意事项能帮助你更好地理解和应用AVL树中的旋转操作。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。