Reputation: 2967
I'm learning data structures and trying to construct a binary tree by inserting nodes in a level order, but having little trouble in doing that. I want to insert nodes to a binary tree just by knowing the no of nodes that are there in the tree currently by traversing directly to the parent node without backtracking. This is what I've written so far
Tree.cpp
#include <iostream>
#include <cstdlib>
#include <cmath>
struct treeStruct {
int data;
struct treeStruct* parent;
struct treeStruct* left;
struct treeStruct* right;
treeStruct() {
data = 0;
parent = NULL;
left = NULL;
right = NULL;
}
};
void printInOrder(treeStruct* root) {
if(root != NULL) {
std::cout << root->data << "\t";
printInOrder(root->left);
printInOrder(root->right);
}
}
void printPreOrder(treeStruct* root) {
if(root != NULL) {
printPreOrder(root->left);
std::cout << root->data << "\t";
printPreOrder(root->right);
}
}
void printPostOrder(treeStruct* root) {
if(root != NULL) {
printPostOrder(root->left);
printPostOrder(root->right);
std::cout << root->data << "\t";
}
}
treeStruct* insertNode(treeStruct* parent, int data, int dir) {
treeStruct* node = new treeStruct();
if(parent == NULL) {
node->data = data;
}
else {
if(dir == 1) {
node->data = data;
node->parent = parent;
parent->left = node;
}
else if(dir == 2) {
node->data = data;
node->parent = parent;
parent->right = node;
}
}
return node;
}
treeStruct* constructInLevelTree(int* data, int len) { //having trouble in here
int level = -1;
int noOfNodes = 0;
treeStruct* root = NULL;
for(int i = 0; i < len; ++i) {
if(level == -1) {
root = insertNode(NULL, data[i], 0);
++level;
++noOfNodes;
}
else if(pow(2, level) >= noOfNodes) {
treeStruct* node = root;
treeStruct* parent = root->parent;
int scanCount = 0;
while(scanCount < noOfNodes) {
if((scanCount % 2) == 0) {
if(node != NULL) {
parent = node;
node = node->left;
}
}
else {
if(node != NULL) {
parent = node;
node = node->right;
}
}
++scanCount;
}
if((scanCount % 2) == 0)
insertNode(parent, data[i], 1);
else
insertNode(parent, data[i], 2);
++noOfNodes;
}
else {
++level;
}
}
return root;
}
int main(int argc, char* argv[]) {
int data[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
treeStruct* root = constructInLevelTree(data, sizeof(data) / sizeof(int));
printInOrder(root);
printPreOrder(root);
printPostOrder(root);
return EXIT_SUCCESS;
}
Upvotes: 1
Views: 533
Reputation: 2967
This is what I wrote after the suggestions given by @ Md Golam Rahman Tushar and @nkvns
Tree.cpp
#include <iostream>
#include <cstdlib>
#include <cmath>
#include <vector>
struct treeStruct {
int data;
struct treeStruct* parent;
struct treeStruct* left;
struct treeStruct* right;
treeStruct() {
data = 0;
parent = NULL;
left = NULL;
right = NULL;
}
};
void printInOrder(treeStruct* root) {
if(root != NULL) {
std::cout << root->data << "\t";
printInOrder(root->left);
printInOrder(root->right);
}
}
void printPreOrder(treeStruct* root) {
if(root != NULL) {
printPreOrder(root->left);
std::cout << root->data << "\t";
printPreOrder(root->right);
}
}
void printPostOrder(treeStruct* root) {
if(root != NULL) {
printPostOrder(root->left);
printPostOrder(root->right);
std::cout << root->data << "\t";
}
}
void insertNode(treeStruct** parent, int data, int dir) {
treeStruct* node = new treeStruct();
if(*parent != NULL) {
if(dir == 1) {
node->data = data;
node->parent = *parent;
(*parent)->left = node;
}
else if(dir == 0) {
node->data = data;
node->parent = *parent;
(*parent)->right = node;
}
}
else {
node->data = data;
*parent = node;
}
}
void getStackTrace(int nodeNo, std::vector<char>& stackTrace) {
stackTrace.clear();
int res;
do {
nodeNo = nodeNo / 2;
if((nodeNo == 1) || (nodeNo == 0))
stackTrace.push_back('T');
else if(nodeNo % 2 == 0)
stackTrace.push_back('L');
else
stackTrace.push_back('R');
} while(nodeNo > 1);
}
treeStruct* constructInLevelTree(int* data, int len) {
int noOfNodes = 0;
treeStruct* root = NULL;
std::vector<char> stackTrace;
for(int i = 0; i < len; ++i) {
if(i == 0) {
insertNode(&root, data[i], -1);
std::cout << "\ninserted root node" << std::endl;
}
else {
getStackTrace(noOfNodes + 1, stackTrace);
treeStruct* parentNode;
std::vector<char>::reverse_iterator stackItr = stackTrace.rbegin();
std::cout << "\nfor data " << data[i] << " taverse is:" << std::endl;
while(stackItr != stackTrace.rend()) {
std::cout << (*stackItr) << "\t";
if((*stackItr) == 'T')
parentNode = root;
else if((*stackItr) == 'L')
parentNode = parentNode->left;
else
parentNode = parentNode->right;
++stackItr;
}
insertNode(&parentNode, data[i], (i % 2));
}
++noOfNodes;
}
return root;
}
int main(int argc, char* argv[]) {
int data[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
for(int i = 0; i < sizeof(data) / sizeof(int); ++i)
std::cout << data[i] << "\t";
std::cout << "\n" << std::endl;
treeStruct* root = constructInLevelTree(data, sizeof(data) / sizeof(int));
std::cout << "\nIn Order traversal" << std::endl;
printInOrder(root);
std::cout << "\nPre Order traversal" << std::endl;
printPreOrder(root);
std::cout << "\nPost Order traversal" << std::endl;
printPostOrder(root);
std::cout <<"\n" << std::endl;
return EXIT_SUCCESS;
}
Upvotes: 0
Reputation: 600
If you want to create tree in level order, at any step of creation your tree is going to be complete binary tree (Please note difference between complete and full binary tree). You can use this invariant effectively. There are two possible approaches here
Upvotes: 1