Segment tree implementation - c++

I was learning segment tree from this page : http://letuskode.blogspot.com/2013/01/segtrees.html
I am finding trouble to understand various fragments of code.I will ask them one by one.Any help will be appreciated.
Node declaration:
struct node{
int val;
void split(node& l, node& r){}
void merge(node& a, node& b)
{
val = min( a.val, b.val );
}
}tree[1<<(n+1)];
1.What will the split function do here ?
2.This code is used for RMQ . So I think that val will be the minimum of two segments and store it in some other segment.Where the value will be saved?
Range Query Function:
node range_query(int root, int left_most_leaf, int right_most_leaf, int u, int v)
{
//query the interval [u,v), ie, {x:u<=x<v}
//the interval [left_most_leaf,right_most_leaf) is
//the set of all leaves descending from "root"
if(u<=left_most_leaf && right_most_leaf<=v)
return tree[root];
int mid = (left_most_leaf+right_most_leaf)/2,
left_child = root*2,
right_child = left_child+1;
tree[root].split(tree[left_child], tree[right_child]);
//node l=identity, r=identity;
//identity is an element such that merge(x,identity) = merge(identity,x) = x for all x
if(u < mid) l = range_query(left_child, left_most_leaf, mid, u, v);
if(v > mid) r = range_query(right_child, mid, right_most_leaf, u, v);
tree[root].merge(tree[left_child],tree[right_child]);
node n;
n.merge(l,r);
return n;
}
1.What is the use of the array tree and what values will be kept there ?
2.What will this statement : tree[root].split(tree[left_child], tree[right_child]); do ?
3.What will those statements do ? :
node n;
n.merge(l,r);
return n;
Update and Merge Up functions:
I am not understanding those two functions properly:
void mergeup(int postn)
{
postn >>=1;
while(postn>0)
{
tree[postn].merge(tree[postn*2],tree[postn*2+1]);
postn >>=1;
}
}
void update(int pos, node new_val)
{
pos+=(1<<n);
tree[pos]=new_val;
mergeup(pos);
}
Also what should I write inside the main function to make this thing work?
Suppose I have an array A={2,3,2,4,20394,21,-132,2832} , How I can use this code to find RMQ(1,4)?

1.What will the split function do here ?
Nothing: the function body is empty. There may be some other implementation where an action is required. (See Example 3) And see answer to 2b
2.... Where the value will be saved?
In the "val" field of the class/struct for which "merge" is called.
1b.What is the use of the array tree and what values will be kept there ?
Array "node tree[...]" stores all the nodes of the tree. Its element type is "struct node".
2b.What will this statement : tree[root].split(tree[left_child], tree[right_child]); do ?
It calls split for the struct node that's stored at index root, passing the nodes of the split node's children to it. What it actually does to tree[root] depends on the implementation of "split".
3b.What will those statements do ? :
node n; // declare a new node
n.merge(l,r); // call merge - store the minimum of l.val, r.val into n.val
return n; // terminate the function and return n
I'll have to figure out the answers to your last Qs in the context of that code. Will take a little time.
Later
This should build a tree and do a range query. I'm not sure that the code on that page is correct. Anyway, the interface for range_query is not what you'd expect for easy usage.
int main(){
int a[] = { -132, 1, 2, 3, 4, 21, 2832, 20394};
for( int i = 0; i < 8; i++ ){
node x;
x.val = a[i];
update( i, x);
}
node y = range_query(0, 8, 15, 8 + 1, 8 + 4 );
}

Related

diameter of a Binary tree recursive approach

I am trying to find diameter using recursion ,I am confused with recursion
some of the test cases I tried I got correct answer at some point
Integer overflow occured But Below author's solution was accepted with same data types
My approach:
For every node, length of longest path which pass it = MaxDepth of its left subtree + MaxDepth of its right subtree.
My question is whats wrong with my implementation
class Solution {
public:
int mx = 0;
int solve(TreeNode* root) {
if (root == NULL)return 0;
int leftheight = diameterOfBinaryTree(root->left) + 1;
int rightheight = diameterOfBinaryTree(root->right) + 1;
mx = max(mx, leftheight + rightheight);
return max(leftheight, rightheight);
}
int diameterOfBinaryTree(TreeNode* root) {
solve(root);
return mx;
}
};
Authors approach: same approach but different recursion implementation
class Solution {
public:
int maxdiadepth = 0;
int dfs(TreeNode* root) {
if (root == NULL) return 0;
int leftdepth = dfs(root->left);
int rightdepth = dfs(root->right);
if (leftdepth + rightdepth > maxdiadepth) maxdiadepth = leftdepth + rightdepth;
return max(leftdepth + 1, rightdepth + 1);
}
int diameterOfBinaryTree(TreeNode* root) {
dfs(root);
return maxdiadepth;
}
};
In the working implementation, the recursive dfs call returns the max depth of the subtree.
In your implementation, the recursive diameterOfBinaryTree call returns the currently accumulated approximation to the diameter. You assign it to variables named leftheight and rightheight - that's misleading; the value is not, in fact, the height of the left or right sub-tree.
Consider the case when you hit a leaf node or the case where you have only one node. Your algorithm returns 2, which is incorrect. This problem arises because you compute the height by adding one to the left / right subtree, no matter what.
To fix this, add one when you return the height, like so: max(leftheight, rightheight) + 1
Btw, when you recursively call, you should do solve(root->left) or solve(root->right) and not diameterOfBinaryTree(root->left) :P

sparse matrix using linked list C++

I'm coding the program that using linked list to store a sparse matrix. First I create a class "Node" contains the index of entry, value of entry and two pointers to next row and next column. Second I find on Google that I need to create the class Matrix like this code below but I don't understand the meaning of Node **rowList and node** columnList. Why they use a pointer to a pointer there and how could I implement a matrix from that? Thank you so much.
class Node
{
public:
int iValue, jValue;
float value;
Node *rowPtr;
Node *colPtr;
};
class Matrix
{
Node **rowList; // rowList is the pointer to the array of rows
Node **columnList; // columnList is the pointer to the array of columns
int rows, cols; // number of rows and columns
}
It appears to be exactly what the comment says. They are arrays. Presumably rowList will be an array of rows elements, and columnList will be an array of cols elements. The reason it's a Node** is that each item in the array is a Node*. A pointer to an array always has an extra level of indirection (an extra *). That means when you index a single element out of that array you get a value of type Node* again.
The arrays are created like this:
rowList = new Node* [rows];
columnList = new Node* [cols];
// Don't forget to initialise the values to NULL! Here's the dull way:
for( int i = 0; i < rows; i++ ) rowList[i] = NULL;
for( int i = 0; i < cols; i++ ) columnList[i] = NULL;
When you need to delete them (in the destructor for Matrix):
delete [] rowList;
delete [] colList;
As for your question on how to implement your matrix from that, that's really up to you. Presumably when you create a node at position (i, j), you append that node to each of rowList and columnList. ie:
Node * node = new Node(i, j, 123.0);
rowList[i] = node;
columnList[j] = node;
But it's not that simple, because the node obviously must be linked into both a row and column list. At the very basic level, and using the structures you've provided, here's one way:
// Inserts newNode at the head of the list and modifies the head pointer.
void insert_row( Node* & r, Node *newNode )
{
newNode->rowPtr = r;
if( r != NULL ) r->rowPtr = newNode;
r = newNode;
}
// Similarly with insert_col()...
Now using the above with my original example:
Node * node = new Node(i, j, 123.0);
insert_row( rowList[i], node );
insert_col( columnList[j], node );
For ordered insert
Since you have code already, I will offer my take on it. But you still need to do some work yourself.
I just try to understand the concept but it's so confusing for me.
Let's just clean things up to begin with. It's a class, and you're using C++ so please use your C++ knowledge:
class Node
{
public:
Node( int i, int j, int val );
void InsertRowAfter( Node* node );
void InsertColAfter( Node* node );
int iValue, jValue; // Row and column index, 1-based
float value; // Element value
Node *rowPtr; // Next element in this row (sorted by jValue)
Node *colPtr; // Next element in this column (sorted by iValue)
};
Node::Node( int i, int j, int val )
: iValue(i)
, jValue(j)
, value(val)
, rowPtr(NULL)
, colPtr(NULL)
{}
// Inserts the given node to follow this node in the row list
void Node::InsertRowAfter( Node* node )
{
// [go on, you do it]
}
// Inserts the given node to follow this node in the column list
void Node::InsertColAfter( Node* node );
{
// [go on, you do it]
}
So, now you need to implement the Matrix::inputData function... Essentially you do what your friend was trying to do, but without the errors and memory leaks. That means you start like this:
// Use 'horz' and 'vert' to search through the row and column lists. If a
// node needs to be created, it will be stored in 'node'.
Node *horz = rowList[iValue - 1];
Node *vert = columnList[jValue - 1];
Node *node;
// If there is no row list or smallest jValue, insert at the head.
// Otherwise, search for an insert point.
if( !horz || horz->jValue > jValue )
{
// [go on, you do it]
}
else
{
// Move 'horz' pointer to position at which we will append a node.
Node *next = horz->rowPtr;
while( next && next->jValue <= jValue ) {
horz = next;
next = next->rowPtr;
}
// If replacing an existing value, there's nothing else to do.
if( horz->jValue == jValue ) {
horz->value = value;
return;
}
// Otherwise append a new node.
// [go on, you do it]
}
Now, you finish the function off, and don't forget to do the column indexing...

Find nth smallest element in Binary Search Tree

I have written an algorithm for finding nth smallest element in BST but it returns root node instead of the nth smallest one. So if you input nodes in order 7 4 3 13 21 15, this algorithm after call find(root, 0) returns Node with value 7 instead of 3, and for call find(root, 1) it returns 13 instead of 4. Any thoughts ?
Binode* Tree::find(Binode* bn, int n) const
{
if(bn != NULL)
{
find(bn->l, n);
if(n-- == 0)
return bn;
find(bn->r, n);
}
else
return NULL;
}
and definition of Binode
class Binode
{
public:
int n;
Binode* l, *r;
Binode(int x) : n(x), l(NULL), r(NULL) {}
};
It is not possible to efficiently retrieve the n-th smallest element in a binary search tree by itself. However, this does become possible if you keep in each node an integer indicating the number of nodes in its entire subtree. From my generic AVL tree implementation:
static BAVLNode * BAVL_GetAt (const BAVL *o, uint64_t index)
{
if (index >= BAVL_Count(o)) {
return NULL;
}
BAVLNode *c = o->root;
while (1) {
ASSERT(c)
ASSERT(index < c->count)
uint64_t left_count = (c->link[0] ? c->link[0]->count : 0);
if (index == left_count) {
return c;
}
if (index < left_count) {
c = c->link[0];
} else {
c = c->link[1];
index -= left_count + 1;
}
}
}
In the above code, node->link[0] and node->link[1] are the left and right child of node, and node->count is the number of nodes in the entire subtree of node.
The above algorithm has O(logn) time complexity, assuming the tree is balanced. Also, if you keep these counts, another operation becomes possible - given a pointer to a node, it is possible to efficiently determine its index (the inverse of the what you asked for). In the code I linked, this operation is called BAVL_IndexOf().
Be aware that the node counts need to be updated as the tree is changed; this can be done with no (asymptotic) change in time complexity.
There are a few problems with your code:
1) find() returns a value (the correct node, assuming the function is working as intended), but you don't propagate that value up the call chain, so top-level calls don't know about the (possible) found element
.
Binode* elem = NULL;
elem = find(bn->l, n);
if (elem) return elem;
if(n-- == 0)
return bn;
elem = find(bn->r, n);
return elem; // here we don't need to test: we need to return regardless of the result
2) even though you do the decrement of n at the right place, the change does not propagate upward in the call chain. You need to pass the parameter by reference (note the & after int in the function signature), so the change is made on the original value, not on a copy of it
.
Binode* Tree::find(Binode* bn, int& n) const
I have not tested the suggested changes, but they should put you in the right direction for progress

Recursive to Iterative Transformation

I've gotten stuck on trying to re-write my code from a recursive function into an iterative function.
I thought I'd ask if there are any general things to think about/tricks/guidelines etc... in regards to going from recursive code to iterative code.
e.g. I can't rly get my head around how to get the following code iterative, mainly due to the loop inside the recursion which further depends on and calls the next recursion.
struct entry
{
uint8_t values[8];
int32_t num_values;
std::array<entry, 256>* next_table;
void push_back(uint8_t value) {values[num_values++] = value;}
};
struct node
{
node* children; // +0 right, +1 left
uint8_t value;
uint8_t is_leaf;
};
void build_tables(node* root, std::array<std::array<entry, 8>, 255>& tables, int& table_count)
{
int table_index = root->value; // root is always a non-leave, thus value is the current table index.
for(int n = 0; n < 256; ++n)
{
auto current = root;
// Recurse the the huffman tree bit by bit for this table entry
for(int i = 0; i < 8; ++i)
{
current = current->children + ((n >> i) & 1); // Travel to the next node current->children[0] is left child and current->children[1] is right child. If current is a leaf then current->childen[0/1] point to the root.
if(current->is_leaf)
tables[table_index][n].push_back(current->value);
}
if(!current->is_leaf)
{
if(current->value == 0) // For non-leaves, the "value" is the sub-table index for this particular non-leave node
{
current->value = table_count++;
build_tables(current, tables, table_count);
}
tables[table_index][n].next_table = &tables[current->value];
}
else
tables[table_index][n].next_table = &tables[0];
}
}
As tables and table_count always refer to the same objects, you might make a small performance gain by taking tables and table_count out of the argument list of build_tables by storing them as members of a temporary struct and then doing something like this:
struct build_tables_struct
{
build_tables_struct(std::array<std::array<entry, 8>, 255>& tables, int& table_count) :
tables(tables), table_count(table_count) {}
std::array<std::array<entry, 8>, 255>& tables;
int& table_count;
build_tables_worker(node* root)
{
...
build_tables_worker(current); // instead of build_tables(current, tables, table_count);
...
}
}
void build_tables(node* root, std::array<std::array<entry, 8>, 255>& tables, int& table_count)
{
build_tables_struct(tables, table_count).build_tables_worker(root);
}
This applies of course only if your compiler is not smart enough to make this optimisation itself.
The only way you can make this non-recursive otherwise is managing the stack yourself. I doubt this would be much if any faster than the recursive version.
This all being said, I doubt your performance issue here is recursion. Pushing three reference arguments to the stack and calling a function I don't think is a huge burden compared to the work your function does.

c++ directed graph depth first search

I am attempting to write a method DFS method for a directed graph. Right now I am running into a segmentation fault, and I am really unsure as to where it is. From what I understand of directed graphs I believe that my logic is right... but a fresh set of eyes would be a very nice help.
Here is my function:
void wdigraph::depth_first (int v) const {
static int fVertex = -1;
static bool* visited = NULL;
if( fVertex == -1 ) {
fVertex = v;
visited = new bool[size];
for( int x = 0; x < size; x++ ) {
visited[x] = false;
}
}
cout << label[v];
visited[v] = true;
for (int v = 0; v < adj_matrix.size(); v++) {
for( int x = 0; x < adj_matrix.size(); x++) {
if( adj_matrix[v][x] != 0 && visited[x] != false ) {
cout << " -> ";
depth_first(x);
}
if ( v == fVertex ) {
fVertex = -1;
delete [] visited;
visited = NULL;
}
}
}
}
class definition:
class wdigraph {
public:
wdigraph(int =NO_NODES); // default constructor
~wdigraph() {}; // destructor
int get_size() { return size; } // returns size of digraph
void depth_first(int) const;// traverses graph using depth-first search
void print_graph() const; // prints adjacency matrix of digraph
private:
int size; // size of digraph
vector<char> label; // node labels
vector< vector<int> > adj_matrix; // adjacency matrix
};
thanks!
You are deleting visited before the end of the program.
Coming back to the starting vertex doesn't mean you finished.
For example, for the graph of V = {1,2,3}, E={(1,2),(2,1),(1,3)}.
Also, notice you are using v as the input parameter and also as the for-loop variable.
There are a few things you might want to consider. The first is that function level static variables are not usually a good idea, you can probably redesign and make those either regular variables (at the cost of extra allocations) or instance members and keep them alive.
The function assumes that the adjacency matrix is square, but the initialization code is not shown, so it should be checked. The assumption can be removed by making the inner loop condition adj_matrix[v].size() (given a node v) or else if that is an invariant, add an assert before that inner loop: assert( adj_matrix[v].size() == adj_matrix.size() && "adj_matrix is not square!" ); --the same goes for the member size and the size of the adj_matrix it self.
The whole algorithm seems more complex than it should, a DFS starting at node v has the general shape of:
dfs( v )
set visited[ v ]
operate on node (print node label...)
for each node reachable from v:
if not visited[ node ]:
dfs( node )
Your algorithm seems to be (incorrectly by the way) transversing the graph in the opposite direction. You set the given node as visited, and then try to locate any node that is the start point of an edge to that node. That is, instead of following nodes reachable from v, you are trying to get nodes for which v is reachable. If that is the case (i.e. if the objective is printing all paths that converge in v) then you must be careful not to hit the same edge twice or you will end up in an infinite loop -> stackoverflow.
To see that you will end with stackoverlow, consider this example. The start node is 1. You create the visited vector and mark position 1 as visited. You find that there is an edge (0,1) in the tree, and that triggers the if: adj_matrix[0][1] != 0 && visited[1], so you enter recursively with start node being 1 again. This time you don't construct the auxiliary data, but remark visited[1], enter the loop, find the same edge and call recursively...
I see a couple of problems:
The following line
if( adj_matrix[v][x] != 0 && visited[x] != false ) {
should be changed to
if( adj_matrix[v][x] != 0 && visited[x] == false ) {
(You want to recurse only on vertices that have not been visited already.)
Also, you're creating a new variable v in the for loop that hides the parameter v: that's legal C++, but it's almost always a terrible idea.