具有重复键的 AVL
在阅读有关 AVL 树重复处理的信息之前,请参阅下面的帖子。
如何处理二叉搜索树中的重复项?
这是为了增加 AVL 树节点以将计数与常规字段(如键、左指针和右指针)一起存储。
在空的二叉搜索树中插入键 12、10、20、9、11、10、12、12 将创建以下。
12(3)
/ \
10(2) 20(1)
/ \
9(1) 11(1)
键的计数显示在括号中
下面是普通 AVL 树的实现,每个键都有计数。此代码基本上取自 AVL 树中的插入和删除代码。为处理重复所做的更改突出显示,其余代码相同。
需要注意的重要一点是更改与简单的二叉搜索树更改非常相似。
C++
// C++ program of AVL tree that
// handles duplicates
#include
using namespace std;
// An AVL tree node
struct node {
int key;
struct node* left;
struct node* right;
int height;
int count;
};
// A utility function to get maximum of two integers
int max(int a, int b);
// A utility function to get height of the tree
int height(struct node* N)
{
if (N == NULL)
return 0;
return N->height;
}
// A utility function to get maximum of two integers
int max(int a, int b)
{
return (a > b) ? a : b;
}
/* Helper function that allocates a new node with the given key and
NULL left and right pointers. */
struct node* newNode(int key)
{
struct node* node = (struct node*)
malloc(sizeof(struct node));
node->key = key;
node->left = NULL;
node->right = NULL;
node->height = 1; // new node is initially added at leaf
node->count = 1;
return (node);
}
// A utility function to right rotate subtree rooted with y
// See the diagram given above.
struct node* rightRotate(struct node* y)
{
struct node* x = y->left;
struct node* T2 = x->right;
// Perform rotation
x->right = y;
y->left = T2;
// Update heights
y->height = max(height(y->left), height(y->right)) + 1;
x->height = max(height(x->left), height(x->right)) + 1;
// Return new root
return x;
}
// A utility function to left rotate subtree rooted with x
// See the diagram given above.
struct node* leftRotate(struct node* x)
{
struct node* y = x->right;
struct node* T2 = y->left;
// Perform rotation
y->left = x;
x->right = T2;
// Update heights
x->height = max(height(x->left), height(x->right)) + 1;
y->height = max(height(y->left), height(y->right)) + 1;
// Return new root
return y;
}
// Get Balance factor of node N
int getBalance(struct node* N)
{
if (N == NULL)
return 0;
return height(N->left) - height(N->right);
}
struct node* insert(struct node* node, int key)
{
/* 1. Perform the normal BST rotation */
if (node == NULL)
return (newNode(key));
// If key already exists in BST, increment count and return
if (key == node->key) {
(node->count)++;
return node;
}
/* Otherwise, recur down the tree */
if (key < node->key)
node->left = insert(node->left, key);
else
node->right = insert(node->right, key);
/* 2. Update height of this ancestor node */
node->height = max(height(node->left), height(node->right)) + 1;
/* 3. Get the balance factor of this ancestor node to check whether
this node became unbalanced */
int balance = getBalance(node);
// If this node becomes unbalanced, then there are 4 cases
// Left Left Case
if (balance > 1 && key < node->left->key)
return rightRotate(node);
// Right Right Case
if (balance < -1 && key > node->right->key)
return leftRotate(node);
// Left Right Case
if (balance > 1 && key > node->left->key) {
node->left = leftRotate(node->left);
return rightRotate(node);
}
// Right Left Case
if (balance < -1 && key < node->right->key) {
node->right = rightRotate(node->right);
return leftRotate(node);
}
/* return the (unchanged) node pointer */
return node;
}
/* Given a non-empty binary search tree, return the node with minimum
key value found in that tree. Note that the entire tree does not
need to be searched. */
struct node* minValueNode(struct node* node)
{
struct node* current = node;
/* loop down to find the leftmost leaf */
while (current->left != NULL)
current = current->left;
return current;
}
struct node* deleteNode(struct node* root, int key)
{
// STEP 1: PERFORM STANDARD BST DELETE
if (root == NULL)
return root;
// If the key to be deleted is smaller than the root's key,
// then it lies in left subtree
if (key < root->key)
root->left = deleteNode(root->left, key);
// If the key to be deleted is greater than the root's key,
// then it lies in right subtree
else if (key > root->key)
root->right = deleteNode(root->right, key);
// if key is same as root's key, then This is the node
// to be deleted
else {
// If key is present more than once, simply decrement
// count and return
if (root->count > 1) {
(root->count)--;
return NULL;
}
// Else, delete the node
// node with only one child or no child
if ((root->left == NULL) || (root->right == NULL)) {
struct node* temp = root->left ? root->left : root->right;
// No child case
if (temp == NULL) {
temp = root;
root = NULL;
}
else // One child case
*root = *temp; // Copy the contents of the non-empty child
free(temp);
}
else {
// node with two children: Get the inorder successor (smallest
// in the right subtree)
struct node* temp = minValueNode(root->right);
// Copy the inorder successor's data to this node and update the count
root->key = temp->key;
root->count = temp->count;
temp->count = 1;
// Delete the inorder successor
root->right = deleteNode(root->right, temp->key);
}
}
// If the tree had only one node then return
if (root == NULL)
return root;
// STEP 2: UPDATE HEIGHT OF THE CURRENT NODE
root->height = max(height(root->left), height(root->right)) + 1;
// STEP 3: GET THE BALANCE FACTOR OF THIS NODE (to check whether
// this node became unbalanced)
int balance = getBalance(root);
// If this node becomes unbalanced, then there are 4 cases
// Left Left Case
if (balance > 1 && getBalance(root->left) >= 0)
return rightRotate(root);
// Left Right Case
if (balance > 1 && getBalance(root->left) < 0) {
root->left = leftRotate(root->left);
return rightRotate(root);
}
// Right Right Case
if (balance < -1 && getBalance(root->right) <= 0)
return leftRotate(root);
// Right Left Case
if (balance < -1 && getBalance(root->right) > 0) {
root->right = rightRotate(root->right);
return leftRotate(root);
}
return root;
}
// A utility function to print preorder traversal of the tree.
// The function also prints height of every node
void preOrder(struct node* root)
{
if (root != NULL) {
cout << root->key << "("<count << ")"<< " ";
preOrder(root->left);
preOrder(root->right);
}
}
/* Driver program to test above function*/
int main()
{
struct node* root = NULL;
/* Constructing tree given in the above figure */
root = insert(root, 9);
root = insert(root, 5);
root = insert(root, 10);
root = insert(root, 5);
root = insert(root, 9);
root = insert(root, 7);
root = insert(root, 17);
cout <<"Pre order traversal of the constructed AVL tree is \n";
preOrder(root);
cout <<"\nPre order traversal after deletion of 9 \n";
preOrder(root);
return 0;
}
// this code is contributed by shivanisinghss2110
C
// C++ program of AVL tree that
// handles duplicates
#include
#include
// An AVL tree node
struct node {
int key;
struct node* left;
struct node* right;
int height;
int count;
};
// A utility function to get maximum of two integers
int max(int a, int b);
// A utility function to get height of the tree
int height(struct node* N)
{
if (N == NULL)
return 0;
return N->height;
}
// A utility function to get maximum of two integers
int max(int a, int b)
{
return (a > b) ? a : b;
}
/* Helper function that allocates a new node with the given key and
NULL left and right pointers. */
struct node* newNode(int key)
{
struct node* node = (struct node*)
malloc(sizeof(struct node));
node->key = key;
node->left = NULL;
node->right = NULL;
node->height = 1; // new node is initially added at leaf
node->count = 1;
return (node);
}
// A utility function to right rotate subtree rooted with y
// See the diagram given above.
struct node* rightRotate(struct node* y)
{
struct node* x = y->left;
struct node* T2 = x->right;
// Perform rotation
x->right = y;
y->left = T2;
// Update heights
y->height = max(height(y->left), height(y->right)) + 1;
x->height = max(height(x->left), height(x->right)) + 1;
// Return new root
return x;
}
// A utility function to left rotate subtree rooted with x
// See the diagram given above.
struct node* leftRotate(struct node* x)
{
struct node* y = x->right;
struct node* T2 = y->left;
// Perform rotation
y->left = x;
x->right = T2;
// Update heights
x->height = max(height(x->left), height(x->right)) + 1;
y->height = max(height(y->left), height(y->right)) + 1;
// Return new root
return y;
}
// Get Balance factor of node N
int getBalance(struct node* N)
{
if (N == NULL)
return 0;
return height(N->left) - height(N->right);
}
struct node* insert(struct node* node, int key)
{
/* 1. Perform the normal BST rotation */
if (node == NULL)
return (newNode(key));
// If key already exists in BST, increment count and return
if (key == node->key) {
(node->count)++;
return node;
}
/* Otherwise, recur down the tree */
if (key < node->key)
node->left = insert(node->left, key);
else
node->right = insert(node->right, key);
/* 2. Update height of this ancestor node */
node->height = max(height(node->left), height(node->right)) + 1;
/* 3. Get the balance factor of this ancestor node to check whether
this node became unbalanced */
int balance = getBalance(node);
// If this node becomes unbalanced, then there are 4 cases
// Left Left Case
if (balance > 1 && key < node->left->key)
return rightRotate(node);
// Right Right Case
if (balance < -1 && key > node->right->key)
return leftRotate(node);
// Left Right Case
if (balance > 1 && key > node->left->key) {
node->left = leftRotate(node->left);
return rightRotate(node);
}
// Right Left Case
if (balance < -1 && key < node->right->key) {
node->right = rightRotate(node->right);
return leftRotate(node);
}
/* return the (unchanged) node pointer */
return node;
}
/* Given a non-empty binary search tree, return the node with minimum
key value found in that tree. Note that the entire tree does not
need to be searched. */
struct node* minValueNode(struct node* node)
{
struct node* current = node;
/* loop down to find the leftmost leaf */
while (current->left != NULL)
current = current->left;
return current;
}
struct node* deleteNode(struct node* root, int key)
{
// STEP 1: PERFORM STANDARD BST DELETE
if (root == NULL)
return root;
// If the key to be deleted is smaller than the root's key,
// then it lies in left subtree
if (key < root->key)
root->left = deleteNode(root->left, key);
// If the key to be deleted is greater than the root's key,
// then it lies in right subtree
else if (key > root->key)
root->right = deleteNode(root->right, key);
// if key is same as root's key, then This is the node
// to be deleted
else {
// If key is present more than once, simply decrement
// count and return
if (root->count > 1) {
(root->count)--;
return NULL;
}
// Else, delete the node
// node with only one child or no child
if ((root->left == NULL) || (root->right == NULL)) {
struct node* temp = root->left ? root->left : root->right;
// No child case
if (temp == NULL) {
temp = root;
root = NULL;
}
else // One child case
*root = *temp; // Copy the contents of the non-empty child
free(temp);
}
else {
// node with two children: Get the inorder successor (smallest
// in the right subtree)
struct node* temp = minValueNode(root->right);
// Copy the inorder successor's data to this node and update the count
root->key = temp->key;
root->count = temp->count;
temp->count = 1;
// Delete the inorder successor
root->right = deleteNode(root->right, temp->key);
}
}
// If the tree had only one node then return
if (root == NULL)
return root;
// STEP 2: UPDATE HEIGHT OF THE CURRENT NODE
root->height = max(height(root->left), height(root->right)) + 1;
// STEP 3: GET THE BALANCE FACTOR OF THIS NODE (to check whether
// this node became unbalanced)
int balance = getBalance(root);
// If this node becomes unbalanced, then there are 4 cases
// Left Left Case
if (balance > 1 && getBalance(root->left) >= 0)
return rightRotate(root);
// Left Right Case
if (balance > 1 && getBalance(root->left) < 0) {
root->left = leftRotate(root->left);
return rightRotate(root);
}
// Right Right Case
if (balance < -1 && getBalance(root->right) <= 0)
return leftRotate(root);
// Right Left Case
if (balance < -1 && getBalance(root->right) > 0) {
root->right = rightRotate(root->right);
return leftRotate(root);
}
return root;
}
// A utility function to print preorder traversal of the tree.
// The function also prints height of every node
void preOrder(struct node* root)
{
if (root != NULL) {
printf("%d(%d) ", root->key, root->count);
preOrder(root->left);
preOrder(root->right);
}
}
/* Driver program to test above function*/
int main()
{
struct node* root = NULL;
/* Constructing tree given in the above figure */
root = insert(root, 9);
root = insert(root, 5);
root = insert(root, 10);
root = insert(root, 5);
root = insert(root, 9);
root = insert(root, 7);
root = insert(root, 17);
printf("Pre order traversal of the constructed AVL tree is \n");
preOrder(root);
root = deleteNode(root, 9);
printf("\nPre order traversal after deletion of 9 \n");
preOrder(root);
return 0;
}
Java
// Java program of AVL tree that handles duplicates
import java.util.*;
class solution {
// An AVL tree node
static class node {
int key;
node left;
node right;
int height;
int count;
}
// A utility function to get height of the tree
static int height(node N)
{
if (N == null)
return 0;
return N.height;
}
// A utility function to get maximum of two integers
static int max(int a, int b)
{
return (a > b) ? a : b;
}
/* Helper function that allocates a new node with the given key and
null left and right pointers. */
static node newNode(int key)
{
node node = new node();
node.key = key;
node.left = null;
node.right = null;
node.height = 1; // new node is initially added at leaf
node.count = 1;
return (node);
}
// A utility function to right rotate subtree rooted with y
// See the diagram given above.
static node rightRotate(node y)
{
node x = y.left;
node T2 = x.right;
// Perform rotation
x.right = y;
y.left = T2;
// Update heights
y.height = max(height(y.left), height(y.right)) + 1;
x.height = max(height(x.left), height(x.right)) + 1;
// Return new root
return x;
}
// A utility function to left rotate subtree rooted with x
// See the diagram given above.
static node leftRotate(node x)
{
node y = x.right;
node T2 = y.left;
// Perform rotation
y.left = x;
x.right = T2;
// Update heights
x.height = max(height(x.left), height(x.right)) + 1;
y.height = max(height(y.left), height(y.right)) + 1;
// Return new root
return y;
}
// Get Balance factor of node N
static int getBalance(node N)
{
if (N == null)
return 0;
return height(N.left) - height(N.right);
}
static node insert(node node, int key)
{
/*1. Perform the normal BST rotation */
if (node == null)
return (newNode(key));
// If key already exists in BST, increment count and return
if (key == node.key) {
(node.count)++;
return node;
}
/* Otherwise, recur down the tree */
if (key < node.key)
node.left = insert(node.left, key);
else
node.right = insert(node.right, key);
/* 2. Update height of this ancestor node */
node.height = max(height(node.left), height(node.right)) + 1;
/* 3. Get the balance factor of this ancestor node to check whether
this node became unbalanced */
int balance = getBalance(node);
// If this node becomes unbalanced, then there are 4 cases
// Left Left Case
if (balance > 1 && key < node.left.key)
return rightRotate(node);
// Right Right Case
if (balance < -1 && key > node.right.key)
return leftRotate(node);
// Left Right Case
if (balance > 1 && key > node.left.key) {
node.left = leftRotate(node.left);
return rightRotate(node);
}
// Right Left Case
if (balance < -1 && key < node.right.key) {
node.right = rightRotate(node.right);
return leftRotate(node);
}
/* return the (unchanged) node pointer */
return node;
}
/* Given a non-empty binary search tree, return the node with minimum
key value found in that tree. Note that the entire tree does not
need to be searched. */
static node minValueNode(node node)
{
node current = node;
/* loop down to find the leftmost leaf */
while (current.left != null)
current = current.left;
return current;
}
static node deleteNode(node root, int key)
{
// STEP 1: PERFORM STANDARD BST DELETE
if (root == null)
return root;
// If the key to be deleted is smaller than the root's key,
// then it lies in left subtree
if (key < root.key)
root.left = deleteNode(root.left, key);
// If the key to be deleted is greater than the root's key,
// then it lies in right subtree
else if (key > root.key)
root.right = deleteNode(root.right, key);
// if key is same as root's key, then This is the node
// to be deleted
else {
// If key is present more than once, simply decrement
// count and return
if (root.count > 1) {
(root.count)--;
return null;
}
// ElSE, delete the node
// node with only one child or no child
if ((root.left == null) || (root.right == null)) {
node temp = root.left != null ? root.left : root.right;
// No child case
if (temp == null) {
temp = root;
root = null;
}
else // One child case
root = temp; // Copy the contents of the non-empty child
}
else {
// node with two children: Get the inorder successor (smallest
// in the right subtree)
node temp = minValueNode(root.right);
// Copy the inorder successor's data to this node and update the count
root.key = temp.key;
root.count = temp.count;
temp.count = 1;
// Delete the inorder successor
root.right = deleteNode(root.right, temp.key);
}
}
// If the tree had only one node then return
if (root == null)
return root;
// STEP 2: UPDATE HEIGHT OF THE CURRENT NODE
root.height = max(height(root.left), height(root.right)) + 1;
// STEP 3: GET THE BALANCE FACTOR OF THIS NODE (to check whether
// this node became unbalanced)
int balance = getBalance(root);
// If this node becomes unbalanced, then there are 4 cases
// Left Left Case
if (balance > 1 && getBalance(root.left) >= 0)
return rightRotate(root);
// Left Right Case
if (balance > 1 && getBalance(root.left) < 0) {
root.left = leftRotate(root.left);
return rightRotate(root);
}
// Right Right Case
if (balance < -1 && getBalance(root.right) <= 0)
return leftRotate(root);
// Right Left Case
if (balance < -1 && getBalance(root.right) > 0) {
root.right = rightRotate(root.right);
return leftRotate(root);
}
return root;
}
// A utility function to print preorder traversal of the tree.
// The function also prints height of every node
static void preOrder(node root)
{
if (root != null) {
System.out.printf("%d(%d) ", root.key, root.count);
preOrder(root.left);
preOrder(root.right);
}
}
/* Driver program to test above function*/
public static void main(String args[])
{
node root = null;
/* Constructing tree given in the above figure */
root = insert(root, 9);
root = insert(root, 5);
root = insert(root, 10);
root = insert(root, 5);
root = insert(root, 9);
root = insert(root, 7);
root = insert(root, 17);
System.out.printf("Pre order traversal of the constructed AVL tree is \n");
preOrder(root);
deleteNode(root, 9);
System.out.printf("\nPre order traversal after deletion of 9 \n");
preOrder(root);
}
}
// contributed by Arnab Kundu
C#
// C# program of AVL tree that
// handles duplicates
using System;
class GFG {
// An AVL tree node
class node {
public int key;
public node left;
public node right;
public int height;
public int count;
}
// A utility function to get
// height of the tree
static int height(node N)
{
if (N == null)
return 0;
return N.height;
}
// A utility function to get
// maximum of two integers
static int max(int a, int b)
{
return (a > b) ? a : b;
}
/* Helper function that allocates a
new node with the given key and
null left and right pointers. */
static node newNode(int key)
{
node node = new node();
node.key = key;
node.left = null;
node.right = null;
node.height = 1; // new node is initially
// added at leaf
node.count = 1;
return (node);
}
// A utility function to right
// rotate subtree rooted with y
// See the diagram given above.
static node rightRotate(node y)
{
node x = y.left;
node T2 = x.right;
// Perform rotation
x.right = y;
y.left = T2;
// Update heights
y.height = max(height(y.left),
height(y.right))
+ 1;
x.height = max(height(x.left),
height(x.right))
+ 1;
// Return new root
return x;
}
// A utility function to left
// rotate subtree rooted with x
// See the diagram given above.
static node leftRotate(node x)
{
node y = x.right;
node T2 = y.left;
// Perform rotation
y.left = x;
x.right = T2;
// Update heights
x.height = max(height(x.left),
height(x.right))
+ 1;
y.height = max(height(y.left),
height(y.right))
+ 1;
// Return new root
return y;
}
// Get Balance factor of node N
static int getBalance(node N)
{
if (N == null)
return 0;
return height(N.left) - height(N.right);
}
static node insert(node node, int key)
{
/*1. Perform the normal BST rotation */
if (node == null)
return (newNode(key));
// If key already exists in BST,
// increment count and return
if (key == node.key) {
(node.count)++;
return node;
}
/* Otherwise, recur down the tree */
if (key < node.key)
node.left = insert(node.left, key);
else
node.right = insert(node.right, key);
/* 2. Update height of this
ancestor node */
node.height = max(height(node.left),
height(node.right))
+ 1;
/* 3. Get the balance factor of
this ancestor node to check whether
this node became unbalanced */
int balance = getBalance(node);
// If this node becomes unbalanced,
// then there are 4 cases
// Left Left Case
if (balance > 1 && key < node.left.key)
return rightRotate(node);
// Right Right Case
if (balance < -1 && key > node.right.key)
return leftRotate(node);
// Left Right Case
if (balance > 1 && key > node.left.key) {
node.left = leftRotate(node.left);
return rightRotate(node);
}
// Right Left Case
if (balance < -1 && key < node.right.key) {
node.right = rightRotate(node.right);
return leftRotate(node);
}
/* return the (unchanged)
node pointer */
return node;
}
/* Given a non-empty binary search
tree, return the node with minimum
key value found in that tree. Note
that the entire tree does not
need to be searched. */
static node minValueNode(node node)
{
node current = node;
/* loop down to find the
leftmost leaf */
while (current.left != null)
current = current.left;
return current;
}
static node deleteNode(node root, int key)
{
// STEP 1: PERFORM STANDARD BST DELETE
if (root == null)
return root;
// If the key to be deleted is
// smaller than the root's key,
// then it lies in left subtree
if (key < root.key)
root.left = deleteNode(root.left, key);
// If the key to be deleted is
// greater than the root's key,
// then it lies in right subtree
else if (key > root.key)
root.right = deleteNode(root.right, key);
// if key is same as root's key,
// then this is the node to be deleted
else {
// If key is present more than
// once, simply decrement
// count and return
if (root.count > 1) {
(root.count)--;
return null;
}
// ElSE, delete the node
// node with only one child
// or no child
if ((root.left == null) || (root.right == null)) {
node temp = root.left != null ? root.left : root.right;
// No child case
if (temp == null) {
temp = root;
root = null;
}
else // One child case
root = temp; // Copy the contents of
// the non-empty child
}
else {
// node with two children: Get
// the inorder successor (smallest
// in the right subtree)
node temp = minValueNode(root.right);
// Copy the inorder successor's
// data to this node and update the count
root.key = temp.key;
root.count = temp.count;
temp.count = 1;
// Delete the inorder successor
root.right = deleteNode(root.right,
temp.key);
}
}
// If the tree had only one
// node then return
if (root == null)
return root;
// STEP 2: UPDATE HEIGHT OF
// THE CURRENT NODE
root.height = max(height(root.left),
height(root.right))
+ 1;
// STEP 3: GET THE BALANCE FACTOR
// OF THIS NODE (to check whether
// this node became unbalanced)
int balance = getBalance(root);
// If this node becomes unbalanced,
// then there are 4 cases
// Left Left Case
if (balance > 1 && getBalance(root.left) >= 0)
return rightRotate(root);
// Left Right Case
if (balance > 1 && getBalance(root.left) < 0) {
root.left = leftRotate(root.left);
return rightRotate(root);
}
// Right Right Case
if (balance < -1 && getBalance(root.right) <= 0)
return leftRotate(root);
// Right Left Case
if (balance < -1 && getBalance(root.right) > 0) {
root.right = rightRotate(root.right);
return leftRotate(root);
}
return root;
}
// A utility function to print
// preorder traversal of the tree.
// The function also prints height
// of every node
static void preOrder(node root)
{
if (root != null) {
Console.Write(root.key + "(" + root.count + ") ");
preOrder(root.left);
preOrder(root.right);
}
}
// Driver Code
static public void Main(String[] args)
{
node root = null;
/* Constructing tree given in
the above figure */
root = insert(root, 9);
root = insert(root, 5);
root = insert(root, 10);
root = insert(root, 5);
root = insert(root, 9);
root = insert(root, 7);
root = insert(root, 17);
Console.Write("Pre order traversal of "
+ "the constructed AVL tree is \n");
preOrder(root);
deleteNode(root, 9);
Console.Write("\nPre order traversal after "
+ "deletion of 9 \n");
preOrder(root);
}
}
// This code is contributed by Arnab Kundu
Python3
# Python code to delete a node in AVL tree
# Generic tree node class
class TreeNode():
def __init__(self, val):
self.count = 1 # assigning count variable so that during insertion in will be incremented for duplicate values
# and during deletion, it will be decremented if has multiple copies.
self.height = 1
self.val = val
self.left = None
self.right = None
# only insertion and deletion will be affected. if multiple copies are there, entry(count) will be printed during traversal.
# AVL tree class which supports insertion,
# deletion operations
class AVL_Tree(object):
def insert(self, root, key):
# Step 1 - Perform normal BST
if not root:
return TreeNode(key)
else if key < root.val:
root.left = self.insert(root.left, key)
else if key > root.val:
root.right = self.insert(root.right, key)
else:
root.count += 1 # incrementing count if same entry is inserted.
# Step 2 - Update the height of the
# ancestor node
root.height = 1 + max(self.getHeight(root.left),
self.getHeight(root.right))
# Step 3 - Get the balance factor
balance = self.getBalance(root)
# Step 4 - If the node is unbalanced,
# then try out the 4 cases
# Case 1 - Left Left
if balance > 1 and key < root.left.val:
return self.rightRotate(root)
# Case 2 - Right Right
if balance < -1 and key > root.right.val:
return self.leftRotate(root)
# Case 3 - Left Right
if balance > 1 and key > root.left.val:
root.left = self.leftRotate(root.left)
return self.rightRotate(root)
# Case 4 - Right Left
if balance < -1 and key < root.right.val:
root.right = self.rightRotate(root.right)
return self.leftRotate(root)
return root
# Recursive function to delete a node with
# given key from subtree with given root.
# It returns root of the modified subtree.
def delete(self, root, key):
# Step 1 - Perform standard BST delete
if not root:
return root
else if key < root.val:
root.left = self.delete(root.left, key)
else if key > root.val:
root.right = self.delete(root.right, key)
else:
if root.count > 1: # if count is more than one i.e multiple copies are there
root.count -= 1 # just decrement count
return root # so that one copy will be deleted and return
if root.left is None:
temp = root.right
root = None
return temp
else if root.right is None:
temp = root.left
root = None
return temp
temp = self.getMinValueNode(root.right)
root.val = temp.val
root.right = self.delete(root.right,
temp.val)
# If the tree has only one node,
# simply return it
if root is None:
return root
# Step 2 - Update the height of the
# ancestor node
root.height = 1 + max(self.getHeight(root.left),
self.getHeight(root.right))
# Step 3 - Get the balance factor
balance = self.getBalance(root)
# Step 4 - If the node is unbalanced,
# then try out the 4 cases
# Case 1 - Left Left
if balance > 1 and self.getBalance(root.left) >= 0:
return self.rightRotate(root)
# Case 2 - Right Right
if balance < -1 and self.getBalance(root.right) <= 0:
return self.leftRotate(root)
# Case 3 - Left Right
if balance > 1 and self.getBalance(root.left) < 0:
root.left = self.leftRotate(root.left)
return self.rightRotate(root)
# Case 4 - Right Left
if balance < -1 and self.getBalance(root.right) > 0:
root.right = self.rightRotate(root.right)
return self.leftRotate(root)
return root
def leftRotate(self, z):
y = z.right
T2 = y.left
# Perform rotation
y.left = z
z.right = T2
# Update heights
z.height = 1 + max(self.getHeight(z.left),
self.getHeight(z.right))
y.height = 1 + max(self.getHeight(y.left),
self.getHeight(y.right))
# Return the new root
return y
def rightRotate(self, z):
y = z.left
T3 = y.right
# Perform rotation
y.right = z
z.left = T3
# Update heights
z.height = 1 + max(self.getHeight(z.left),
self.getHeight(z.right))
y.height = 1 + max(self.getHeight(y.left),
self.getHeight(y.right))
# Return the new root
return y
def getHeight(self, root):
if not root:
return 0
return root.height
def getBalance(self, root):
if not root:
return 0
return self.getHeight(root.left) - self.getHeight(root.right)
def getMinValueNode(self, root):
if root is None or root.left is None:
return root
return self.getMinValueNode(root.left)
def preOrder(self, root):
if not root:
return
print("{}({}) ".format(root.val, root.count), end="")
self.preOrder(root.left)
self.preOrder(root.right)
myTree = AVL_Tree()
root = None
nums = [9, 5, 10, 5, 9, 7, 17]
for num in nums:
root = myTree.insert(root, num)
# Preorder Traversal
print("Preorder Traversal after insertion -")
myTree.preOrder(root)
print()
# Delete
key = 10
root = myTree.delete(root, key)
key = 10
root = myTree.delete(root, key)
key = -1
root = myTree.delete(root, key)
key = 0
root = myTree.delete(root, key)
# Preorder Traversal
print("Preorder Traversal after deletion -")
myTree.preOrder(root)
print()
# This code is contributed by Ajitesh Pathak
Javascript
输出:
Pre order traversal of the constructed AVL tree is
9(2) 5(2) 7(1) 10(1) 17(1)
Pre order traversal after deletion of 9
9(1) 5(2) 7(1) 10(1) 17(1)