Projectdoc
Projectdoc
Students:
Abd-Alrahman Al-Rashdan
Thaer Al-Jaafrah
Omar albustanji
Huthaifa Al-Khateeb
Muhammad Al-Qassas
- Insertion: Adding a new node to the tree while maintaining the BST property.
- Deletion: Removing a node from the tree while maintaining the BST property.
- Traversal: Visiting and processing all nodes in a specific order (in-order, pre-order, post-order).
BSTs are commonly used in computer science due to their ability to provide relatively fast operations
for searching and sorting data.
Understanding the structure and rules of a BST is crucial for implementing it in any programming
language like C++, Java, Python, etc. This structure allows for the efficient organization and retrieval
of data.
2
TABLE OF CONTENTS
Abstract ------------------------------------------------------------------------------------------------------2
Table of contents ------------------------------------------------------------------------------------------3
Introduction-------------------------------------------------------------------------------------------------4
Specification-------------------------------------------------------------------------------------------------5
Implementation --------------------------------------------------------------------------------------------6
Recursive Binary Search Tree Operations------------------------------------------------------------7
2.1 The Functions IsFull and IsEmpty ---------------------------------------------------------------- 8
3 conclusion -----------------------------------------------------------------------------------------------13
3
introduction
In the realm of data structures, the linear linked list has proven advantageous for
storing sorted information. However, a notable drawback surfaces when confronted with the
time complexity of searching through lengthy lists. The sequential or linear search, with its
O(N) time complexity, becomes a potential bottleneck for efficiency, particularly as the list
grows. Fortunately, in the pursuit of enhancing search speed while preserving the flexibility of
linked structures, the binary search tree (BST) emerges as a compelling solution.
Unlike arrays, where binary search efficiently navigates a sorted list by finding
midpoints, applying the same strategy to a linked list poses challenge. The practicality of
determining the midpoint in a linked list remains elusive. Enter the binary search tree — a
structure that not only maintains the adaptability of linked lists but also facilitates rapid
O(log2N) access to any node within the collection.
A binary search tree is a structure with two properties: a shape property and a
property that relates the keys of the elements in the structure. We look first at the shape
property. Each node in a singly linked list may point to one other node: the one that follows
it. Thus, a singly linked list is a linear structure; each node in the list (except the last) has a
unique successor. In contrast, a binary tree is a structure in which each node can have two
successor nodes, called children. Each of the children, being nodes in the binary tree, can also
have two child nodes, and these children can also have two children, and so on, giving the
tree its branching structure. The “beginning” of the tree is a unique starting node called the
“root”. If a node in the tree has no children, it is called a “leaf”.
4
Specification
Structure: The placement of each element in the binary tree must satisfy the binary search property: The
value of the key of an element is greater than the value of the key of any element in its left subtree, and
less than the value of the key of any element in its right subtree.
MakeEmpty
Function: Initializes tree to empty state.
Boolean IsEmpty
Function: Determines whether tree is empty.
Boolean IsFull
Function: Determines whether tree is full.
int LengthIs
Function: Determines the number of elements in tree.
Postconditions: If there is an element someItem whose key matches item’s key, then found = true and
item is a copy of someItem; otherwise, found = false and item is unchanged. Tree is unchanged.
InsertItem(ItemType item)
Function: Adds item to tree.
5
DeleteItem(ItemType item)
Function: Deletes the element whose key matches item’s key.
Preconditions: Key member of item is initialized. One and only one element in tree has a key matching
item’s key.
Print(ofstream& outFile)
Function: Prints the values in the tree in ascending key order on outFile.
Postconditions: Items in the tree have been printed in ascending key order. outFile is still open.
ResetTree(OrderType order)
Function: Initializes current position for an iteration through the tree in OrderType order.
Preconditions: Current position is defined. Element at current position is not last in tree.
Postconditions: Current position is one position beyond current position at entry to GetNextItem.
finished = (current position is last in tree). item is a copy of element at current position.
Implementation
We develop the algorithms for the operations specified for the Binary Search Tree ADT and represent the
tree as a linked structure whose nodes are allocated dynamically. Because the binary search tree is
inherently a recursive structure, we first implement the algorithms using recursive solutions. We then
take the InsertItem and DeleteItem functions and show how they can be implemented iteratively. Here is
the first approximation for the class TreeType. If we need more data members, we can add them at a
later time. As with our first brush with linked lists, we choose not to make the class generic. Let’s make
this implementation be a tree of char values.
6
#include <iostream>
struct TreeNode;
typedef char ItemType;
// Assumption: ItemType is a type for which the operators "<"
// and "==" are defined--either an appropriate built-in type or
// a class that overloads these operators.
enum OrderType {PRE_ORDER, IN_ORDER, POST_ORDER};
class TreeType
{
public:
TreeType(); // Constructor.
~TreeType(); // Destructor.
TreeType(const TreeType& originalTree); // Copy constructor.
void operator=(TreeType& originalTree);
void MakeEmpty();
bool IsEmpty() const;
bool IsFull() const;
int LengthIs() const;
void RetrieveItem(ItemType& item, bool& found) const;
void InsertItem(ItemType item);
void DeleteItem(ItemType item);
void ResetTree(OrderType order);
void GetNextItem(ItemType& item, OrderType order,
bool& finished);
void Print(std::ofstream& outFile) const;
private:
TreeNode* root;
};
7
The Functions IsFull and IsEmpty
⮚ IsFull: This function checks whether the binary search tree is full or not. A full binary tree is a tree
where every node other than the leaves has two children. So, if the tree is completely filled with
nodes, except possibly for the bottom level which is filled from left to right, it is considered full.
⮚ IsEmpty: This function checks if the binary search tree is empty, meaning it has no nodes.
Example:
bool TreeType::IsFull() const
// Returns true if the free store has no room for another node
// and false otherwise.
{
TreeNode* location;
try
{
location = new TreeNode;
delete location;
return false;
}
catch(std::bad_alloc exception)
{
return true;
}
}
bool TreeType::IsEmpty() const
// Returns true if the tree is empty and false otherwise.
{
return root == NULL;
}
Example:
int CountNodes(TreeNode* tree);
int TreeType::LengthIs() const
// Calls the recursive function CountNodes to count the
// nodes in the tree.
{
return CountNodes(root);
}
int CountNodes(TreeNode* tree)
// Post: Returns the number of nodes in the tree.
{
if (tree == NULL)
return 0;
else
8
return CountNodes(tree->left) + CountNodes(tree->right) + 1;
}
Example:
void Retrieve(TreeNode* tree,
ItemType& item, bool& found){
if (tree == NULL)
found = false; // item is not found.
else if (item < tree->info)
Retrieve(tree->left, item, found); // Search left subtree.
else if (item > tree->info)
Retrieve(tree->right, item, found);// Search right subtree.
}
else {
item = tree->info;
found = true;
}
void TreeType::RetrieveItem(ItemType& item, bool& found) const{
Retrieve(root, item, found);
}
Example:
void Insert(TreeNode*& tree, ItemType item)
// Inserts item into tree.
if (tree == NULL)
{// Insertion place found. tree = new TreeNode;
tree->right = NULL;
tree->left = NULL;
tree->info = item;
}
else if (item < tree->info)
}
Insert(tree->left, item);
else
Insert(tree->right, item);
9
}
Example:
void Delete(TreeNode*& tree, ItemType item){
if (item < tree->info)
Delete(tree->left, item);
else if (item > tree->info)
// Look in left subtree.
Delete(tree->right, item); // Look in right subtree.
else
DeleteNode(tree); // Node found; call DeleteNode.
}
void TreeType::DeleteItem(ItemType item)
{
Delete(root, item);
}
Example:
void PrintTree(TreeNode* tree, std::ofstream& outFile)
{
if (tree != NULL)
{
PrintTree(tree->left, outFile); // Print left subtree.
outFile << tree->info;
PrintTree(tree->right, outFile); // Print right subtree.
}}
void TreeType::Print(std::ofstream& outFile) const
{
PrintTree(root, outFile);
}
10
The Class Constructor and Destructor
⮚ Constructor: Initializes the binary search tree, often setting the root node to nullptr or any initial
values.
⮚ Destructor: Releases memory and resources occupied by the binary search tree when it goes out
of scope or is explicitly destroyed.
Example:
void Destroy(TreeNode*& tree);
TreeType::~TreeType()
// Calls recursive function Destroy to destroy the tree.
{
Destroy(root);
}
void Destroy(TreeNode*& tree)
// Post: tree is empty; nodes have been deallocated.
{
if (tree != NULL)
{
Destroy(tree->left);
Destroy(tree->right);
delete tree;
}
}
Example:
//Reset the binary search tree
void ResetTree(Node* root) {
if (root == nullptr) {
return;
}
11
ResetTree(root->right); // Recursively clear right subtree
return current;
}
conclusion
In conclusion, BSTs are versatile data structures that provide efficient searching capabilities, making
them invaluable in numerous software applications. Their effectiveness lies in their ability to maintain
ordered data and perform operations swiftly, underscoring their significance in modern programming
and software development.
As technology evolves, further research and enhancements in balancing techniques and optimizing BST
operations will continue to refine their efficiency and applicability across various domains.
12