Questions regarding Red-Black Tree Deletion (z has 2 children) (pre-fixDelete) - c++

Code Source - https://github.com/Bibeknam/algorithmtutorprograms/blob/master/data-structures/red-black-trees/RedBlackTree.cpp
y = z;
int y_original_color = y->color;
if (z->left == TNULL) {
x = z->right;
rbTransplant(z, z->right);
} else if (z->right == TNULL) {
x = z->left;
rbTransplant(z, z->left);
} else {
y = minimum(z->right);
y_original_color = y->color;
x = y->right;
if (y->parent == z) {
x->parent = y; \\ [1] Local Class TNull
} else {
rbTransplant(y, y->right); \\ [2] Losing Y
y->right = z->right;
y->right->parent = y;
}
rbTransplant(z, y);
y->left = z->left;
y->left->parent = y;
y->color = z->color; \\ [3] Need of Recoloring
}
Questions
Local Class TNull - (In case y->right is a TNull) Within this class function, TNull is a local pointer simply passed to x; isn't changing the parent of x also change the parent of the local TNull?
Losing Y - This section is meant to be executed in case the minimum in right subtree of z is not a direct children. Later it will be placed at z's location. Won't this segment only pivot y->right / x until it reaches z's location, instead of y / minimum?
Need of Recoloring - Iirc, recoloring will also happen in the later fixDelete() function call, why is this needed?
Please bear with me, I'm slow in this kind of stuff and I'm really at my wits' end. This is the first time I'm asking here. Thank you.

On your questions
Yes that can happen, TNull's parent is set and the authors remark that this is a deliberate design choice which they exploit.
y is moving to where z is and this just fixes y so its pointers are what z had. s
No. Essentially when the node to be deleted has 2 children, you find the successor or predecessor node (which has to have 0 or 1 child) and swap the nodes. You then delete the node at the successor or predecessor node position. The predecessor or successor node swapped, preserves the tree ordering. But the important thing is in swapping the nodes, the colour is not swapped, it must be preserved so the red-black tree properties are still correct.
This is what y_original_color is for.

Related

How to wrap x and y around the screen?

For example, if a moving ball goes beyond the screen, what is the exact method to do it?
I currently do this:
if (x < 0.0) x = screenWidth() - 1;
else if (x >= screenWidth()) x = 0;
// same for y
But I saw this version:
if (x < 0.0) x = x + screenWidth();
else if (x >= screenWidth()) x = x - screenWidth();
// same for y
Isn't the second version doing useless addition/subtraction?
They do slightly different things: one does a cyclic wrapping (the second version) the other one just brings it to the edge (the first version).
Note that the code you are using for the cyclic wrapping may in general be wrong. Consider for example a screen_size = 800; and x = -10000;. Your code will bring it to x = -9200. You probably want to do x = x % screen_size before using your code for the cyclic wrapping, or you could use: ((x % screen_size) + screen_size) % screen_size instead.
In your version you just move the ball to the edge of the screen if it went out of it, but in the other version it keeps the distance that the balls travelled theoretically outside the screen to be considered in its new position. This helps to show the ball as travelling with the same speed.

Belman-Ford algorithm in 2d Array

I've got a problem with applying a Bellman-Ford algorithm to 2D Array (not to graph)
Input array has m x n dimensions:
s[1,1] s[1,2] ... s[1,n] -> Exit
s[2,1] s[2,2] ... s[2,n]
...
Entry -> s[m,1] s[m,2] ... s[m,n]
And it is room-alike (each entry is a room with s[x,y] cost of enterance). Each room could have also a negative cost, and we have to find cheapest path from Entry to choosen room and to Exit.
For example, we've got this array of rooms and costs:
1 5 6
2 -3 4
5 2 -8
And we want to walk over room [3,2], s[3,2] = 4. We are starting form 5 at [1,3] and must walk over [3,2] before we go to [3,3].
And my question is, what is the best way to implement it in Bellman-Ford algorithm? I know that Dijkstry algorithm will not work becouse of negative cost.
Is for each room from [0, maxHeight] and relax all neighbors correct? Like this:
for (int i = height-1; i >= 0; --i) {
for (int j = 0; j < width; ++j) {
int x = i;
int y = j;
if (x > 0) // up
Relax(x, y, x - 1, y);
if (y + 1 < width) // right
Relax(x, y, x, y + 1);
if (y > 0) // left
Relax(x, y, x, y - 1);
if (x + 1 < height) // down
Relax(x, y, x + 1, y);
}
}
But how can I then read a cost to choosen room and from room to exit?
If you know how to move on the graph from an array, you can scroll to additional condition paragraph. Read also next paragraph.
In fact, you can look at that building like on a graph.
You can see like: (I forgot doors in second line, sorry.)
So, how it is possible to be implement. Ignore for the moment additional condition (visit a particular vertex before leaving).
Weight function:
Let S[][] be an array of entry cost. Notice, that about weight of edge decides only vertex on the end. It has no matter if it's (1, 2) -> (1,3) or (2,3) -> (1, 3). Cost is defined by second vertex. so function may look like:
cost_type cost(vertex v, vertex w) {
return S[w.y][w.x];
}
//As you can see, first argument is unnecessary.
Edges:
In fact you don't have to keep all edges in some array. You can calculate them in function every time you need.
The neighbours for vertex (x, y) are (x+1, y), (x-1, y), (x, y+1), (x, y-1), if that nodes exist. You have to check it, but it's easy. (Check if new_x > 0 && new_x < max_x.) It may look like that:
//Size of matrix is M x N
is_correct(vertex w) {
if(w.y < 1 || w.y > M || w.x < 1 || w.x > N) {
return INCORRECT;
}
return CORRECT;
}
Generating neighbours can look like:
std::tie(x, y) = std::make_tuple(v.x, v.y);
for(vertex w : {{x+1, y}, {x-1, y}, {x, y+1}, {x, y-1}}) {
if(is_correct(w) == CORRECT) {//CORRECT may be true
relax(v, w);
}
}
I believe, that it shouldn't take extra memory for four edges. If you don't know std::tie, look at cppreference. (Extra variables x, y take more memory, but I believe that it's more readable here. In your code it may not appear.)
Obviously you have to have other 2D array with distance and (if necessary) predecessor, but I think it's clear and I don't have to describe it.
Additional condition:
You want to know cost from enter to exit, but you have to visit some vertex compulsory. Easiest way to calculate it is to calculate cost from enter to compulsory and from compulsory to exit. (There will be two separate calculations.) It will not change big O time. After that you can just add results.
You just have to guarantee that it's impossible to visit exit before compulsory. It's easy, you can just erase outgoing edges from exit by adding extra line in is_correct function, (Then vertex v will be necessary.) or in generating neighbours code fragment.
Now you can implement it basing on wikipedia. You have graph.
Why you shouldn't listen?
Better way is to use Belman Ford Algorithm from other vertex. Notice, that if you know optimal path from A to B, you also know optimal path from B to A. Why? Always you have to pay for last vertex and you don't pay for first, so you can ignore costs of them. Rest is obvious.
Now, if you know that you want to know paths A->B and B->C, you can calculate B->A and B->C using one time BF from node B and reverse path B->A. It's over.
You just have to erase outgoing edges from entry and exit nodes.
However, if you need very fast algorithm, you have to optimize that. But it is for another topic, I think. Also, it looks like no one is interested in hard optimization.
I can quickly add, just that small and easy optimization bases at that, that you can ignore relaxation from correspondingly distant vertices. In array you can calculate distance in easy way, so it's pleasant optimization.
I have not mentioned well know optimization, cause I believe that all of them are in a random course of the web.

Tree graph: drawing elements which might explode

I'm deciding how to store data and how to draw a tree graph. Assuming I want a minimum space M between two elements, I was thinking I could traverse the entire tree structure from the top to the bottom in breath-first search.
If there's just one element below the current one, it will be drawn with the same X coordinate as his father. If there are two elements, they will be drawn one at -M/2 and the other at +M/2 with respect to their father X coordinate. And so on..
The problem is: what if an element like C (see diagram below) has a great number of children?? I should restructure the entire tree since I should move the element D to the left and make space for all the E-F children of C. Moving D to the left will get the tree crooked and I will need to move B too. Moving B to the left would alter the tree's symmetry so I'll need to move C too and so on..
How can I draw a perfectly symmetric tree whose elements may have a large number of children?
Do it the other way up: compute each node's horizontal position from those of its children after they've been computed. Something like this (WARNING: completely untested code; may consist entirely of bugs):
void Node::place_self(coord_t x0, coord_t y0) {
this->y0 = y0; this->y1 = y0+height;
if (!left && !right) {
// This is a leaf. Put its top left corner at (x0,y0).
this->x0 = x0; this->y0 = y0;
this->subtree_x1 = x0+width;
}
else if (!left || !right) {
// Only one child. Put this immediately above it.
Node * child = left ? left : right;
child->place_self(x0,y0+height+gap);
coord_t xc = child->x0 + child->width/2;
this->x0 = xc-width/2;
this->subtree_x1 = max(this->x0+width, child->subtree_x1);
}
else {
// Two children. Put this above their midline.
left->place_self(x0, y0+height+gap);
right->place_self(left->subtree_x1+gap, y0+height+gap);
coord_t xc = (x0 + right->subtree_x1)/2;
this->x0 = xc-width/2;
this->subtree_x1 = max(this->x0+width, right->subtree_x1);
}
}

How to rotate a treap or AVL-tree?

Sorry to bother you guys again, but I have a question and i haven't figured it out on my own for several days.
It is about the rotation of a treap, for example, to right rotate a treap at pos.
The question is how to link (or connect) pos->left to pos's original parent?
I found this code online, which works, but i didn't see how it solves my question, is it because of the use of *&? If so, could you help me explain it a little bit?
And what is the function of pos=b is this code?
void Treap::right_rotate(Node *&pos) {
Node *b = pos->left;
pos->left = b->right;
b->right = pos;
pos = b;
}
Thanks in advance!!
The tricky part is indeed the *& part. That declares it as a reference to a pointer (here's a link or two to some similar sample code, but I fear they may be more confusing than helpful).
By changing out the node to which the pointer points with pos = b, you can swap the contents to the different node without having to know the parent. The original reference is updated to be the new rotated node.
Here's a diagram just in case you needed a little overkill of what the rotation looks like (though it sounds like you understand that part).
Initial condition:
Node *&pos;
|
[P]
/ \
L R
/ \ / \
w x y z
You then store the left child since you are about to overwrite it as far as P is concerned.
Node *b = pos->left;
pos->left = b->right;
|
L [P]
/ \ / \
w x R
/ \
y z
Now we finish the rotation since since L is floating in space, breaking proper tree structure:
b->right = pos;
L
/ \ |
w [P]
/ \
x R
/ \
y z
We then finish the upkeep by updating the reference to the node pointer to be the new node that replaces the contents of that place in memory:
pos = b;
|
[L]
/ \
w P
/ \
x R
/ \
y z
Whomever was previously pointing to pos (pos's original parent) now points to the same spot in memory, but that value has now been replaced with the child that has been rotated.

Polygon in rectangle algorithm?

I have an algorithm which can find if a point is in a given polygon:
int CGlEngineFunctions::PointInPoly(int npts, float *xp, float *yp, float x, float y)
{
int i, j, c = 0;
for (i = 0, j = npts-1; i < npts; j = i++) {
if ((((yp[i] <= y) && (y < yp[j])) ||
((yp[j] <= y) && (y < yp[i]))) &&
(x < (xp[j] - xp[i]) * (y - yp[i]) / (yp[j] - yp[i]) + xp[i]))
c = !c;
}
return c;
}
given this, how could I make it check if its within a rectangle defind by Ptopleft and Pbottomright instead of a single point?
Thanks
Basically you know how in Adobe Illustrator you can drag to select all objects that fall within the selection rectangle? well I mean that. –
Can't you just find the minimum and maximum x and y values among the points of the polygon and check to see if any of the values are outside the rectangle's dimensions?
EDIT: duh, I misinterpreted the question. If you want to ensure that the polygon is encosed by a rectangle, do a check for each polygon point. You can do that more cheaply with the minimum/maximum x and y coordinates and checking if that rectangle is within the query rectangle.
EDIT2: Oops, meant horizontal, not vertical edges.
EDIT3: Oops #2, it does handle horizontal edges by avoiding checking edges that are horizontal. If you cross multiply however, you can avoid the special casing as well.
int isPointInRect( Point point, Point ptopleft, Point pbottomright) {
float xp[2] ;
xp[0] = ptopleft.x,
xp[1] = pbottomright.x;
float yp[2] ;
yp[0] = ptopleft.y ;
yp[1] = pbottomright.y ;
return CGlEngineFunctions::PointInPoly(2, xp, yp, point.x, point.y);
}
As mentioned before, for that specific problem, this function is an overkill. However, if you are required to use it, note that:
1. It works only for convex polygons,
2. The arrays holding the polygon's vertices must be sorted such that consecutive points in the array relate to adjacent vertices of your polygon.
3. To work properly, the vertices must be ordered in the "right hand rule" order. That means that when you start "walking" along the edges, you only make left turns.
That said, I think there is an error in the implementation. Instead of:
// c initialized to 0 (false), then...
c = !c;
you should have something like:
// c initialized to 1 (true), then...
// negate your condition:
if ( ! (....))
c = 0;