binary search tree using rand - random

i am trying to create a binary search tree with 50 random variables, i wrote a code but the random variables are not being declared..please help me out
#include <iostream>
#include <cstdlib>
using namespace std;
//creating a class node which contains value,rvalue which stores the value pointed by rlink and lvalue which stores the value pointed by llink
class node
{
private:
int value;
int rvalue;
int lvalue;
node *rlink;
node *llink;
public:
void insertnode(node*,int);
node *create(node*,int);
};
void node::insertnode(node *h,int k)
{
h=new node;
h->value=k;
h->rlink=NULL;
h->llink=NULL;
h->rvalue=0;
h->lvalue=0;
}
node *node::create(node*root, int i)
{
int A[i];
for(int j=0; j<i; j++) {
A[j]=rand()%1000; //stores random values in array
cout<<A[j];
}
node *k;
node *h;
insertnode(root, A[0]);
cout<<h->value;
for (int j=1; j<i; j++) {
if(A[j]<h->value){
if(h->llink==NULL) {
insertnode(k, A[j]);
h->lvalue=k->value;
}
h->llink=k;
}
else if(A[j]>h->value)
{
if(h->rlink==NULL) {
insertnode(k, A[j]);
h->rvalue=k->value;
}
h->rlink=k;
}
}
return root;
}
int main()
{
int i;
cout<<"enter the number of elements in a matix";
cin>>i;
node s;
node *h;
h=s.create(h,i);
}

in the function create(), you are using variables k and h which are pointers to node. But you have not initialized this variables and also you have not allocated space for those pointers. First allocate memory to this variables.

There are quite a few problems with your code.
To create a node should just create a new node for a given value (this should be done with a constructor. The other values in the node class will be initialized when the node is inserted in to the tree)
To insert a node you should always be passing the root of the tree (or a reference to the tree itself) and the node to insert and then finding where to insert the node in the insert method (This can also be where you do aeny balancing if necessary)
If you use the tree approach (which I would recommend) the tree should have a reference to it's root and possibly a count of the nodes in it
To generate random nodes there is no use in using an array you should just get a new random value, create a node for it, and insert that into the list
To do the last part of this do something like (assuming C++)
int main() {
Tree *tree = new Tree(); //This creates a tree (you will need to create a tree class with a constructor
int total = 50; //This the number of nodes you want store this however is necessary
....
srand(time(NULL));
for(int i = 0; i < total; i++) {
int val = rand() % 1000 + 1; //This gets a number between 1-1000
Node *node = new Node(val); //This constructs the node (write this constructor)
tree.insertNode(node); //This will insert the node into the tree (write this method)
}
....
}
This would create a tree with 50 values assuming the constructor for Node and Tree and the insertNode method words

Related

Why the time complexity of the below program which converts BT to BST is nlogn (which is the time complexity of sort)?

I am confused, the function binaryTreeToBST that has the below-mentioned operations and function call. Why are we not adding time complexities of each called function instead of taking only the time complexity of sort (step 3 below)?
countNodes
Creating temp array arr[] that stores inorder traversal of the tree. (takes O(n) )
sort the temp array arr[]. This step takes O(nlogn) time.
Again do inorder traversal to convert BT to BST(takes O(n) )
/* A program to convert Binary Tree to Binary Search Tree */
#include <stdio.h>
#include <stdlib.h>
/* A binary tree node structure */
struct node {
int data;
struct node* left;
struct node* right;
};
/* A helper function that stores inorder traversal of a tree rooted
with node */
void storeInorder(struct node* node, int inorder[], int* index_ptr)
{
// Base Case
if (node == NULL)
return;
/* first store the left subtree */
storeInorder(node->left, inorder, index_ptr);
/* Copy the root's data */
inorder[*index_ptr] = node->data;
(*index_ptr)++; // increase index for next entry
/* finally store the right subtree */
storeInorder(node->right, inorder, index_ptr);
}
/* A helper function to count nodes in a Binary Tree */
int countNodes(struct node* root)
{
if (root == NULL)
return 0;
return countNodes(root->left) + countNodes(root->right) + 1;
}
// Following function is needed for library function qsort()
int compare(const void* a, const void* b)
{
return (*(int*)a - *(int*)b);
}
/* A helper function that copies contents of arr[] to Binary Tree.
This function basically does Inorder traversal of Binary Tree and
one by one copy arr[] elements to Binary Tree nodes */
void arrayToBST(int* arr, struct node* root, int* index_ptr)
{
// Base Case
if (root == NULL)
return;
/* first update the left subtree */
arrayToBST(arr, root->left, index_ptr);
/* Now update root's data and increment index */
root->data = arr[*index_ptr];
(*index_ptr)++;
/* finally update the right subtree */
arrayToBST(arr, root->right, index_ptr);
}
// This function converts a given Binary Tree to BST
void binaryTreeToBST(struct node* root)
{
// base case: tree is empty
if (root == NULL)
return;
/* Count the number of nodes in Binary Tree so that
we know the size of temporary array to be created */
int n = countNodes(root);
// Create a temp array arr[] and store inorder traversal of tree in arr[]
int* arr = new int[n];
int i = 0;
storeInorder(root, arr, &i);
// Sort the array using library function for quick sort
qsort(arr, n, sizeof(arr[0]), compare);
// Copy array elements back to Binary Tree
i = 0;
arrayToBST(arr, root, &i);
// delete dynamically allocated memory to avoid memory leak
delete[] arr;
}
/* Utility function to create a new Binary Tree node */
struct node* newNode(int data)
{
struct node* temp = new struct node;
temp->data = data;
temp->left = NULL;
temp->right = NULL;
return temp;
}
/* Utility function to print inorder traversal of Binary Tree */
void printInorder(struct node* node)
{
if (node == NULL)
return;
/* first recur on left child */
printInorder(node->left);
/* then print the data of node */
printf("%d ", node->data);
/* now recur on right child */
printInorder(node->right);
}
/* Driver function to test above functions */
int main()
{
struct node* root = NULL;
/* Constructing tree given in the above figure
10
/ \
30 15
/ \
20 5 */
root = newNode(10);
root->left = newNode(30);
root->right = newNode(15);
root->left->left = newNode(20);
root->right->right = newNode(5);
// convert Binary Tree to BST
binaryTreeToBST(root);
printf("Following is Inorder Traversal of the converted BST: \n");
printInorder(root);
return 0;
}

Tree and graphs problems in Julia using struct data types, pointers and this

I want to write solve some graph/trees problems using Julia language.
Here is some good example. In C it was done this way:
Recursive C program for level order traversal of Binary Tree
#include <stdio.h>
#include <stdlib.h>
/* A binary tree node has data, pointer to left child
and a pointer to right child */
struct node
{
int data;
struct node *left, *right;
};
/* Function prototypes */
void printGivenLevel(struct node* root, int level);
int height(struct node* node);
struct node* newNode(int data);
/* Function to print level order traversal a tree*/
void printLevelOrder(struct node* root)
{
int h = height(root);
int i;
for (i=1; i<=h; i++)
printGivenLevel(root, i);
}
/* Print nodes at a given level */
void printGivenLevel(struct node* root, int level)
{
if (root == NULL)
return;
if (level == 1)
printf("%d ", root->data);
else if (level > 1)
{
printGivenLevel(root->left, level-1);
printGivenLevel(root->right, level-1);
}
}
/* Compute the "height" of a tree -- the number of
nodes along the longest path from the root node
down to the farthest leaf node.*/
int height(struct node* node)
{
if (node==NULL)
return 0;
else
{
/* compute the height of each subtree */
int lheight = height(node->left);
int rheight = height(node->right);
/* use the larger one */
if (lheight > rheight)
return(lheight+1);
else return(rheight+1);
}
}
/* 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 program to test above functions*/
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);
printf("Level Order traversal of binary tree is \n");
printLevelOrder(root);
return 0;
}
I have tried to do it in Julia in similar way, but there are some problems, especially with accessing to struct elements.(like node->right and node->left).
Or some way to create Self-referential struct and function to allocate nodes.
struct node
data::Int
left::Ptr{node}
right::Ptr{node}
end
# Compute the "height" of a tree -- the number of
# nodes along the longest path from the root node
# down to the farthest leaf node.
function height = (node::Ptr{node})
if node === nothing
return 0
else
# compute the height of each subtree
lheight = height(node->left)
rheight = height(node->right)
# use the larger one
if lheight > rheight
return lheight+1
else return rheight+1
end
end
end
From what I've seen trying to recreate a problem solution in C way isn't the way, however this struct type should be useful. I just have to know how to create self-referent struct, how to allocate elements in this node and how to get them.
First of all, I would strongly suggest reading through https://docs.julialang.org/en/v1/, since Julia is different from C in quite a few ways. There are multiple things to point out here:
Per default structs in Julia are immutable, which means you cannot modify fields after it is created. It is also always passed by copy instead of by reference, since it doesn't have a specific memory address and usually gets allocated on the stack. This actually has multiple benefits for the compiler and is part of the reason why Julia can be so fast. In your example you probably want a mutable struct, which is more similar a struct in C.
In Julia, you should never have to use pointers (Ptr) directly, unless you are calling C code. Since Julia uses a garbage collector, raw pointers have a lot of gotchas when it comes to memory management and should generally just be avoided. You usually just work with objects directly or, if you want to pass immutable objects by reference, you can wrap them in Ref.
In Julia, fields are always accessed either just with a dot x.field (equivalent to getproperty(x, :field)), or in some cases getfield(x, :field). (The latter can't be overloaded by the user, which is sometimes useful). -> actually creates an anonymous function.
For your example the following should work instead:
mutable struct Node
data::Int
left::Node
right::Node
Node(data::Int) = new(data)
end
function height(node::Node, field::Symbol)
isdefined(node, field) || return 0
return height(getproperty(node, field))
end
function height(node::Node)
lheight = height(node, :left)
rheight = height(node, :right)
# use the larger one
if lheight > rheight
return lheight+1
else
return rheight+1
end
end
What the first part is doing is creating a mutable struct Node, with self-referential fields like your C example. The line Node(data::Int) = new(data) is actually an inner constructor taking just the data and if you call new directly in a mutable struct, you can leave trailing fields undefined. You can define these fields afterwards with x.field = y. If these fields are themselves mutable, you can also check if they are undefined with isdefined(x, :field). Here, I am adding another method to height, which also takes a field name, which returns the height of the field if it's defined and 0 otherwise.
You would then construct nodes and calculate their height like this:
julia> n = Node(1)
Node(1, #undef, #undef)
julia> n.left=Node(2)
Node(2, #undef, #undef)
julia> n
Node(1, Node(2, #undef, #undef), #undef)
julia> height(n)
2
Hope that helps! If you want to learn more, the documentation I linked above is usually quite good.

Find all the nodes which can be reached from a given node within certain distance

Multiple nodes can also be traversed in sequence to create a path.
struct Node {
float pos [2];
bool visited = false;
};
// Search Space
Node nodes [MAX_NODE_COUNT];
// Function to return all reachable nodes
// nodeCount : Number of nodes
// nodes : Array of nodes
// indexCount : Size of the returned array
// Return : Returns array of all reachable node indices
int* GetReachableNodes (int nodeCount, Node* nodes, int* indexCount)
{
// This is the naive approach
queue <int> indices;
vector <int> indexList;
indices.push (nodes [0]);
nodes [0].visited = true;
// Loop while queue is not empty
while (!indices.empty ())
{
// Pop the front of the queue
int parent = indices.front ();
indices.pop ();
// Loop through all children
for (int i = 0; i < nodeCount; ++i)
{
if (!nodes [i].visited && i != parent && DistanceSqr (nodes [i], nodes [parent]) < maxDistanceSqr)
{
indices.push (i);
nodes [i].visited = true;
indexList.push_back (i);
}
}
}
int* returnData = new int [indexList.size ()];
std::move (indexList.begin (), indexList.end (), returnData);
*indexCount = indexList.size ();
// Caller responsible for delete
return returnData;
}
The problem is I can't use a graph since all nodes are connected to each other.
All the data is just an array of nodes with their positions and the start node.
I can solve this problem easily with BFS but it's n^2.
I have been figuring out how to solve this in less than O(n^2) time complexity.
Some of the approaches I tried were parallel BFS, Dijkstra but it doesn't help a lot.
Any help will be really appreciated.

Function to insert an integer into a circular linked _list in ascending order

I am writing a function to insert an integer into a circular linked _list in ascending order whose elements are sorted in ascending order (smallest to largest).
The input to the function insertSortedList is a pointer start to some node in the circular list and an integer n between 0 and 100. Return a pointer to the newly inserted node.
The structure to follow for a node of the circular linked list is-
Struct CNode;
Typedef struct CNode cnode;
Struct CNode
{
Int value;
Cnode* next;
};
Cnode* insertSortedList (cnode* start,int n)
{
//WRITE YOUR CODE HERE
}
//FUNCTION SIGNATURE ENDS
Test Case 1:
Input:
[3->4->6->1->2->^],5
Expected Return Value:
[5->6->1->2->3->4->^]
Test Case 2:
Input:
[1->2->3->4->5->^],0
Expected Return Value:
[0->1->2->3->4->5->^]
Here's my code:
Cnode* insertSortedList (cnode* start,int n)
{
int count=1,i,count1=0;
Cnode* temp=start;
Cnode* temp1=start;
Cnode* temp2=start;
Cnode* newHead=NULL;
while(temp!=NULL)
{
temp=temp->next;
count ++;
}
int arr[count];
while(temp2!=NULL)
{
for(j=0;j<count;j++)
{
arr[j]=temp->data;
temp2=temp2->next;
}
}
while(n>=temp2->value)
{
temp2=temp2->next;
}
newHead=temp2;
for(i=0;i<count;i++)
{
Cnode* newNode=new Cnode();
newNode->data=arr[i];
newNode->next=NULL;
}
}
You said it's a circular linked-list but you are checking for temp != null. It should be temp→next != start.
Its not so complicated at all. Given a pointer to any element in a circular linked list, whose elements are already in ascending order, we just need to find the location of the new element, which can be done in a few lines. Simple Java code -
CNode prev = start;
CNode next = start.next;
while(true){
if(prev.value <= n && n <= next.value) break;
prev=next; next=next.next;
}
CNode node = new CNode();
node.value = n;
prev.next=node; node.next=next;
return node;

How to construct a binary tree using a level order traversal sequence

How to construct a binary tree using a level order traversal sequence, for example from sequence {1,2,3,#,#,4,#,#,5}, we can construct a binary tree like this:
1
/ \
2 3
/
4
\
5
where '#' signifies a path terminator where no node exists below.
Finally I implement Pham Trung's algorithm by c++
struct TreeNode
{
TreeNode *left;
TreeNode *right;
int val;
TreeNode(int x): left(NULL), right(NULL), val(x) {}
};
TreeNode *build_tree(char nodes[], int n)
{
TreeNode *root = new TreeNode(nodes[0] - '0');
queue<TreeNode*> q;
bool is_left = true;
TreeNode *cur = NULL;
q.push(root);
for (int i = 1; i < n; i++) {
TreeNode *node = NULL;
if (nodes[i] != '#') {
node = new TreeNode(nodes[i] - '0');
q.push(node);
}
if (is_left) {
cur = q.front();
q.pop();
cur->left = node;
is_left = false;
} else {
cur->right = node;
is_left = true;
}
}
return root;
}
Assume using array int[]data with 0-based index, we have a simple function to get children:
Left child
int getLeftChild(int index){
if(index*2 + 1 >= data.length)
return -1;// -1 Means out of bound
return data[(index*2) + 1];
}
Right child
int getRightChild(int index){
if(index*2 + 2 >= data.length)
return -1;// -1 Means out of bound
return data[(index*2) + 2];
}
Edit:
Ok, so by maintaining a queue, we can build this binary tree.
We use a queue to maintain those nodes that are not yet processed.
Using a variable count to keep track of the number of children added for the current node.
First, create a root node, assign it as the current node.
So starting from index 1 (index 0 is the root), as the count is 0, we add this node as left child of the current node.
Increase count. If this node is not '#', add it to the queue.
Moving to the next index, the count is 1, so we add this as right child of current node, reset count to 0 and update current node (by assigning the current node as the first element in the queue). If this node is not '#', add it to the queue.
int count = 0;
Queue q = new Queue();
q.add(new Node(data[0]);
Node cur = null;
for(int i = 1; i < data.length; i++){
Node node = new Node(data[i]);
if(count == 0){
cur = q.dequeue();
}
if(count==0){
count++;
cur.leftChild = node;
}else {
count = 0;
cur.rightChild = node;
}
if(data[i] != '#'){
q.enqueue(node);
}
}
class Node{
int data;
Node leftChild, rightChild;
}
Note: this should only work for a binary tree and not BST.
we can build this binary tree from level order traversal by maintaining a queue. Queue is used to maintain those nodes that are not yet processed.
Using a variable count(index variable) to keep track of the number of children added for the current node.
First, create a root node, assign it as the current node. So starting from index 1,
index value is 1 means, we will add the next value as left node.
index value is 2 means we will add the next value as right node and index value 2 means that we have added left and right node, then do the same for the remaining nodes.
if arr value is -1
3.a. if index value is 1,i.e., there is no left node then change the index variable to add right node.
3.b. if index value is 2, i.e, there is no right node then we have repeat this step for the remaining.
static class Node{
int data;
Node left;
Node right;
Node(int d){
data=d;
left=null;
right=null;
}
}
public static Node constBT(int arr[],int n){
Node root=null;
Node curr=null;
int index=0;
Queue<Node> q=new LinkedList<>();
for(int i=0;i<n;i++){
if(root==null){
root=new Node(arr[i]);
q.add(root);
curr=q.peek();
index=1;
}else{
if(arr[i]==-1){
if(index==1)
index=2;
else{
q.remove();
curr=q.peek();
index=1;
}
}
else if(index==1){
curr.left=new Node(arr[i]);
q.add(curr.left);
index=2;
}else if(index==2){
curr.right=new Node(arr[i]);
q.add(curr.right);
q.remove();
curr=q.peek();
index=1;
}
}
}
return root;
}
My approach is similar to Pham Trung yet intutive. We would maintain an array of Nodes of given data instead of using a queue. We would do reverse engineering on BFS using queue. because BFS for a tree is basically its Level Order Traversal (LOT).
It is important to note that we should have the NULL childs of an node for the LOT to be unique and the reconstruction of Tree from LOT to be possible.
In this case LOT : 1,2,3,-1,-1,4,-1,-1,5
where I have used -1 instead of '#' to represent NULLs
And Tree is
1
/ \
2 3
/ \ /
-1 -1 4
/ \
-1 5
Here, we can easily see that when 1 is popped from the BFS queue, it pushed its left child
(2) and right child (3) in the queue. Similary, for 2 it pushed -1 (NULL) for both of its children. And the process is continued.
So, we can follow the following pseudo code to generate the tree rooted at LOT[0]
j = 1
For every node in LOT:
if n<=j: break
if node != NULL:
make LOT[j] left child of node
if n<=j+1: break
make LOT[j+1] right child of node
j <- j+2
Finally, C++ code for the same
Class Declaration and Preorder traversal
class Node{
public:
int val;
Node* lft, *rgt;
Node(int x ):val(x) {lft=rgt=nullptr;}
};
void preorder(Node* root) {
if(!root) return;
cout<<root->val<<" ";
preorder(root->lft);
preorder(root->rgt);
}
Restoring Tree from LOT Logic
int main(){
int arr[] = {1,2,3,-1,-1,4,-1,-1,5};
int n = sizeof(arr)/sizeof(int);
Node* brr[n];
for(int i=0;i<n;i++) {
if(arr[i]==-1) brr[i] = nullptr;
else brr[i] = new Node(arr[i]);
}
for(int i=0,j=1;j<n;i++) {
if(!brr[i]) continue;
brr[i]->lft = brr[j++];
if(j<n) brr[i]->rgt = brr[j++];
}
preorder(brr[0]);
}
Output: 1 2 3 4 5

Resources