Banana-Leopard/TASTY huggingface dataset:
// C++ program to check if a given binary tree is complete
// or not
#include <bits/stdc++.h>
using namespace std;
  
// A binary tree node has data, pointer to left child and a
// pointer to right child
struct node {
    int data;
    struct node* left;
    struct node* right;
};
  
// Given a binary tree, return true if the tree is complete
// else false
bool isCompleteBT(node* root)
{
    // Base Case: An empty tree is complete Binary Tree
    if (root == NULL)
        return true;
  
    // Create an empty queue
    // int rear, front;
    // node **queue = createQueue(&front, &rear);
    queue<node*> q;
    q.push(root);
    // Create a flag variable which will be set true when a
    // non full node is seen
    bool flag = false;
  
    // Do level order traversal using queue.
    // enQueue(queue, &rear, root);
    while (!q.empty()) {
        node* temp = q.front();
        q.pop();
  
        /* Check if left child is present*/
        if (temp->left) {
            // If we have seen a non full node, and we see a
            // node with non-empty left child, then the
            // given tree is not a complete Binary Tree
            if (flag == true)
                return false;
  
            q.push(temp->left); // Enqueue Left Child
        }
        // If this a non-full node, set the flag as true
        else
            flag = true;
  
        /* Check if right child is present*/
        if (temp->right) {
            // If we have seen a non full node, and we see a
            // node with non-empty right child, then the
            // given tree is not a complete Binary Tree
            if (flag == true)
                return false;
  
            q.push(temp->right); // Enqueue Right Child
        }
        // If this a non-full node, set the flag as true
        else
            flag = true;
    }
  
    // If we reach here, then the tree is complete Binary
    // Tree
    return true;
}
  
/* Helper function that allocates a new node with the
given data and NULL left and right pointers. */
struct node* newNode(int data)
{
    struct node* node
        = (struct node*)malloc(sizeof(struct node));
    node->data = data;
    node->left = NULL;
    node->right = NULL;
    return (node);
}
  
/* Driver code*/
int main()
{
    /* Let us construct the following Binary Tree which
        is not a complete Binary Tree
              1
            /  \
            2   3
           / \  /
          4   5 6
        */
  
    node* root = newNode(1);
    root->left = newNode(2);
    root->right = newNode(3);
    root->left->left = newNode(4);
    root->left->right = newNode(5);
    root->right->left = newNode(6);
  
    if (isCompleteBT(root) == true)
        cout << "Complete Binary Tree";
    else
        cout << "NOT Complete Binary Tree";
  
    return 0;
}
  
// This code is contributed by Sania Kumari Gupta (kriSania804)

Time complexity: linear
Space complexity: linear
/* Program to check if a given Binary Tree is balanced like a Red-Black Tree */
#include <bits/stdc++.h>
using namespace std;
 
struct Node
{
    int key;
    Node *left, *right;
};
 
/* utility that allocates a new Node with the given key  */
Node* newNode(int key)
{
    Node* node = new Node;
    node->key = key;
    node->left = node->right = NULL;
    return (node);
}
 
// Returns returns tree if the Binary tree is balanced like a Red-Black
// tree. This function also sets value in maxh and minh (passed by
// reference). maxh and minh are set as maximum and minimum heights of root.
bool isBalancedUtil(Node *root, int &maxh, int &minh)
{
    // Base case
    if (root == NULL)
    {
        maxh = minh = 0;
        return true;
    }
 
    int lmxh, lmnh; // To store max and min heights of left subtree
    int rmxh, rmnh; // To store max and min heights of right subtree
 
    // Check if left subtree is balanced, also set lmxh and lmnh
    if (isBalancedUtil(root->left, lmxh, lmnh) == false)
        return false;
 
    // Check if right subtree is balanced, also set rmxh and rmnh
    if (isBalancedUtil(root->right, rmxh, rmnh) == false)
        return false;
 
    // Set the max and min heights of this node for the parent call
    maxh = max(lmxh, rmxh) + 1;
    minh = min(lmnh, rmnh) + 1;
 
    // See if this node is balanced
    if (maxh <= 2*minh)
        return true;
 
    return false;
}
 
// A wrapper over isBalancedUtil()
bool isBalanced(Node *root)
{
    int maxh, minh;
    return isBalancedUtil(root, maxh, minh);
}
 
/* Driver program to test above functions*/
int main()
{
    Node * root = newNode(10);
    root->left = newNode(5);
    root->right = newNode(100);
    root->right->left = newNode(50);
    root->right->right = newNode(150);
    root->right->left->left = newNode(40);
    isBalanced(root)? cout << "Balanced" : cout << "Not Balanced";
 
    return 0;
}

Time complexity: linear
Space complexity: linear
// C++ program to check if two trees are mirror
// of each other
#include<bits/stdc++.h>
using namespace std;
 
/* A binary tree node has data, pointer to
   left child and a pointer to right child */
struct Node
{
    int data;
    Node* left, *right;
};
 
/* Given two trees, return true if they are
   mirror of each other */
/*As function has to return bool value instead integer value*/
bool areMirror(Node* a, Node* b)
{
    /* Base case : Both empty */
    if (a==NULL && b==NULL)
        return true;
 
    // If only one is empty
    if (a==NULL || b == NULL)
        return false;
 
    /* Both non-empty, compare them recursively
     Note that in recursive calls, we pass left
     of one tree and right of other tree */
    return  a->data == b->data &&
            areMirror(a->left, b->right) &&
            areMirror(a->right, b->left);
}
 
/* Helper function that allocates a new node */
Node* newNode(int data)
{
    Node* node = new Node;
    node->data  = data;
    node->left  =  node->right  = NULL;
    return(node);
}
 
/* Driver program to test areMirror() */
int main()
{
    Node *a = newNode(1);
    Node *b = newNode(1);
    a->left = newNode(2);
    a->right = newNode(3);
    a->left->left  = newNode(4);
    a->left->right = newNode(5);
 
    b->left = newNode(3);
    b->right = newNode(2);
    b->right->left = newNode(5);
    b->right->right = newNode(4);
 
    areMirror(a, b)? cout << "Yes" : cout << "No";
 
    return 0;
}

Time complexity: linear
Space complexity: logn
// C++ implementation to check whether the two 
// binary trees are mirrors of each other or not
#include <bits/stdc++.h>
using namespace std;
  
// structure of a node in binary tree
struct Node
{
    int data;
    struct Node *left, *right;
};
  
// Utility function to create and return 
// a new node for a binary tree
struct Node* newNode(int data)
{
    struct Node *temp = new Node();
    temp->data = data;
    temp->left = temp->right = NULL;
    return temp;
}
  
// function to check whether the two binary trees
// are mirrors of each other or not
string areMirrors(Node *root1, Node *root2)
{
    stack<Node*> st1, st2;
    while (1)
    {
        // iterative inorder traversal of 1st tree and
        // reverse inorder traversal of 2nd tree
        while (root1 && root2)
        {
            // if the corresponding nodes in the two traversal
            // have different data values, then they are not
            // mirrors of each other.
            if (root1->data != root2->data)
                return "No";
                  
            st1.push(root1);
            st2.push(root2);
            root1 = root1->left;
            root2 = root2->right;    
        }
          
        // if at any point one root becomes null and
        // the other root is not null, then they are 
        // not mirrors. This condition verifies that
        // structures of tree are mirrors of each other.
        if (!(root1 == NULL && root2 == NULL))
            return "No";
              
        if (!st1.empty() && !st2.empty())
        {
            root1 = st1.top();
            root2 = st2.top();
            st1.pop(); 
            st2.pop();
              
            /* we have visited the node and its left subtree.
               Now, it's right subtree's turn */
            root1 = root1->right;
              
            /* we have visited the node and its right subtree.
               Now, it's left subtree's turn */
            root2 = root2->left;
        }    
          
        // both the trees have been completely traversed
        else
            break;
    }
      
    // trees are mirrors of each other
    return "Yes";
}
  
// Driver program to test above
int main()
{
    // 1st binary tree formation
    Node *root1 = newNode(1);            /*         1          */                      
    root1->left = newNode(3);            /*       /   \        */
    root1->right = newNode(2);           /*      3     2       */ 
    root1->right->left = newNode(5);     /*          /   \     */  
    root1->right->right = newNode(4);    /*         5     4    */
      
    // 2nd binary tree formation    
    Node *root2 = newNode(1);            /*         1          */                      
    root2->left = newNode(2);            /*       /   \        */
    root2->right = newNode(3);           /*      2     3       */
    root2->left->left = newNode(4);      /*    /   \           */
    root2->left->right = newNode(5);     /*   4    5           */
          
    cout << areMirrors(root1, root2);
    return 0;
} 

Time complexity: linear
Space complexity: linear
// C++ program to check if a given Binary
// Tree is symmetric or not
#include<bits/stdc++.h>
using namespace std;
 
// A Binary Tree Node
struct Node
{
    int key;
    struct Node* left, *right;
};
 
// Utility function to create new Node
Node *newNode(int key)
{
    Node *temp = new Node;
    temp->key = key;
    temp->left = temp->right = NULL;
    return (temp);
}
 
// Returns true if a tree is symmetric
// i.e. mirror image of itself
bool isSymmetric(struct Node* root)
{
    if(root == NULL)
        return true;
     
    // If it is a single tree node, then
    // it is a symmetric tree.
    if(!root->left && !root->right)
        return true;
     
    queue <Node*> q;
     
    // Add root to queue two times so that
    // it can be checked if either one child
    // alone is NULL or not.
    q.push(root);
    q.push(root);
     
    // To store two nodes for checking their
    // symmetry.
    Node* leftNode, *rightNode;
     
    while(!q.empty()){
         
        // Remove first two nodes to check
        // their symmetry.
        leftNode = q.front();
        q.pop();
         
        rightNode = q.front();
        q.pop();
         
        // if both left and right nodes
        // exist, but have different
        // values--> inequality, return false
        if(leftNode->key != rightNode->key){
        return false;
        }
         
        // Push left child of left subtree node
        // and right child of right subtree
        // node in queue.
        if(leftNode->left && rightNode->right){
            q.push(leftNode->left);
            q.push(rightNode->right);
        }
         
        // If only one child is present alone
        // and other is NULL, then tree
        // is not symmetric.
        else if (leftNode->left || rightNode->right)
        return false;
         
        // Push right child of left subtree node
        // and left child of right subtree node
        // in queue.
        if(leftNode->right && rightNode->left){
            q.push(leftNode->right);
            q.push(rightNode->left);
        }
         
        // If only one child is present alone
        // and other is NULL, then tree
        // is not symmetric.
        else if(leftNode->right || rightNode->left)
        return false;
    }
     
    return true;
}
 
// Driver program
int main()
{
    // Let us construct the Tree shown in
    // the above figure
    Node *root = newNode(1);
    root->left = newNode(2);
    root->right = newNode(2);
    root->left->left = newNode(3);
    root->left->right = newNode(4);
    root->right->left = newNode(4);
    root->right->right = newNode(3);
 
    if(isSymmetric(root))
        cout << "The given tree is Symmetric";
    else
        cout << "The given tree is not Symmetric";
    return 0;
}
 
// This code is contributed by Nikhil jindal.

Time complexity: linear
Space complexity: logn
#include <bits/stdc++.h>
using namespace std;
 
/* A binary tree node has key, pointer to left
   child and a pointer to right child */
struct Node {
    int key;
    struct Node *left, *right;
};
 
/* To create a newNode of tree and return pointer */
struct Node* newNode(int key)
{
    Node* temp = new Node;
    temp->key = key;
    temp->left = temp->right = NULL;
    return (temp);
}
 
// Takes two parameters - same initially and
// calls recursively
void printMiddleLevelUtil(Node* a, Node* b)
{
    // Base case e
    if (a == NULL || b == NULL)
        return;
 
    // Fast pointer has reached the leaf so print
    // value at slow pointer
    if ((b->left == NULL) && (b->right == NULL)) {
        cout << a->key << " ";
        return;
    }
 
    // Recursive call
    // root.left.left and root.left.right will
    // print same value
    // root.right.left and root.right.right
    // will print same value
    // So we use any one of the condition
    if (b->left->left) {
        printMiddleLevelUtil(a->left, b->left->left);
        printMiddleLevelUtil(a->right, b->left->left);
    }
    else {
        printMiddleLevelUtil(a->left, b->left);
        printMiddleLevelUtil(a->right, b->left);
    }
}
 
// Main printing method that take a Tree as input
void printMiddleLevel(Node* node)
{
    printMiddleLevelUtil(node, node);
}
 
// Driver program to test above functions
int main()
{
 
    Node* n1 = newNode(1);
    Node* n2 = newNode(2);
    Node* n3 = newNode(3);
    Node* n4 = newNode(4);
    Node* n5 = newNode(5);
    Node* n6 = newNode(6);
    Node* n7 = newNode(7);
 
    n2->left = n4;
    n2->right = n5;
    n3->left = n6;
    n3->right = n7;
    n1->left = n2;
    n1->right = n3;
 
    printMiddleLevel(n1);
}
 
// This code is contributed by Prasad Kshirsagar

Time complexity: linear
Space complexity: logn
// C++ program to Print root to leaf path WITHOUT
// using recursion
#include <bits/stdc++.h>
using namespace std;
 
/* A binary tree */
struct Node
{
    int data;
    struct Node *left, *right;
};
 
/* Helper function that allocates a new node
   with the given data and NULL left and right
   pointers.*/
Node* newNode(int data)
{
    Node* node = new Node;
    node->data = data;
    node->left = node->right = NULL;
    return node;
}
 
/* Function to print root to leaf path for a leaf
   using parent nodes stored in map */
void printTopToBottomPath(Node* curr,
                         map<Node*, Node*> parent)
{
    stack<Node*> stk;
 
    // start from leaf node and keep on pushing
    // nodes into stack till root node is reached
    while (curr)
    {
        stk.push(curr);
        curr = parent[curr];
    }
 
    // Start popping nodes from stack and print them
    while (!stk.empty())
    {
        curr = stk.top();
        stk.pop();
        cout << curr->data << " ";
    }
    cout << endl;
}
 
/* An iterative function to do preorder traversal
   of binary tree  and print root to leaf path
   without using recursion */
void printRootToLeaf(Node* root)
{
    // Corner Case
    if (root == NULL)
        return;
 
    // Create an empty stack and push root to it
    stack<Node*> nodeStack;
    nodeStack.push(root);
 
    // Create a map to store parent pointers of binary
    // tree nodes
    map<Node*, Node*> parent;
 
    // parent of root is NULL
    parent[root] = NULL;
 
    /* Pop all items one by one. Do following for
       every popped item
        a) push its right child and set its parent
           pointer
        b) push its left child and set its parent
           pointer
       Note that right child is pushed first so that
       left is processed first */
    while (!nodeStack.empty())
    {
        // Pop the top item from stack
        Node* current = nodeStack.top();
        nodeStack.pop();
 
        // If leaf node encountered, print Top To
        // Bottom path
        if (!(current->left) && !(current->right))
            printTopToBottomPath(current, parent);
 
        // Push right & left children of the popped node
        // to stack. Also set their parent pointer in
        // the map
        if (current->right)
        {
            parent[current->right] = current;
            nodeStack.push(current->right);
        }
        if (current->left)
        {
            parent[current->left] = current;
            nodeStack.push(current->left);
        }
    }
}
 
// Driver program to test above functions
int main()
{
    /* Constructed binary tree is
         10
        /  \
       8    2
      / \   /
     3     5 2     */
    Node* root = newNode(10);
    root->left = newNode(8);
    root->right = newNode(2);
    root->left->left = newNode(3);
    root->left->right = newNode(5);
    root->right->left = newNode(2);
 
    printRootToLeaf(root);
 
    return 0;
}

Time complexity: nlogn
Space complexity: linear
// C++ program to print root to leaf path without using
// recursion
#include <bits/stdc++.h>
using namespace std;
 
// A binary tree node structure
struct Node {
    int data;
    Node *left, *right;
};
 
// fun to create a new node
Node* newNode(int data)
{
    Node* temp = new Node();
    temp->data = data;
    temp->left = temp->right = NULL;
    return temp;
}
 
// fun to check leaf node
bool isleafnode(Node* root)
{
    return !root->left && !root->right;
}
 
// fun to print root to leaf paths without using parent
// pointers
void printRootToLeaf(Node* root)
{
    // base case
    if (!root)
        return;
 
    string path = "";
 
    // create an empty stack to store a pair of tree nodes
    // and its path from root node.
    stack<pair<Node*, string> > s;
 
    // push the root node
    s.push({ root, path });
 
    // loop untill stack becomes empty
    while (!s.empty()) {
 
        auto it = s.top();
        s.pop();
 
        root = it.first;
        path = it.second;
 
        // convert the curr root value to string
        string curr = to_string(root->data) + " ";
 
        // add the current node to the existing path
        path += curr;
 
        // print the path if a node is encountered
        if (isleafnode(root))
            cout << path << endl;
 
        if (root->right)
            s.push({ root->right, path });
        if (root->left)
            s.push({ root->left, path });
    }
}
 
int main()
{
    // create a tree
    Node* root = newNode(10);
    root->left = newNode(8);
    root->right = newNode(2);
    root->left->left = newNode(3);
    root->left->right = newNode(5);
    root->right->left = newNode(2);
 
    printRootToLeaf(root);
 
    return 0;
}
// This code is contributed by Modem Upendra

Time complexity: linear
Space complexity: linear
// C++ program to print all root to leaf paths
// with there relative position
#include<bits/stdc++.h>
using namespace std;
 
#define MAX_PATH_SIZE 1000
 
// tree structure
struct Node
{
    char data;
    Node *left, *right;
};
 
// function create new node
Node * newNode(char data)
{
    struct Node *temp = new Node;
    temp->data = data;
    temp->left = temp->right = NULL;
    return temp;
}
 
// store path information
struct PATH
{
    int  Hd; // horizontal distance of node from root.
    char key; // store key
};
 
// Prints given root to leaf path with underscores
void printPath(vector < PATH > path, int size)
{
    // Find the minimum horizontal distance value
    // in current root to leaf path
    int minimum_Hd = INT_MAX;
 
    PATH p;
 
    // find minimum horizontal distance
    for (int it=0; it<size; it++)
    {
        p = path[it];
        minimum_Hd = min(minimum_Hd, p.Hd);
    }
 
    // print the root to leaf path with "_"
    // that indicate the related position
    for (int it=0; it < size; it++)
    {
        // current tree node
        p = path[it];
        int noOfUnderScores = abs(p.Hd - minimum_Hd);
 
        // print underscore
        for (int i = 0; i < noOfUnderScores; i++)
            cout << "_ ";
 
        // print current key
        cout << p.key << endl;
    }
    cout << "==============================" << endl;
}
 
// a utility function print all path from root to leaf
// working of this function is similar to function of
// "Print_vertical_order" : Print paths of binary tree
// in vertical order
// https://www.geeksforgeeks.org/print-binary-tree-vertical-order-set-2/
void printAllPathsUtil(Node *root,
                       vector < PATH > &AllPath,
                       int HD, int order )
{
    // base case
    if(root == NULL)
        return;
 
    // leaf node
    if (root->left == NULL && root->right == NULL)
    {
        // add leaf node and then print path
        AllPath[order] = (PATH { HD, root->data });
        printPath(AllPath, order+1);
        return;
    }
 
    // store current path information
    AllPath[order] = (PATH { HD, root->data });
 
    // call left sub_tree
    printAllPathsUtil(root->left, AllPath, HD-1, order+1);
 
    //call left sub_tree
    printAllPathsUtil(root->right, AllPath, HD+1, order+1);
}
 
void printAllPaths(Node *root)
{
    // base case
    if (root == NULL)
        return;
 
    vector<PATH> Allpaths(MAX_PATH_SIZE);
    printAllPathsUtil(root, Allpaths, 0, 0);
}
 
// Driver program to test above function
int main()
{
    Node *root = newNode('A');
    root->left = newNode('B');
    root->right = newNode('C');
    root->left->left = newNode('D');
    root->left->right = newNode('E');
    root->right->left = newNode('F');
    root->right->right = newNode('G');
    printAllPaths(root);
    return 0;
}

Time complexity: constant
Space complexity: logn
// Recursive C++ program to print odd level nodes
#include <bits/stdc++.h>
using namespace std;
 
struct Node {
    int data;
    Node* left, *right;
};
 
void printOddNodes(Node *root, bool isOdd = true)
{
    // If empty tree
    if (root == NULL)
      return;
 
    // If current node is of odd level
    if (isOdd)
       cout << root->data << " " ;
 
    // Recur for children with isOdd
    // switched.
    printOddNodes(root->left, !isOdd);
    printOddNodes(root->right, !isOdd);
}
 
// Utility method to create a node
struct Node* newNode(int data)
{
    struct Node* node = new Node;
    node->data = data;
    node->left = node->right = NULL;
    return (node);
}
 
// Driver code
int main()
{
    struct Node* root = newNode(1);
    root->left = newNode(2);
    root->right = newNode(3);
    root->left->left = newNode(4);
    root->left->right = newNode(5);
    printOddNodes(root);
 
    return 0;
}

Time complexity: linear
Space complexity: linear