Pre-order tree traversal and the order of stack pushing - c++

Does the order of stack pushing matter in pre-order traversal of trees?
For example, Iterative Preorder Traversal
In the following source code,
void iterativePreorder(node* root)
{
if (root == NULL)
return;
stack<node*> nodeStack;
nodeStack.push(root);
while (nodeStack.empty() == false)
{
struct node* node = nodeStack.top();
printf("%d ", node->data);
nodeStack.pop();
if (node->right)//<--------------------------------
nodeStack.push(node->right);
if (node->left)//<---------------------------------
nodeStack.push(node->left);
}
}
if I switch the position of stack-pushing of left and right nodes,
void iterativePreorder(node* root)
{
if (root == NULL)
return;
stack<node*> nodeStack;
nodeStack.push(root);
while (nodeStack.empty() == false)
{
struct node* node = nodeStack.top();
printf("%d ", node->data);
nodeStack.pop();
if (node->left)//<---------------------------------
nodeStack.push(node->left);
if (node->right)//<--------------------------------
nodeStack.push(node->right);
}
}
does it make any difference?
I mean, if the positions are switched, is that still a proper pre-order traversal?

Related

is this binary tree function postorder or preorder?

My understanding is that in binary tree, the preorder traversal visits the root node first, then traverses the left subtree, and finally traverses the right subtree. The postorder traversal visits the left subtree, then the right subtree, and finally the root node.
In the final of my class this asks if this the function f() is preorder or postorder.
template
int f(treeNode* t)
{
int n=0, leftValue, rightValue;
if (t != NULL) {
if (t->leftChild != NULL || t->rightChild != NULL)
n++;
leftValue = f(t->leftChild);
rightValue = f(t->rightChild);
return n + leftValue + rightValue;
} else
return 0;
}
Doesn't this travel the down the left tree, the the right tree before processing anything? So it should be postorder shouldn't it?
Similar to how this function to delete the nodes in a binary tree:
clear(Node* curr) {
if (!curr)
return;
clear(curr->left);
clear(curr->right);
delete curr;
}

C++ Segmentation fault -- Self-balancing Tree insertion

I'm trying to solve a self-balancing tree problem on Hackerrank (https://www.hackerrank.com/challenges/self-balancing-tree/problem) and I keep getting a Segmentation fault in the last 3 test cases. I saw that this same problem had been posted before and tried to apply the same approach (check for nullptr) to my case, but no success so far. The following code is written in C++ and I would appreciate a lot if you guys could help me out. Thanks!
/* Node is defined as :
typedef struct node
{
int val;
struct node* left;
struct node* right;
int ht;
} node; */
node * newNode(int val)
{
node * newNode = new node;
newNode->val = val;
newNode->left = nullptr;
newNode->right = nullptr;
newNode->ht = 0;
return newNode;
}
int getHeight(node* root)
{
if(root == nullptr) {
return -1;
} else {
return root->ht;
}
}
node* rightRotate(node* root)
{
node* temp = root->left;
root->left = temp->right;
temp->right = root;
root->ht = 1 + max(getHeight(root->left), getHeight(root->right));
temp->ht = 1 + max(getHeight(temp->left), getHeight(temp->right));
return temp;
}
node* leftRotate(node* root)
{
node* temp = root->right;
root->right = temp->left;
temp->left = root;
root->ht = 1 + max(getHeight(root->left), getHeight(root->right));
temp->ht = 1 + max(getHeight(temp->left), getHeight(temp->right));
return temp;
}
node * insert(node * root,int val)
{
if(root == nullptr) {
root = newNode(val);
return root;
}
if(val > root->val) {
root->right = insert(root->right, val);
}
else if(val < root->val) {
root->left = insert(root->left, val);
}
else{ return 0; }
root->ht = 1 + max(getHeight(root->left),getHeight(root->right));
int balance = getHeight(root->left) - getHeight(root->right);
if(root->left != nullptr && balance > 1) {//Left subtree disbalanced
if(val < root->left->val) {
//Left-Left case: perform a right rotation on the disb. node
return rightRotate(root);
}
else {
//Left-Right case: perfom a left rotation on the disb. node left subtree
//and a right rotation on the disb. node
root->left = leftRotate(root->left);
return rightRotate(root);
}
}
if(root->right != nullptr && balance < -1) {//Right subtree disbalanced
if(val > root->right->val) {
//Right-Right case: perform a left rotation on the disb. node
return leftRotate(root);
}
else {
//Right-Left case: perfom a right rotation on the disb. node right subtree
//and a left rotation on the disb. node
root->right = rightRotate(root->left);
return leftRotate(root);
}
}
return root;
}
Edit:
For debugging purposes I've used an online gdb and added to the code above the following traversal method and main function:
void inOrder(node* root) {
if(root == NULL) {
return;
} else {
inOrder(root->left);
cout << root->val << " ";
inOrder(root->right);
}
}
int main()
{
node* root=NULL;
root=insert(root,2);
root=insert(root,4);
root=insert(root,3);
inOrder(root);
return 0;
}
After trying to insert the values 2, 4 and 3, in this order, we would have a disbalanced tree since the right subtree would have a height of 1 while the left subtree would have a height of -1 (leaf node is nullptr) and the balance factor would be less than -1. Further analysis shows that we have a RIGHT-LEFT case since the node causing the disbalance is the left child of the right child of the disbalanced node (root 2). We would then have to perform a right rotation on the disbalanced node right child followed by a left rotation on the disbalanced node itself, and the tree should end up looking like the following:
3
/ \
2 4
Thanks to everyone who tried helping me out on this one, it turns out there is no limit to how dumb I can be. I believe I've figured out what I had done wrong.
The problem in this question lies on the section that checks if the right subtree is disbalanced and, if so, performs the necessary rotations. On the code piece below, it should be
root->right = rightRotate(root->right);
instead of
root->right = rightRotate(root->left);

How do I access a pointer from within a nested class?

This class's purpose is to emulate the functions of a Binary Search Tree. In the below code, I am trying to adapt it from a struct and a bunch of functions, into a wrapper class, called BST. One thing I am not sure of however, is how to access 'root' from within the node struct. Root is currently declared within the BST class.
class bst
{
public:
struct Node
{
public:
int data;
struct Node *left;
struct Node *right;
Node* FindMin(Node* root)
{
while(root->left != NULL) root = root->left;
return root;
}
Node* Insert(Node *root,int data)
{
if(root == NULL) {
root = new Node();
root->data = data;
root->left = root->right = NULL;
//Update Height & Size
bstHeight = 0;
bstSize = 0;
}
else if(data <= root->data)
root->left = Insert(root->left,data);
else
root->right = Insert(root->right,data);
return root;
}
Node* Delete(struct Node *root, int data)
{
if(root == NULL) return root;
else if(data < root->data) root->left = Delete(root->left,data);
else if (data > root->data) root->right = Delete(root->right,data);
//Value found
else {
// Case 1: No child
if(root->left == NULL && root->right == NULL)
{
delete root;
root = NULL;
//Update Height & Size
bstHeight = 0;
bstSize = 0;
}
//Case 2: One child
else if(root->left == NULL)
{
struct Node *temp = root;
root = root->right;
delete temp;
//Update Height & Size
bstHeight = 0;
bstSize = 0;
}
else if(root->right == NULL)
{
struct Node *temp = root;
root = root->left;
delete temp;
//Update Height & Size
bstHeight = 0;
bstSize = 0;
}
// case 3: 2 children
else
{
struct Node *temp = FindMin(root->right);
root->data = temp->data;
root->right = Delete(root->right,temp->data);
//Update Height & Size
bstHeight = 0;
bstSize = 0;
}
}
return root;
}
//# of Nodes in tree
void size(Node *root)
{
//Check if end
if(root == NULL) return;
//Not end
else
{
bstSize = bstSize + 1;
size(root->left); //Visit left subtree
size(root->right); // Visit right subtree
}
}
void height(Node *root, int temp)
{
//Check if end
if(root == NULL)
{
if(temp > bstHeight)
{
bstHeight = temp;
}
return;
}
//Not end
else
{
temp = temp + 1;
height(root->left, temp); //Visit left subtree
height(root->right, temp); // Visit right subtree
}
}
//Function to visit nodes in Inorder
void show()
{
if(root == NULL) return;
show(root->left); //Visit left subtree
printf("%d ",root->data); //Print data
show(root->right); // Visit right subtree
}
void check(Node *root)
{
//End of a 'branch'
if(root == NULL) return;
int value = 0;
value = root->data;
//Checking left subtree
if(value < root->left->data)
{
//Tree is NOT valid
valid = 0;
}
//Checking right subtree
if(value > root->right->data)
{
//Tree is NOT valid
valid = 0;
}
check(root->left); //Visit left subtree
printf("%d ",root->data); //Print data
//check(root->right); // Visit right subtree
}
};
Node* root = NULL;
};
Specifically, in the show function. It's not as simple as putting it into Node with the rest of the functions, as root needs to be unique, and new Node is called at least once. Show will not compile in the current state, and I'm not sure where to proceed from here.
Though the comment says everything, let me give an additional hint:
When you want to keep your code as similar as possible to what you have now, try to add a constructor to the Node class that expects a pointer or reference (preferable) to the root and check, that each time you create a Node, you give the root to the constructor.
By the way, it might even be a better approach to look at some simple Node-based data structure implementations in C++, for example in the thread
Simple linked list in C++

Build a binary tree from a given preorder traversal

I have a preorder traversal of a binary tree that is stored in an array and I would like to recreate the binary tree based on this traversal. My array looks like this: {NNNLLNLLNLNLNNLLNLL}, where N represents a node and L represents a leaf. I would like to do this recursively but I am having trouble coming up with an algorithm. Any suggestions would be very appreciated.
This should work assuming every node has 2 or 0 descendants (a tree that satisfies this property is called full or strict binary tree)
void create_from_traversal(Node* root, int& index) {
if (traversal[index] == 'L') {
root->left = root->right = NULL;
return;
}
root->left = new Node();
create_from_traversal(root->left, ++index);
root->right = new Node();
create_from_traversal(root->right, ++index);
}
Complete example with check:
#include <string>
#include <iostream>
class Node {
public:
Node* left;
Node* right;
};
std::string traversal = "NNNLLNLLNLNLNNLLNLL";
void create_from_traversal(Node* root, int& index) {
if (traversal[index] == 'L') {
root->left = root->right = NULL;
return;
}
root->left = new Node();
create_from_traversal(root->left, ++index);
root->right = new Node();
create_from_traversal(root->right, ++index);
}
void print_traversal(Node* root) {
if (root->left == NULL) {
std::cout << "L";
return;
}
std::cout << "N";
print_traversal(root->left);
print_traversal(root->right);
}
int main() {
Node* root = new Node();
int index = 0;
create_from_traversal(root, index);
// Does it work?
print_traversal(root); // Output should be equal to given traversal
std::cout << std::endl;
}
Output:
NNNLLNLLNLNLNNLLNLL
You need one more traversal before you can reconstruct the tree. Given any two traversals among the three (Pre, Post, In) you can reconstruct. But given only one it is not possible to uniquely reconstruct the tree.

iteratively insert into a binary search tree.Debug C++ code

Here is a c++ function to create a BST tree from an array of integers?
It's simple.
Take first element ,make root.
Take next array element and insert it into the tree.
Why is the loop starting from i=2 and not i=1??
node* buildtree(int a[], int len)
{
node* root=new node(a[0]);
node* temp=root;
for(int i=1;i<len;i++)
{
while(!(root->left==NULL && root->right==NULL))
{
cout<<"here"<<i<<" "<<a[i]<<" " << root->val<<"\n";
if(root->val>a[i])
root=root->left;
else
root=root->right;
}
node* currnode=new node(a[i]);
if(root->val>a[i])
root->left=currnode;
else
root->right=currnode;
if(root==NULL)
cout<<"error...never.here";
root=temp;
}
return root;
}
Thanks a lot for explaining it.I tried it another way but it only finds the root.What's the problem in it?
node* buildtree(int a[],int len)
{ node* root=new node(a[0]);
node* curr;
for(int i=1;i<len;i++)
{ curr=root;
while(curr!=NULL)
{
if(curr->val>a[i])
curr=curr->left;
else
curr=curr->right;
}
curr=new node(a[i]);
}
return root;
}
Because in the first iteration of the loop the while condition is not true because the root node has no child nodes.
while(!(root->left==NULL && root->right==NULL)
for i=1 the left and the right node are NULL and the left node is populated at the end of the first iteration.
When trying to find the point of insertion,
while(!(root->left==NULL && root->right==NULL))
{
cout<<"here"<<i<<" "<<a[i]<<" " << root->val<<"\n";
if(root->val>a[i])
root=root->left;
else
root=root->right;
}
you only stop if both children are NULL, so at some point or other, you will set root to NULL. Consider the array begins with [5, 3, 6, ... ]. You start with
NULL <- node(5) -> NULL
node(3) <- node(5) ->NULL
and then try to insert the 3. Since not both children are NULL, the while loop runs
if (5 > 7) // false
root = root->left;
else
root = root->right; // now root == NULL, oops
and the controlling condition is checked anew
while(!(NULL->left == NULL && NULL->right == NULL))
segfault likely here, undefined behaviour invoked.
You should do something like
while(true) {
if (root->val > a[i]) {
if (root->left == NULL) {
root->left = new node(a[i]);
break;
} else {
root = root->left;
}
} else {
if (root->right == NULL) {
root->right = new node(a[i]);
break;
} else {
root = root->right;
}
}
}