[fix/feat]: remove memory leak in avltree.cpp (#2429)

* fix: remove memory leak by adding deleteAllNodes

* clang-format and clang-tidy fixes for 9d76f8bd

* docs: explain usage of standard headers

* docs: use doxygen syntax

* docs: document parameters of the functions

* style: use proper spelling

* style: simplify logic in deleteNode

* docs: add missing [in]

* docs: add missing slashes

* docs: document `main`

Co-authored-by: David Leal <halfpacho@gmail.com>

* updating DIRECTORY.md

* clang-format and clang-tidy fixes for c852f62d

---------

Co-authored-by: github-actions[bot] <github-actions@users.noreply.github.com>
Co-authored-by: David Leal <halfpacho@gmail.com>
This commit is contained in:
Piotr Idzik 2023-02-04 01:40:26 +01:00 committed by GitHub
parent dc8ecfbf50
commit cc33efd3b6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 110 additions and 58 deletions

View File

@ -19,6 +19,7 @@
* [Count Of Trailing Ciphers In Factorial N](https://github.com/TheAlgorithms/C-Plus-Plus/blob/HEAD/bit_manipulation/count_of_trailing_ciphers_in_factorial_n.cpp) * [Count Of Trailing Ciphers In Factorial N](https://github.com/TheAlgorithms/C-Plus-Plus/blob/HEAD/bit_manipulation/count_of_trailing_ciphers_in_factorial_n.cpp)
* [Find Non Repeating Number](https://github.com/TheAlgorithms/C-Plus-Plus/blob/HEAD/bit_manipulation/find_non_repeating_number.cpp) * [Find Non Repeating Number](https://github.com/TheAlgorithms/C-Plus-Plus/blob/HEAD/bit_manipulation/find_non_repeating_number.cpp)
* [Hamming Distance](https://github.com/TheAlgorithms/C-Plus-Plus/blob/HEAD/bit_manipulation/hamming_distance.cpp) * [Hamming Distance](https://github.com/TheAlgorithms/C-Plus-Plus/blob/HEAD/bit_manipulation/hamming_distance.cpp)
* [Power Of 2](https://github.com/TheAlgorithms/C-Plus-Plus/blob/HEAD/bit_manipulation/power_of_2.cpp)
* [Set Kth Bit](https://github.com/TheAlgorithms/C-Plus-Plus/blob/HEAD/bit_manipulation/set_kth_bit.cpp) * [Set Kth Bit](https://github.com/TheAlgorithms/C-Plus-Plus/blob/HEAD/bit_manipulation/set_kth_bit.cpp)
* [Travelling Salesman Using Bit Manipulation](https://github.com/TheAlgorithms/C-Plus-Plus/blob/HEAD/bit_manipulation/travelling_salesman_using_bit_manipulation.cpp) * [Travelling Salesman Using Bit Manipulation](https://github.com/TheAlgorithms/C-Plus-Plus/blob/HEAD/bit_manipulation/travelling_salesman_using_bit_manipulation.cpp)

View File

@ -1,11 +1,12 @@
/** /**
* @file * @file
* @brief [Find whether a given number is power of 2] * @brief [Find whether a given number is power of 2]
* (https://www.geeksforgeeks.org/program-to-find-whether-a-given-number-is-power-of-2/) implementation * (https://www.geeksforgeeks.org/program-to-find-whether-a-given-number-is-power-of-2/)
* implementation
* *
* @details * @details
* We are given a positive integer number. We need to check whether the number is power of * We are given a positive integer number. We need to check whether the number
* 2 or not. * is power of 2 or not.
* *
* A binary number consists of two digits. They are 0 & 1. Digit 1 is known as * A binary number consists of two digits. They are 0 & 1. Digit 1 is known as
* set bit in computer terms. * set bit in computer terms.
@ -27,16 +28,16 @@ namespace bit_manipulation {
* @param n is the number who will be checked * @param n is the number who will be checked
* @returns either true or false * @returns either true or false
*/ */
bool isPowerOfTwo( bool isPowerOfTwo(std ::int64_t n) { // int64_t is preferred over int so that
std ::int64_t n) { // int64_t is preferred over int so that // no Overflow can be there.
// no Overflow can be there.
return n > 0 && !(n & n - 1); // If we subtract a power of 2 numbers by 1 return n > 0 && !(n & n - 1); // If we subtract a power of 2 numbers by 1
// then all unset bits after the only set bit become set; and the set bit becomes unset. // then all unset bits after the only set bit become set; and the set bit
// becomes unset.
// If a number n is a power of 2 then bitwise and of n-1 and n will be zero. // If a number n is a power of 2 then bitwise and of n-1 and n will be zero.
// The expression n&(n-1) will not work when n is 0. // The expression n&(n-1) will not work when n is 0.
// To handle this case also, our expression will become n& (!n&(n-1)) // To handle this case also, our expression will become n& (!n&(n-1))
} }
} // namespace bit_manipulation } // namespace bit_manipulation

View File

@ -6,38 +6,52 @@
* \warning This program is a poor implementation and does not utilize any of * \warning This program is a poor implementation and does not utilize any of
* the C++ STL features. * the C++ STL features.
*/ */
#include <algorithm> #include <algorithm> /// for std::max
#include <iostream> #include <iostream> /// for std::cout
#include <queue> #include <queue> /// for std::queue
typedef struct node { using node = struct node {
int data; int data;
int height; int height;
struct node *left; struct node *left;
struct node *right; struct node *right;
} node; };
/** Create and return a new Node */ /**
* @brief creates and returns a new node
* @param[in] data value stored in the node
* @return newly created node
*/
node *createNode(int data) { node *createNode(int data) {
node *nn = new node(); node *nn = new node();
nn->data = data; nn->data = data;
nn->height = 0; nn->height = 0;
nn->left = NULL; nn->left = nullptr;
nn->right = NULL; nn->right = nullptr;
return nn; return nn;
} }
/** Returns height of tree */ /**
* @param[in] root the root of the tree
* @return height of tree
*/
int height(node *root) { int height(node *root) {
if (root == NULL) if (root == nullptr) {
return 0; return 0;
}
return 1 + std::max(height(root->left), height(root->right)); return 1 + std::max(height(root->left), height(root->right));
} }
/** Returns difference between height of left and right subtree */ /**
* @param[in] root of the tree
* @return difference between height of left and right subtree
*/
int getBalance(node *root) { return height(root->left) - height(root->right); } int getBalance(node *root) { return height(root->left) - height(root->right); }
/** Returns Node after Right Rotation */ /**
* @param root of the tree to be rotated
* @return node after right rotation
*/
node *rightRotate(node *root) { node *rightRotate(node *root) {
node *t = root->left; node *t = root->left;
node *u = t->right; node *u = t->right;
@ -46,7 +60,10 @@ node *rightRotate(node *root) {
return t; return t;
} }
/** Returns Node after Left Rotation */ /**
* @param root of the tree to be rotated
* @return node after left rotation
*/
node *leftRotate(node *root) { node *leftRotate(node *root) {
node *t = root->right; node *t = root->right;
node *u = t->left; node *u = t->left;
@ -55,55 +72,67 @@ node *leftRotate(node *root) {
return t; return t;
} }
/** Returns node with minimum value in the tree */ /**
* @param root of the tree
* @returns node with minimum value in the tree
*/
node *minValue(node *root) { node *minValue(node *root) {
if (root->left == NULL) if (root->left == nullptr) {
return root; return root;
}
return minValue(root->left); return minValue(root->left);
} }
/** Balanced Insertion */ /**
* @brief inserts a new element into AVL tree
* @param root of the tree
* @param[in] item the element to be insterted into the tree
* @return root of the updated tree
*/
node *insert(node *root, int item) { node *insert(node *root, int item) {
node *nn = createNode(item); if (root == nullptr) {
if (root == NULL) return createNode(item);
return nn; }
if (item < root->data) if (item < root->data) {
root->left = insert(root->left, item); root->left = insert(root->left, item);
else } else {
root->right = insert(root->right, item); root->right = insert(root->right, item);
}
int b = getBalance(root); int b = getBalance(root);
if (b > 1) { if (b > 1) {
if (getBalance(root->left) < 0) if (getBalance(root->left) < 0) {
root->left = leftRotate(root->left); // Left-Right Case root->left = leftRotate(root->left); // Left-Right Case
return rightRotate(root); // Left-Left Case }
return rightRotate(root); // Left-Left Case
} else if (b < -1) { } else if (b < -1) {
if (getBalance(root->right) > 0) if (getBalance(root->right) > 0) {
root->right = rightRotate(root->right); // Right-Left Case root->right = rightRotate(root->right); // Right-Left Case
return leftRotate(root); // Right-Right Case }
return leftRotate(root); // Right-Right Case
} }
return root; return root;
} }
/** Balanced Deletion */ /**
node *deleteNode(node *root, int key) { * @brief removes a given element from AVL tree
if (root == NULL) * @param root of the tree
* @param[in] element the element to be deleted from the tree
* @return root of the updated tree
*/
node *deleteNode(node *root, int element) {
if (root == nullptr) {
return root; return root;
if (key < root->data) }
root->left = deleteNode(root->left, key); if (element < root->data) {
else if (key > root->data) root->left = deleteNode(root->left, element);
root->right = deleteNode(root->right, key); } else if (element > root->data) {
root->right = deleteNode(root->right, element);
else { } else {
// Node to be deleted is leaf node or have only one Child // Node to be deleted is leaf node or have only one Child
if (!root->right) { if (!root->right || !root->left) {
node *temp = root->left; node *temp = !root->right ? root->left : root->right;
delete (root); delete root;
root = NULL;
return temp;
} else if (!root->left) {
node *temp = root->right;
delete (root);
root = NULL;
return temp; return temp;
} }
// Node to be deleted have both left and right subtrees // Node to be deleted have both left and right subtrees
@ -115,7 +144,22 @@ node *deleteNode(node *root, int key) {
return root; return root;
} }
/** LevelOrder (Breadth First Search) */ /**
* @brief calls delete on every node
* @param root of the tree
*/
void deleteAllNodes(const node *const root) {
if (root) {
deleteAllNodes(root->left);
deleteAllNodes(root->right);
delete root;
}
}
/**
* @brief prints given tree in the LevelOrder
* @param[in] root of the tree
*/
void levelOrder(node *root) { void levelOrder(node *root) {
std::queue<node *> q; std::queue<node *> q;
q.push(root); q.push(root);
@ -123,18 +167,23 @@ void levelOrder(node *root) {
root = q.front(); root = q.front();
std::cout << root->data << " "; std::cout << root->data << " ";
q.pop(); q.pop();
if (root->left) if (root->left) {
q.push(root->left); q.push(root->left);
if (root->right) }
if (root->right) {
q.push(root->right); q.push(root->right);
}
} }
} }
/** Main function */ /**
* @brief Main function
* @returns 0 on exit
*/
int main() { int main() {
// Testing AVL Tree // Testing AVL Tree
node *root = NULL; node *root = nullptr;
int i; int i = 0;
for (i = 1; i <= 7; i++) root = insert(root, i); for (i = 1; i <= 7; i++) root = insert(root, i);
std::cout << "LevelOrder: "; std::cout << "LevelOrder: ";
levelOrder(root); levelOrder(root);
@ -144,5 +193,6 @@ int main() {
root = deleteNode(root, 4); // Deletin key with value 4 root = deleteNode(root, 4); // Deletin key with value 4
std::cout << "\nLevelOrder: "; std::cout << "\nLevelOrder: ";
levelOrder(root); levelOrder(root);
deleteAllNodes(root);
return 0; return 0;
} }