C++ Programming Code Examples
C++ > Data Structures and Algorithm Analysis in C++ Code Examples
Implementation for AVL tree
/* Implementation for AVL tree */
#include "AvlTree.h"
#include <iostream.h>
/**
* Implements an unbalanced Avl search tree.
* Note that all "matching" is based on the compares method.
*/
/**
* Construct the tree.
*/
template <class Comparable>
AvlTree<Comparable>::AvlTree( const Comparable & notFound ) :
ITEM_NOT_FOUND( notFound ), root( NULL )
{
}
/**
* Copy constructor.
*/
template <class Comparable>
AvlTree<Comparable>::AvlTree( const AvlTree<Comparable> & rhs ) :
ITEM_NOT_FOUND( rhs.ITEM_NOT_FOUND ), root( NULL )
{
*this = rhs;
}
/**
* Destructor for the tree.
*/
template <class Comparable>
AvlTree<Comparable>::~AvlTree( )
{
makeEmpty( );
}
/**
* Insert x into the tree; duplicates are ignored.
*/
template <class Comparable>
void AvlTree<Comparable>::insert( const Comparable & x )
{
insert( x, root );
}
/**
* Remove x from the tree. Nothing is done if x is not found.
*/
template <class Comparable>
void AvlTree<Comparable>::remove( const Comparable & x )
{
cout << "Sorry, remove unimplemented; " << x <<
" still present" << endl;
}
/**
* Find the smallest item in the tree.
* Return smallest item or ITEM_NOT_FOUND if empty.
*/
template <class Comparable>
const Comparable & AvlTree<Comparable>::findMin( ) const
{
return elementAt( findMin( root ) );
}
/**
* Find the largest item in the tree.
* Return the largest item of ITEM_NOT_FOUND if empty.
*/
template <class Comparable>
const Comparable & AvlTree<Comparable>::findMax( ) const
{
return elementAt( findMax( root ) );
}
/**
* Find item x in the tree.
* Return the matching item or ITEM_NOT_FOUND if not found.
*/
template <class Comparable>
const Comparable & AvlTree<Comparable>::
find( const Comparable & x ) const
{
return elementAt( find( x, root ) );
}
/**
* Make the tree logically empty.
*/
template <class Comparable>
void AvlTree<Comparable>::makeEmpty( )
{
makeEmpty( root );
}
/**
* Test if the tree is logically empty.
* Return true if empty, false otherwise.
*/
template <class Comparable>
bool AvlTree<Comparable>::isEmpty( ) const
{
return root == NULL;
}
/**
* Print the tree contents in sorted order.
*/
template <class Comparable>
void AvlTree<Comparable>::printTree( ) const
{
if( isEmpty( ) )
cout << "Empty tree" << endl;
else
printTree( root );
}
/**
* Deep copy.
*/
template <class Comparable>
const AvlTree<Comparable> &
AvlTree<Comparable>::
operator=( const AvlTree<Comparable> & rhs )
{
if( this != &rhs )
{
makeEmpty( );
root = clone( rhs.root );
}
return *this;
}
/**
* Internal method to get element field in node t.
* Return the element field or ITEM_NOT_FOUND if t is NULL.
*/
template <class Comparable>
const Comparable & AvlTree<Comparable>::elementAt( AvlNode<Comparable> *t ) const
{
if( t == NULL )
return ITEM_NOT_FOUND;
else
return t->element;
}
/**
* Internal method to insert into a subtree.
* x is the item to insert.
* t is the node that roots the tree.
*/
template <class Comparable>
void AvlTree<Comparable>::insert( const Comparable & x, AvlNode<Comparable> * & t ) const
{
if( t == NULL )
t = new AvlNode<Comparable>( x, NULL, NULL );
else if( x < t->element )
{
insert( x, t->left );
if( height( t->left ) - height( t->right ) == 2 )
if( x < t->left->element )
rotateWithLeftChild( t );
else
doubleWithLeftChild( t );
}
else if( t->element < x )
{
insert( x, t->right );
if( height( t->right ) - height( t->left ) == 2 )
if( t->right->element < x )
rotateWithRightChild( t );
else
doubleWithRightChild( t );
}
else
; // Duplicate; do nothing
t->height = max( height( t->left ), height( t->right ) ) + 1;
}
/**
* Internal method to find the smallest item in a subtree t.
* Return node containing the smallest item.
*/
template <class Comparable>
AvlNode<Comparable> *
AvlTree<Comparable>::findMin( AvlNode<Comparable> *t ) const
{
if( t == NULL)
return t;
while( t->left != NULL )
t = t->left;
return t;
}
/**
* Internal method to find the largest item in a subtree t.
* Return node containing the largest item.
*/
template <class Comparable>
AvlNode<Comparable> *
AvlTree<Comparable>::findMax( AvlNode<Comparable> *t ) const
{
if( t == NULL )
return t;
while( t->right != NULL )
t = t->right;
return t;
}
/**
* Internal method to find an item in a subtree.
* x is item to search for.
* t is the node that roots the tree.
* Return node containing the matched item.
*/
template <class Comparable>
AvlNode<Comparable> *
AvlTree<Comparable>::find( const Comparable & x, AvlNode<Comparable> *t ) const
{
while( t != NULL )
if( x < t->element )
t = t->left;
else if( t->element < x )
t = t->right;
else
return t; // Match
return NULL; // No match
}
/**
* Internal method to make subtree empty.
*/
template <class Comparable>
void AvlTree<Comparable>::makeEmpty( AvlNode<Comparable> * & t ) const
{
if( t != NULL )
{
makeEmpty( t->left );
makeEmpty( t->right );
delete t;
}
t = NULL;
}
/**
* Internal method to clone subtree.
*/
template <class Comparable>
AvlNode<Comparable> *
AvlTree<Comparable>::clone( AvlNode<Comparable> * t ) const
{
if( t == NULL )
return NULL;
else
return new AvlNode<Comparable>( t->element, clone( t->left ),
clone( t->right ), t->height );
}
/**
* Return the height of node t or -1 if NULL.
*/
template <class Comparable>
int AvlTree<Comparable>::height( AvlNode<Comparable> *t ) const
{
return t == NULL ? -1 : t->height;
}
/**
* Return maximum of lhs and rhs.
*/
template <class Comparable>
int AvlTree<Comparable>::max( int lhs, int rhs ) const
{
return lhs > rhs ? lhs : rhs;
}
/**
* Rotate binary tree node with left child.
* For AVL trees, this is a single rotation for case 1.
* Update heights, then set new root.
*/
template <class Comparable>
void AvlTree<Comparable>::rotateWithLeftChild( AvlNode<Comparable> * & k2 ) const
{
AvlNode<Comparable> *k1 = k2->left;
k2->left = k1->right;
k1->right = k2;
k2->height = max( height( k2->left ), height( k2->right ) ) + 1;
k1->height = max( height( k1->left ), k2->height ) + 1;
k2 = k1;
}
/**
* Rotate binary tree node with right child.
* For AVL trees, this is a single rotation for case 4.
* Update heights, then set new root.
*/
template <class Comparable>
void AvlTree<Comparable>::rotateWithRightChild( AvlNode<Comparable> * & k1 ) const
{
AvlNode<Comparable> *k2 = k1->right;
k1->right = k2->left;
k2->left = k1;
k1->height = max( height( k1->left ), height( k1->right ) ) + 1;
k2->height = max( height( k2->right ), k1->height ) + 1;
k1 = k2;
}
/**
* Double rotate binary tree node: first left child.
* with its right child; then node k3 with new left child.
* For AVL trees, this is a double rotation for case 2.
* Update heights, then set new root.
*/
template <class Comparable>
void AvlTree<Comparable>::doubleWithLeftChild( AvlNode<Comparable> * & k3 ) const
{
rotateWithRightChild( k3->left );
rotateWithLeftChild( k3 );
}
/**
* Double rotate binary tree node: first right child.
* with its left child; then node k1 with new right child.
* For AVL trees, this is a double rotation for case 3.
* Update heights, then set new root.
*/
template <class Comparable>
void AvlTree<Comparable>::doubleWithRightChild( AvlNode<Comparable> * & k1 ) const
{
rotateWithLeftChild( k1->right );
rotateWithRightChild( k1 );
}
/**
* Internal method to print a subtree in sorted order.
* t points to the node that roots the tree.
*/
template <class Comparable>
void AvlTree<Comparable>::printTree( AvlNode<Comparable> *t ) const
{
if( t != NULL )
{
printTree( t->left );
cout << t->element << endl;
printTree( t->right );
}
}
Allocate storage space. Default allocation functions (single-object form). A new operator is used to create the object while a delete operator is used to delete the object. When the object is created by using the new operator, then the object will exist until we explicitly use the delete operator to delete the object. Therefore, we can say that the lifetime of the object is not related to the block structure of the program.
Return the smallest. Returns the smallest of a and b. If both are equivalent, a is returned. min() function is a library function of algorithm header, it is used to find the smallest value from given two values, it accepts two values and returns the smallest value and if both the values are the same it returns the first value. The versions for initializer lists (3) return the smallest of all the elements in the list. Returning the first of them if these are more than one. The function uses operator< (or comp, if provided) to compare the values.
A destructor is a special member function that works just opposite to constructor, unlike constructors that are used for initializing an object, destructors destroy (or delete) the object. Destructors in C++ are members functions in a class that delete an object. They are called when the class object goes out of scope such as when the function ends, the program ends, a delete variable is called etc. Destructors are different from normal member functions as they don't take any argument and don't return anything. Also, destructors have the same name as their class and their name is preceded by a tilde(~).
Every object in C++ has access to its own address through an important pointer called this pointer. The this pointer is an implicit parameter to all member functions. Therefore, inside a member function, this may be used to refer to the invoking object. Friend functions do not have a this pointer, because friends are not members of a class. Only member functions have a this pointer. In C++ programming, this is a keyword that refers to the current instance of the class. There can be 3 main usage of this keyword in C++: • It can be used to pass current object as a parameter to another method. • It can be used to refer current class instance variable. • It can be used to declare indexers. To understand 'this' pointer, it is important to know how objects look at functions and data members of a class.
In computer programming, we use the if statement to run a block code only when a certain condition is met. An if statement can be followed by an optional else statement, which executes when the boolean expression is false. There are three forms of if...else statements in C++: • if statement, • if...else statement, • if...else if...else statement, The if statement evaluates the condition inside the parentheses ( ). If the condition evaluates to true, the code inside the body of if is executed. If the condition evaluates to false, the code inside the body of if is skipped.
#include is a way of including a standard or user-defined file in the program and is mostly written at the beginning of any C/C++ program. This directive is read by the preprocessor and orders it to insert the content of a user-defined or system header file into the following program. These files are mainly imported from an outside source into the current program. The process of importing such files that might be system-defined or user-defined is known as File Inclusion. This type of preprocessor directive tells the compiler to include a file in the source code program.
The if...else statement executes two different codes depending upon whether the test expression is true or false. Sometimes, a choice has to be made from more than 2 possibilities. The if...else ladder allows you to check between multiple test expressions and execute different statements. In C/C++ if-else-if ladder helps user decide from among multiple options. The C/C++ if statements are executed from the top down. As soon as one of the conditions controlling the if is true, the statement associated with that if is executed, and the rest of the C else-if ladder is bypassed. If none of the conditions is true, then the final else statement will be executed.
A C++ template is a powerful feature added to C++. It allows you to define the generic classes and generic functions and thus provides support for generic programming. Generic programming is a technique where generic types are used as parameters in algorithms so that they can work for a variety of data types. We can define a template for a function. For example, if we have an add() function, we can create versions of the add function for adding the int, float or double type values. Where Ttype: It is a placeholder name for a data type used by the function. It is used within the function definition. It is only a placeholder that the compiler will automatically replace this placeholder with the actual data type. class: A class keyword is used to specify a generic type in a template declaration.
In while loop, condition is evaluated first and if it returns true then the statements inside while loop execute, this happens repeatedly until the condition returns false. When condition returns false, the control comes out of loop and jumps to the next statement in the program after while loop. The important point to note when using while loop is that we need to use increment or decrement statement inside while loop so that the loop variable gets changed on each iteration, and at some point condition returns false. This way we can end the execution of while loop otherwise the loop would execute indefinitely. A while loop that never stops is said to be the infinite while loop, when we give the condition in such a way so that it never returns false, then the loops becomes infinite and repeats itself indefinitely.
In C++, classes and structs are blueprints that are used to create the instance of a class. Structs are used for lightweight objects such as Rectangle, color, Point, etc. Unlike class, structs in C++ are value type than reference type. It is useful if you have data that is not intended to be modified after creation of struct. C++ Structure is a collection of different data types. It is similar to the class that holds different types of data. A structure is declared by preceding the struct keyword followed by the identifier(structure name). Inside the curly braces, we can declare the member variables of different types.
Deallocate storage space. Default deallocation functions (single-object form). A delete operator is used to deallocate memory space that is dynamically created using the new operator, calloc and malloc() function, etc., at the run time of a program in C++ language. In other words, a delete operator is used to release array and non-array (pointer) objects from the heap, which the new operator dynamically allocates to put variables on heap memory. We can use either the delete operator or delete [ ] operator in our program to delete the deallocated space. A delete operator has a void return type, and hence, it does not return a value.
The pointer in C++ language is a variable, it is also known as locator or indicator that points to an address of a value. In C++, a pointer refers to a variable that holds the address of another variable. Like regular variables, pointers have a data type. For example, a pointer of type integer can hold the address of a variable of type integer. A pointer of character type can hold the address of a variable of character type. You should see a pointer as a symbolic representation of a memory address. With pointers, programs can simulate call-by-reference. They can also create and manipulate dynamic data structures. In C++, a pointer variable refers to a variable pointing to a specific address in a memory pointed by another variable.
Templates are powerful features of C++ which allows us to write generic programs. Similar to function templates, we can use class templates to create a single class to work with different data types. Class templates come in handy as they can make our code shorter and more manageable. A class template starts with the keyword template followed by template parameter(s) inside <> which is followed by the class declaration. T is the template argument which is a placeholder for the data type used, and class is a keyword. Inside the class body, a member variable var and a member function functionName() are both of type T.
This C++ program implements the "Disjoint" Set data structure. It is a data structure that keeps track of a set of elements partitioned into a number of disjoint ("nonoverlapping")