AVL Tree insertion/deletion Search Algorithm Implementation and analysis-2 (tree height method)

Source: Internet
Author: User

In the previous article (AVL Tree insertion and deletion Search Algorithm Implementation and analysis-1 (balanced factor method, this article describes how to use a balance factor to record the height difference between left and right Subtrees to implement AVL Tree insertion, deletion, and search algorithms, and analyzes some defects of this method. Here, I will use another method to implement these algorithms, and I personally think it is simpler and clearer than what I wrote in the previous article.

Before introducing this method, let's talk about how to calculate the height (or depth) of a binary tree ). The code and explanation are as follows:

Int bitreedepth (bitree BT)
{
// Calculate the depth of the tree
// According to the binary tree depth definition, the depth of the binary tree should be the maximum value of its left and right subtree depth plus 1,
// While the root node counts as Layer 3 and the height is 0.
If (bt = NULL) // if the tree is empty,-1 is returned.
Return-1;
Else
{
Int nldepth = bitreedepth (BT-> lchild); // evaluate the depth of the left Tree
Int nrdepth = bitreedepth (BT-> rchild); // evaluate the depth of the right tree
If (nldepth> = nrdepth)
{
Return nldepth + 1;
}
Else
{
Return nrdepth + 1;
}
}
}


After understanding how to find the tree height, we will start to explain the AVL Tree insertion and deletion and search algorithm:

Type is defined:

Typedef int bool;
Typedef char datatype;

Typedef struct avlnode
{
Datatype data; // data value
Struct avlnode * lchild; // pointer to the left subtree
Struct avlnode * rchild; // pointer to the right subtree
Int height; // record the height of the tree that uses this node as the root
} Avlnode, * avltree;


There are also some auxiliary functions to be used, as shown below:

Static int max (int A, int B)
{
Return (A> B? A: B );
}
//----------------------------------------------------------------------------
Static int height (avltree)
{
If (AT = NULL)
Return-1;
Return at-> height;
}

//--------------------------------------------------------------------------
Avltree getparent (avltree at, datatype X)
{
// The parent node of the node whose return value is X
If (! At | at-> DATA = x)
Return NULL;
If (at-> lchild & at-> lchild-> DATA = x) |
(At-> rchild & at-> rchild-> DATA = x ))
Return;
Else if (at-> lchild & x <at-> lchild-> data ))
Return getparent (at-> lchild, X );
Else
Return getparent (at-> rchild, X );
}
//--------------------------------------------------------------------------
Avlnode * findmin (avltree)
{
// Find the minimum Node
If ()
{
While (at-> lchild)
{
At = at-> lchild;
}
}
Return;
}


The code and explanation of its rotation are as follows:

Static avltree singlerotatewithright (avltree)
{
// Right single rotation
If (! At)
Return NULL;
Avltree x = at-> rchild;
At-> rchild = x-> lchild;
X-> lchild =;


At-> Height = max (at-> lchild), height (at-> rchild) + 1;
X-> Height = max (X-> rchild), At-> height) + 1;
// Return the new root.
Return X;
}

//--------------------------------------------------------------------------
Static avltree singlerotatewithleft (avltree)
{
// Left single rotation
If (! At)
Return NULL;
Avltree x = at-> lchild;
At-> lchild = x-> rchild;
X-> rchild =;

At-> Height = max (at-> lchild), height (at-> rchild) + 1;
X-> Height = max (X-> lchild), At-> height) + 1;
// Return the new root.
Return X;
}
//--------------------------------------------------------------------------------
Static avltree doublerotatewithright (avltree)
{
// Rotate the right double to return the new root.
If (at-> lchild! = NULL)
{
At-> lchild = singlerotatewithleft (at-> lchild );
Return singlerotatewithright ();
}
}
//--------------------------------------------------------------------------
Static avltree doublerotatewithleft (avltree)
{
// Rotate the left and return the new root.
If (at-> rchild! = NULL)
{
At-> rchild = singlerotatewithright (at-> rchild );
Return singlerotatewithleft ();
}
}


All preparations are complete. The following is our topic: insert, delete, and search. Its code and explanation are as follows:

Avlnode * insertnode (avltree at, datatype X)
{
// If X does not exist, insert it into the tree
If (AT = NULL)
{
At = (avltree) malloc (sizeof (avlnode ));
If (AT = NULL)
{
// Insertion failed
Return NULL;
}
Else
{
// Initialize a new node
At-> DATA = X;
At-> lchild = NULL;
At-> rchild = NULL;
At-> Height = 0;
}
}
Else
{
If (x <at-> data)
{
// Insert in the left subtree
At-> lchild = insertnode (at-> lchild, X );

If (height (at-> lchild)-height (at-> rchild) = 2)
{
// If the imbalance is lost
If (x <at-> lchild-> data)
{
// If it is inserted in the left subtree, the left rotation is performed.
At = singlerotatewithleft ();
}
Else
{
// If it is inserted in the right subtree, double left rotation is required.
At = doublerotatewithleft ();
}
}
}
Else if (x> at-> data)
{
// Insert in the right subtree
At-> rchild = insertnode (at-> rchild, X );

If (height (at-> rchild)-height (at-> lchild) = 2)
{
// If the imbalance is lost
If (x> at-> rchild-> data)
{
// If it is inserted in the right subtree, the single right rotation is performed.
At = singlerotatewithright ();
}
Else
{
// If it is inserted in the left subtree, double-Right rotation is performed.
At = doublerotatewithright ();
}
}
}
}
// After insertion, recalculate the tree height and return the root pointer of the new tree.
At-> Height = max (at-> lchild), height (at-> rchild) + 1;
Return;
}
// Configure //----------------------------------------------------------------------------------------
Avlnode * deletenode (avltree at, datatype X)
{
// If the tree is empty, null is returned; otherwise, the root of the deleted node is returned.
If (AT = NULL)
{
Return NULL;
}

If (x = at-> data)
{
// Locate the node to be deleted
Avltree min = findmin (at-> rchild );
If (Min! = NULL)
{
// The right subtree exists.
At-> DATA = min-> data;
If (Min! = At-> rchild)
{
// At-> rchild has the left subtree
Avltree parent = getparent (at-> rchild, Min-> data );
Parent-> lchild = min-> rchild;
}
Else
{
// At-> rchild does not exist in the left subtree
At-> rchild = min-> rchild;
}
}
Else
{
// The right subtree does not exist.
Min =;
At = at-> lchild;
}
Free (min );
}
Else if (x <at-> data)
{
// Delete the child tree on the left
At-> lchild = deletenode (at-> lchild, X );
If (height (at-> rchild)-height (at-> lchild) = 2)
{
// Lost balance after deletion
If (at-> rchild)
{
// If the left subtree of at-> rchild is greater than the right subtree after deletion, the left subtree is rotated
If (height (at-> rchild-> lchild)> height (at-> rchild ))
At = doublerotatewithleft ();
Else // otherwise, perform the Left Single Rotation
At = singlerotatewithleft ();
}
}
}

Else if (x> at-> data)
{
// Delete it from its right subtree
At-> rchild = deletenode (at-> rchild, X );
If (height (at-> lchild)-height (at-> rchild) = 2)
{
// Lost balance after deletion
If (at-> lchild)
{
// If the right subtree of at-> lchild is greater than the left subtree after deletion, the right double rotation is performed.
If (height (at-> lchild-> rchild)> height (at-> lchild ))
At = doublerotatewithright ();
Else // otherwise, perform the right single rotation
At = singlerotatewithright ();
}
}
}
// Recalculate the at depth and return the root pointer of the deleted tree
If (! = NULL)
{
At-> Height = max (at-> lchild), height (at-> rchild) + 1;
}
Return;
}

//--------------------------------------------------------------------------------

Avltree findatnode (avltree at, datatype C)
{
If (! At)
Return NULL;
Else if (at-> CDATA = C) // returns its pointer
Return;
Else if (C <at-> CDATA)
{
// Search in its left subtree

Return findatnode (at-> lchild, C );
}
Else
{
// Search in its right subtree

Return findatnode (at-> rchild, C );
}
}

Algorithm analysis:

1. I think this implementation method is better than the previous one. The idea is clearer and the code is easier to understand.

2. This implementation method does not use the reference type. As mentioned in the previous article, this method does not need to use double pointers, which reduces the chance of errors and makes the code easier to understand. It changes the value of the pointer variable by returning the pointer to the root of the tree and assigning it to the original pointer variable. It also reduces the number of switch... case statements in the previous algorithm.

3. the time complexity and space complexity are the same as the algorithm implementation in the previous article. The time complexity of all algorithms is log2n.

If the algorithm is incorrect, you may want to point it out!

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.