C++ Programming Code Examples
C++ > Data Structures and Algorithm Analysis in C++ Code Examples
Implementation for AA-tree
/* Implementation for AA-tree */
#include "AATree.h"
#include <iostream.h>
/**
* Construct the tree.
*/
template <class Comparable>
AATree<Comparable>::AATree( const Comparable & notFound ) :
ITEM_NOT_FOUND( notFound )
{
nullNode = new AANode<Comparable>;
nullNode->left = nullNode->right = nullNode;
nullNode->level = 0;
root = nullNode;
}
/**
* Copy constructor.
*/
template <class Comparable>
AATree<Comparable>::AATree( const AATree<Comparable> & rhs ) :
ITEM_NOT_FOUND( rhs.ITEM_NOT_FOUND )
{
nullNode = new AANode<Comparable>;
nullNode->left = nullNode->right = nullNode;
nullNode->level = 0;
root = clone( rhs.root );
}
/**
* Destructor for the tree.
*/
template <class Comparable>
AATree<Comparable>::~AATree( )
{
makeEmpty( );
delete nullNode;
}
/**
* Insert x into the tree; duplicates are ignored.
*/
template <class Comparable>
void AATree<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 AATree<Comparable>::remove( const Comparable & x )
{
remove( x, root );
}
/**
* Find the smallest item in the tree.
* Return smallest item or ITEM_NOT_FOUND if empty.
*/
template <class Comparable>
const Comparable & AATree<Comparable>::findMin( ) const
{
if( isEmpty( ) )
return ITEM_NOT_FOUND;
AANode<Comparable> *ptr = root;
while( ptr->left != nullNode )
ptr = ptr->left;
return ptr->element;
}
/**
* Find the largest item in the tree.
* Return the largest item of ITEM_NOT_FOUND if empty.
*/
template <class Comparable>
const Comparable & AATree<Comparable>::findMax( ) const
{
if( isEmpty( ) )
return ITEM_NOT_FOUND;
AANode<Comparable> *ptr = root;
while( ptr->right != nullNode )
ptr = ptr->right;
return ptr->element;
}
/**
* Find item x in the tree.
* Return the matching item or ITEM_NOT_FOUND if not found.
*/
template <class Comparable>
const Comparable & AATree<Comparable>::
find( const Comparable & x ) const
{
AANode<Comparable> *current = root;
nullNode->element = x;
for( ; ; )
{
if( x < current->element )
current = current->left;
else if( current->element < x )
current = current->right;
else if( current != nullNode )
return current->element;
else
return ITEM_NOT_FOUND;
}
}
/**
* Make the tree logically empty.
*/
template <class Comparable>
void AATree<Comparable>::makeEmpty( )
{
makeEmpty( root );
}
/**
* Test if the tree is logically empty.
* Return true if empty, false otherwise.
*/
template <class Comparable>
bool AATree<Comparable>::isEmpty( ) const
{
return root == nullNode;
}
/**
* Print the tree contents in sorted order.
*/
template <class Comparable>
void AATree<Comparable>::printTree( ) const
{
if( root == nullNode )
cout << "Empty tree" << endl;
else
printTree( root );
}
/**
* Deep copy.
*/
template <class Comparable>
const AATree<Comparable> &
AATree<Comparable>::operator=( const AATree<Comparable> & rhs )
{
if( this != &rhs )
{
makeEmpty( );
root = clone( rhs.root );
}
return *this;
}
/**
* Internal method to insert into a subtree.
* x is the item to insert.
* t is the node that roots the tree.
* Set the new root.
*/
template <class Comparable>
void AATree<Comparable>::
insert( const Comparable & x, AANode<Comparable> * & t )
{
if( t == nullNode )
t = new AANode<Comparable>( x, nullNode, nullNode );
else if( x < t->element )
insert( x, t->left );
else if( t->element < x )
insert( x, t->right );
else
return; // Duplicate; do nothing
skew( t );
split( t );
}
/**
* Internal method to remove from a subtree.
* x is the item to remove.
* t is the node that roots the tree.
* Set the new root.
*/
template <class Comparable>
void AATree<Comparable>::
remove( const Comparable & x, AANode<Comparable> * & t )
{
static AANode<Comparable> *lastNode, *deletedNode = nullNode;
if( t != nullNode )
{
// Step 1: Search down the tree and set lastNode and deletedNode
lastNode = t;
if( x < t->element )
remove( x, t->left );
else
{
deletedNode = t;
remove( x, t->right );
}
// Step 2: If at the bottom of the tree and
// x is present, we remove it
if( t == lastNode )
{
if( deletedNode == nullNode || x != deletedNode->element )
return; // Item not found; do nothing
deletedNode->element = t->element;
deletedNode = nullNode;
t = t->right;
delete lastNode;
}
// Step 3: Otherwise, we are not at the bottom; rebalance
else
if( t->left->level < t->level - 1 ||
t->right->level < t->level - 1 )
{
if( t->right->level > --t->level )
t->right->level = t->level;
skew( t );
skew( t->right );
skew( t->right->right );
split( t );
split( t->right );
}
}
}
/**
* Internal method to make subtree empty.
*/
template <class Comparable>
void AATree<Comparable>::makeEmpty( AANode<Comparable> * & t )
{
if( t != nullNode )
{
makeEmpty( t->left );
makeEmpty( t->right );
delete t;
}
t = nullNode;
}
/**
* Internal method to print a subtree in sorted order.
* @param t the node that roots the tree.
*/
template <class Comparable>
void AATree<Comparable>::printTree( AANode<Comparable> *t ) const
{
if( t != nullNode )
{
printTree( t->left );
cout << t->element << endl;
printTree( t->right );
}
}
/**
* Rotate binary tree node with left child.
*/
template <class Comparable>
void AATree<Comparable>::rotateWithLeftChild( AANode<Comparable> * & k2 ) const
{
AANode<Comparable> *k1 = k2->left;
k2->left = k1->right;
k1->right = k2;
k2 = k1;
}
/**
* Rotate binary tree node with right child.
*/
template <class Comparable>
void AATree<Comparable>::rotateWithRightChild( AANode<Comparable> * & k1 ) const
{
AANode<Comparable> *k2 = k1->right;
k1->right = k2->left;
k2->left = k1;
k1 = k2;
}
/**
* Skew primitive for AA-trees.
* t is the node that roots the tree.
*/
template <class Comparable>
void AATree<Comparable>::skew( AANode<Comparable> * & t ) const
{
if( t->left->level == t->level )
rotateWithLeftChild( t );
}
/**
* Split primitive for AA-trees.
* t is the node that roots the tree.
*/
template <class Comparable>
void AATree<Comparable>::split( AANode<Comparable> * & t ) const
{
if( t->right->right->level == t->level )
{
rotateWithRightChild( t );
t->level++;
}
}
/**
* Internal method to clone subtree.
*/
template <class Comparable>
AANode<Comparable> *
AATree<Comparable>::clone( AANode<Comparable> * t ) const
{
if( t == t->left ) // Cannot test against nullNode!!!
return nullNode;
else
return new AANode<Comparable>( t->element, clone( t->left ),
clone( t->right ), t->level );
}
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(~).
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.
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.
Static is a keyword in C++ used to give special characteristics to an element. Static elements are allocated storage only once in a program lifetime in static storage area. And they have a scope till the program lifetime. In C++, static is a keyword or modifier that belongs to the type not instance. So instance is not required to access the static members. In C++, static can be field, method, constructor, class, properties, operator and event. Advantage of C++ static keyword: Memory efficient. Now we don't need to create instance for accessing the static members, so it saves memory. Moreover, it belongs to the type, so it will not get memory each time when instance is created.
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.
#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.
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.
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.
Logical Operators are used to compare and connect two or more expressions or variables, such that the value of the expression is completely dependent on the original expression or value or variable. We use logical operators to check whether an expression is true or false. If the expression is true, it returns 1 whereas if the expression is false, it returns 0. Assume variable A holds 1 and variable B holds 0:
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.
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.
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 computer programming, loops are used to repeat a block of code. For example, when you are displaying number from 1 to 100 you may want set the value of a variable to 1 and display it 100 times, increasing its value by 1 on each loop iteration. When you know exactly how many times you want to loop through a block of code, use the for loop instead of a while loop. A for loop is a repetition control structure that allows you to efficiently write a loop that needs to execute a specific number of times.
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.
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.
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.