Node is not being inserted after random number of times, Binary Search Tree (C++) - insert

As you will see in the below output, nodes with values 10 and 15 are not being added.
The whole code is below
..............
.............
...............
..............
.............
#include<iostream>
using namespace std;
#define SPACE 10
class TreeNode{
public:
int value;
TreeNode *left;
TreeNode *right;
TreeNode(){
value = 0;
left = NULL;
right = NULL;
}
TreeNode(int v){
value = v;
left = NULL;
right = NULL;
}
};
class BST{
public:
TreeNode *root;
BST(){
root = NULL;
}
bool isEmpty(){
if(root == NULL)
return true;
else
return false;
};
void insertNode(TreeNode *new_node){
if(root == NULL){
root = new_node;
cout<<"Node entered at root"<<endl;
}
else{
TreeNode *temp = root;
while(temp!=NULL){
if(new_node->value == temp->value){
cout<<"Node already exist"<<endl;
break;
}
else if((new_node->value < temp->value) && (temp ->left == NULL)){
temp->left = new_node;
cout<<"Inserted at right"<<endl;
break;
}
else if (new_node->value < temp->value){
temp = temp->left;
break;
}
else if((new_node->value > temp->value) && (temp ->right == NULL)){
temp->right = new_node;
cout<<"Inserted at left"<<endl;
break;
}
else if (new_node->value > temp->value){
temp = temp->right;
break;
}
}
}
}
void print2D(TreeNode * r, int space) {
if (r == NULL) // Base case 1
return;
space += SPACE; // Increase distance between levels 2
print2D(r -> right, space); // Process right child first 3
cout << endl;
for (int i = SPACE; i < space; i++) // 5
cout << " "; // 5.1
cout << r -> value << "\n"; // 6
print2D(r -> left, space); // Process left child 7
}
};
int main(){
BST obj;
int option, val;
do {
cout << "What operation do you want to perform? " <<
" Select Option number. Enter 0 to exit." << endl;
cout << "1. Insert Node" << endl;
//cout << "2. Search Node" << endl;
//cout << "3. Delete Node" << endl;
cout << "2. Print/Traversal BST values" << endl;
//cout << "5. Height of Tree" << endl;
//cout << "6. Clear Screen" << endl;
cout << "0. Exit Program" << endl;
cin >> option;
//Node n1;
TreeNode *newNode = new TreeNode();
switch (option){
case 0:
break;
case 1:
cout<<"Insert Node"<<endl;
cout<<"Enter the value of the node"<<endl;
cin>>val;
newNode->value = val;
obj.insertNode(newNode);
break;
case 2:
cout<<"Print value"<<endl;
obj.print2D(obj.root, 5);
break;
default:
cout<<"Enter appropriate option"<<endl;
} //switch
}while(option!=0);
}
OUTPUT:
What operation do you want to perform? Select Option number. Enter 0 to exit.
1. Insert Node
2. Print/Traversal BST values
0. Exit Program
1
Insert Node
Enter the value of the node
30
Node entered at root
What operation do you want to perform? Select Option number. Enter 0 to exit.
1. Insert Node
2. Print/Traversal BST values
0. Exit Program
1
Insert Node
Enter the value of the node
18
Inserted at right
What operation do you want to perform? Select Option number. Enter 0 to exit.
1. Insert Node
2. Print/Traversal BST values
0. Exit Program
1
Insert Node
Enter the value of the node
45
Inserted at left
What operation do you want to perform? Select Option number. Enter 0 to exit.
1. Insert Node
2. Print/Traversal BST values
0. Exit Program
1
Insert Node
Enter the value of the node
10
What operation do you want to perform? Select Option number. Enter 0 to exit.
1. Insert Node
2. Print/Traversal BST values
0. Exit Program
1
Insert Node
Enter the value of the node
15
What operation do you want to perform? Select Option number. Enter 0 to exit.
1. Insert Node
2. Print/Traversal BST values
0. Exit Program
2
Print value
45
30
18
As you see the node 10 and 15 is not being added to the tree. I've tried every single way.
Plz if anyone has solution do provide it. Thank you

Make temp=temp->left in first else if block and remove second else if block and do same for 3rd and 4 th else if block

Related

A Scapegoat Tree That Just Won't Balance

So, I'm working on this project for Comp 272, Data Structures and Algorithms, and before anyone asks I have no one to help me. It's an online program through Athabasca University and for some unknown reason they didn't supply me with a tutor for this course, which is a first... So... Yeah. The question is as follows:
"(20 marks) Exercise 8.2. Illustrate what happens when the sequence 1, 5, 2, 4, 3 is added to an empty ScapegoatTree, and show where the credits described in the proof of Lemma 8.3 go, and how they are used during this sequence of additions."
This is my code, its complete and it compiles:
/*
Name: Westcott.
Assignment: 2, Question 3.
Date: 08-26-2022.
"(20 marks) Exercise 8.2. Illustrate what happens when the sequence 1, 5, 2, 4, 3 is added to an empty
ScapegoatTree, and show where the credits described in the proof of Lemma 8.3 go, and how they are used
during this sequence of additions."
*/
#include <iostream>
using namespace std;
class Node { // Originally I did this with Node as a subclass of sgTree but I found that this
public: // way was easier. This is actually my second attempt, from scratch, at doing this
int data; // problem. First version developed so many bugs I couldn't keep up with them.
Node* left;
Node* right;
Node* parent;
Node() : data(0), parent(NULL), left(NULL), right(NULL) {};
Node(int x) : data(x), parent(NULL), left(NULL), right(NULL) {};
~Node() {}; // Normally I would do a little more work on clean up but... Yea this problem didn't leave me much room.
Node* binarySearch(Node* root, int x); // The Node class only holds binarySearch in addition to its
// constructors/destructor, and of course the Node*'s left, right and parent.
};
class sgTree { // The sgTree keeps track of the root, n (the number of nodes in the tree), and q which is
public: // as Pat put it a 'high water mark'.
Node* root;
int n;
int q;
sgTree() : root(new Node()), n(1), q(1) {}
sgTree(int x) : root(new Node(x)), n(0), q(0) {}
~sgTree() {
delete root;
}
bool add(int x); // The add function is compounded, within it are findDepth and rebuild.
bool removeX(int x); // removeX works, but it didn't have a big part to play in this question,
int findDepth(Node* addedNode); // but I'll include it to maintain our sorted set interface.
void printTree(Node* u, int space) { // This was extra function I wrote to help me problem solve.
cout << "BINARY TREE DISPLAY" << endl; // this version only prints a title and then it calls printTreeSub on line 46.
cout << "________________________________________________\n\n" << endl;
printTreeSub(u, space);
cout << "________________________________________________\n\n" << endl;
}
int printTreeSub(Node* u, int space); // Function definition for this is on line 81.
int storeInArray(Node* ptr, Node* arr[], int i);// this is our function for storing all the elements of a tree in an array.
int size(Node* u); // this is size, defined on line 74.
void rebuild(Node* u); // And rebuild and buildBalanced are the stars of the show, defined on lines 262 and 282
Node* buildBalanced(Node** a, int i, int ns); // just above the main() funciton.
};
int log32(int q) { // As you can see there's two versions of this function.
int c = 0; // this is supposed to return the log of n to base 3/2.
while (q != 0) { // The version below I got from this website:
q = q / 2; // https://www.geeksforgeeks.org/scapegoat-tree-set-1-introduction-insertion/
c++; // It works fine but I prefer the one I wrote.
} // this is a much simpler function. It just divides q until its zero
return c; // and increments c on each division. Its not exact but it is based on what Pat said
} // in this lecture: https://www.youtube.com/watch?v=OGNUoDPVRCc&t=4852s
/*
static int const log32(int n)
{
double const log23 = 2.4663034623764317;
return (int)ceil(log23 * log(n));
}
*/
int sgTree::size(Node* u) {
if (u == NULL) {
return 0;
}
return 1 + size(u->left) + size(u->right); // Recursion in size();
}
int sgTree::printTreeSub(Node* u, int space) { // Here is my strange print function
if (u == NULL) return space; // I say strange because I'm not even 100% sure
space--; // how I got it to work. The order itself I worked out, but I built it
space -= printTreeSub(u->left, space); // and, originally, got a half decent tree, but then I just kept playing
if (u->right == NULL && u->left == NULL) { // around with increments, decrements, and returned values
cout << "\n\n\n" << u->data << "\n\n\n" << endl; // of space until it just sort of came together.
return 1; // Basically it prints the left most Node first and then prints every node
} // beneath that using recursion. I realized that by setting the for loop
for (int i = space; i >= 0; i--) { // on line 89 I could imitate different nodes having different heights in
cout << " "; // the tree. I figured that using n as an input I could take advantage of
} // the recursion to get an accurate tree. That much I understand.
cout << " " << u->data << "'s children are: "; // But it didn't work out quite how I wanted it to so I just kept playing
if (u->left != NULL) { // with space increments and decrements on different sides of the tree until
cout << u->left->data; // I got something pretty good.
}
else {
cout << "NULL";
}
if (u->right != NULL) {
cout << " and " << u->right->data;
}
else {
cout << " NULL";
}
cout << "\n\n" << endl;
space--;
space -= printTreeSub(u->right, space);
return 1;
}
int sgTree::storeInArray(Node* ptr, Node* a[], int i) { // This function took me a while to figure out.
if (ptr == NULL) { // The recursive insertions of values using i, when
return i; // i is defined by the very same recursion, makes this
} // a bit of a challenge to get your head around.
i = storeInArray(ptr->left, a, i); // Basically its just taking advantage on an inOrder
a[i] = ptr; // transversal to get the values stored into the array
i++; // in order from least to greatest.
return storeInArray(ptr->right, a, i);
}
Node* Node::binarySearch(Node* root, int x) { // I covered this in another question.
if (root->data == x) {
return root;
}
else if (x < root->data) {
if (root->left == NULL) {
return root;
}
return binarySearch(root->left, x);
}
else if (x > root->data) {
if (root->right == NULL) {
return root;
}
return binarySearch(root->right, x);
}
}
bool sgTree::add(int x) { // The add function itself isn't too difficult.
Node* addedNode = new Node(x); // We make a Node using our data, then we search for that Node
Node* parent = root->binarySearch(root, x); // in the tree. I amended binarySearch to return the parent
addedNode->parent = parent; // if it hits a NULL child, on lines 127 and 133.
if (x < parent->data) { // That way the new Node can just go into the returned parents child
parent->left = addedNode; // here is where we choose whether it enters the left or the right.
}
else if (x > parent->data) {
parent->right = addedNode;
}
int h = findDepth(addedNode); // We run findDepth() on the addedNode. I realize that this probably should
// have been a part of the binarySearch, it means we go down
if (h > log32(q)) { // the tree twice instead of once. I did look at changing binarySearch into searchAndDepth
// having binarySearch return an int for the height isn't a problem, but then that would
// mess up removeX and, I don't know. What's more important?
Node* w = addedNode->parent; // If this were going to be a database hosting millions of pieces of data I would give
while (3 * size(w) < 2 * size(w->parent)) { // that alot more consideration but, this is just an exercise after all so...
w = w->parent; // From there, we compare our height to the value output by log32(q) on line 152.
}
rebuild(w); // This expression 3 * size(w) < 2 * size(w->parent) is the formula on page 178 rewritten
//rebuild(root); // as a cross multiplication, clever. It keeps going up the tree until we find the scapegoat w.
// This is a much nicer result.
//See line 311.
} // Now, this is where my problems began. Pat says that this line should read: rebuild(w->parent);
n++; // but when I do that I get an error when w is the root. Because then w->parent is NULL. And in that case
q++; // line 258 throws an error because we're trying to set p equal to NULL's parent. It's not there.
return true; // So my work around was to just offset this by one and send rebuild(w). But that doesn't seem
} // to balance the tree just right. In fact, the best tree results when we replace w with root.
// and just rebalance the whole tree. But in any case, we increment n and q and lets pick this up on line 256.
int sgTree::findDepth(Node* addedNode) {
int d = 0;
while (addedNode != root) {
addedNode = addedNode->parent;
d++;
}
return d;
}
bool sgTree::removeX(int x) {
Node* u = root->binarySearch(root, x);
if (u->left == NULL && u->right == NULL) {
if (u == u->parent->left) {
u->parent->left = NULL;
}
if (u == u->parent->right) {
u->parent->right = NULL;
}
cout << u->data << " deleted" << endl;
n--;
delete u;
return true;
}
if (u->left != NULL && u->right == NULL) {
if (u->parent->left = u) {
u->parent->left = u->left;
}
else if (u->parent->right = u) {
u->parent->right = u->left;
}
cout << u->data << " deleted" << endl;
n--;
delete u;
return true;
}
if (u->left == NULL && u->right != NULL) {
if (u == u->parent->left) {
u->parent->left = u->right;
u->right->parent = u->parent;
}
else if (u == u->parent->right) {
u->parent->right = u->right;
u->right->parent = u->parent;
}
cout << u->data << " deleted" << endl;
n--;
delete u;
return true;
}
if (u->left != NULL && u->right != NULL) {
Node* X = u->right;
if (X->left == NULL) {
X->left = u->left;
if (u->parent != NULL) {
if (u->parent->right == u) {
u->parent->right == X;
}
else if (u->parent->left == u) {
u->parent->left = X;
}
}
else {
root = X;
}
X->parent = u->parent;
cout << u->data << " deleted" << endl;
n--;
delete u;
return true;
}
while (X->left != NULL) {
X = X->left;
}
X->parent->left = NULL;
X->left = u->left;
X->right = u->right;
if (u->parent != NULL) {
X->parent = u->parent;
}
cout << u->data << " deleted" << endl;
n--;
root = X;
delete u;
return true;
}
}
void sgTree::rebuild(Node* u) {
int ns = size(u); // Everything is pretty kosher here. Just get the number of nodes in the subtree.
Node* p = u->parent; // Originally I had n here instead of ns and... I don't want to talk about how long it took me to find that mistake...
/* It's funny because while writing the comments for this I'm like "Oh, hang on, if I just push the definition of p behind the if statement on line 262
and evaluate for whether or not u is NULL instead of p, that should solve all my problems! Yea, no, it doesn't. Because then for some reason it tries rebalancing
empty tree and... Yea I just have to stop myself from trying to fix this because everytime I do I get caught in an infinite loop of me chasing my tail in errors.
I think a solution could be found in buildBalanced, and I literally went through that function line by line, trying to comprehend a work around. I've included at
a photograph of that white board. Yea this is the code that Pat gave us... and its garbage. It doesn't work. Maybe its a C++ thing, I don't know... But I'm
getting frustrated again so I'm going to stop thinking about this part RIGHT HERE, and move on LOL*/
Node** a = new Node * [ns]; // a Node pointer-pointer array... again, another fine piece of code from the textbook. Sorry, trying to stay positive here.
storeInArray(u, a, 0); // See Line 112
if (p == NULL) { // Okay, once we have our array we use buildBalanced to rebuild the subtree with respect to which
root = buildBalanced(a, 0, ns); // child u is relative to its parent.
root->parent = NULL; // See line 281 for buildBalanced().
}
else if (p->right == u) {
p->right = buildBalanced(a, 0, ns);
p->right->parent = p;
}
else {
p->left = buildBalanced(a, 0, ns);
p->left->parent = p;
}
}
Node* sgTree::buildBalanced(Node** a, int i, int ns) { // This is without a doubt one of the hardest functions I've ever had
if (ns == 0) { // the displeasure of trying to understand... Trying to stay positive.
return NULL; // I've gone through it, in a line by line implementation of the array:
} // a[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10} you can find that analysis in
int m = ns / 2; // the photo buildBalanced_Analysis.
a[i + m]->left = buildBalanced(a, i, m); // As confusing as it is, I have to admit that it is a beautiful function.
if (a[i + m]->left != NULL) { // It basically uses the two integers i and m to simultaneously
a[i + m]->left->parent = a[i + m]; // regulate the organization of the new tree and to specifically
} // grab the right value from the array when its needed.
a[i + m]->right = buildBalanced(a, i + m + 1, ns - m - 1); // but trying to map this out didn't help me to solve the issues I've been having.
if (a[i + m]->right != NULL) {
a[i + m]->right->parent = a[i + m];
}
return a[i + m];
}
int main() {
sgTree newTree(1);
int a[] = { 5, 2, 4, 3 };
for (int i = 0; i < (sizeof(a) / sizeof(a[0])); i++) {
newTree.add(a[i]);
}
newTree.printTree(newTree.root, newTree.n);
/*
This is a nice test, when paired with rebuild(root), that too me is the only thing that approaches redeeming this whole question.
sgTree newTreeB(1);
int b[] = { 2, 3, 4, 5, 6, 7, 8, 9, 10 };
for (int i = 0; i < (sizeof(b) / sizeof(b[0])); i++) {
newTreeB.add(b[i]);
}
newTreeB.printTree(newTreeB.root, newTreeB.n);
*/
}
Now the issue itself is not that hard to understand. My tree should look like this:
But instead, it looks like this, with 5 at the root and the values 1 and 4 as the leaves:
I'm confident that the problem lives somewhere around line 159 and in those first few calls to buildBalanced. The comments in the code itself elaborate more on the issue. I've spent days just pouring over this trying everything I can think of to make it work and... Yeah... I just can't figure it out.

Mirror a Binary Tree without recursion

I am trying to mirror the binary tree without recursive methods by using two queues and a binary tree which I have created.
Following is the function which i have used.
root is the pointer to the root node of the original binary tree and mirrior_root is of a mirrored binary tree.
The error seems to be lies in the logic part !
Help would be appreciated !
#include<iostream>
#include<queue>
using namespace std;
class Node
{
public:
Node *lchild;
int data;
Node *rchild;
};
class Tree
{
public:
Node *root;
Node *mirror_root;
Tree()
{
root = NULL;
}
void create_Tree()
{
Node *p;
Node *t;
int x;
queue <Node *> q;
root = new Node ;
cout << "Enter the data you want to insert in root";
cin >> x;
root->data = x;
root->lchild = root ->rchild = NULL;
q.emplace(root);
while(! q.empty())
{
p = q.front();
q.pop();
cout << "Enter the left child of " << p->data << ":";
cin >> x;
if(x != -1)
{
t= new Node;
t->data = x;
t->lchild = t->rchild = NULL;
p->lchild = t;
q.emplace(t);
}
cout << "Enter the right child of " << p->data << ":";
cin >> x;
if(x != -1)
{
t= new Node;
t->data = x;
t->lchild = t->rchild = NULL;
p->rchild = t;
q.emplace(t);
}
}
}
void Preorder(Node *p)
{
if(p)
{
cout << p->data << " " ;
Preorder(p->lchild);
Preorder(p->rchild);
}
}
void Level_order(Node *p)
{
queue <Node *> q;
q.emplace(p);
cout << p->data << " " ;
while(!q.empty())
{
p = q.front();
q.pop();
if(p->lchild)
{
cout << p->lchild->data << " ";
q.emplace(p->lchild);
}
if(p->rchild)
{
cout << p->rchild->data << " ";
q.emplace(p->rchild);
}
}
}
void mirror_tree(Node *p)
{
Node *mirror_root;
Node *t;
Node *k;
queue <Node *> q_root;
queue <Node *> q_mirror;
mirror_root = new Node;
mirror_root->data = p->data;
mirror_root->lchild = mirror_root->rchild = NULL;
t=mirror_root;
q_root.emplace(p);
q_mirror.emplace(t);
while(!q_root.empty())
{
p=q_root.front();
q_root.pop();
t = q_mirror.front();
q_mirror.pop();
if(p->lchild)
{
k = new Node;
k->data = p->lchild->data;
k->lchild = k->rchild = NULL;
t->rchild = k;
q_root.emplace(p->lchild);
q_mirror.emplace(t->rchild);
}
if(p->rchild)
{
k = new Node;
k->data = p->rchild ->data;
k->lchild = k->rchild = NULL;
t->lchild = k;
q_root.emplace(p->rchild);
q_mirror.emplace(t->lchild);
}
}
}
};
int main()
{
Tree bt;
bt.create_Tree();
bt.mirror_tree(bt.root);
cout << "Level order of mirrored binary tree is : ";
bt.Level_order(bt.mirror_root);
}
Here is input and output
Enter the data you want to insert in root: 5
Enter the left child of 5:6
Enter the right child of 5:7
Enter the left child of 6:8
Enter the right child of 6:9
Enter the left child of 7:10
Enter the right child of 7:11
Enter the left child of 8:-1
Enter the right child of 8:-1
Enter the left child of 9:-1
Enter the right child of 9:-1
Enter the left child of 10:-1
Enter the right child of 10:-1
Enter the left child of 11:-1
Enter the right child of 11:-1
Level order of mirrored binary tree is : 7769539
Output which i expected is
Level order of mirrored binary tree is 5 7 6 11 10 9 8
The problem is that you declare Node *mirror_root as a local variable in mirror_tree, while you want the code to give a value to the class member with the same name.
So remove that line from the mirror_tree function.

How can i make this modification on Dijkstra Algorithm more efficient?

The problem is a part of my computer science homework. The homework includes 5 different types of students that travel through a given weighted undirected node graph where each student has a different method. The fifth student is the most difficult one and I haven't been able to implement it efficiently.
The fifth student has a secret power, (s)he can teleport between adjacent nodes, so it takes 0 time to travel between them. However, to recharge that secret power, (s)he needs to pass two edges, and (s)he does not have that secret power at the beginning of his/her journey. Unlike other four students, (s)he can use the same edge multiple times, so in the first move, (s)he may go N_1->N_2 and N_2->N_1 to recharge his/her secret power. (S)he cannot store his/her secret power and must use it right away after after gaining it.
The fifth student wants to know the shortest time to reach the summit. At start, (s)he does not have any power, so (s)he needs to pass two edges to recharge it.
The method i tried was a modification of Dijkstra's Algorithm; where instead of moving node by node, from one node it calculates all three possible jumps, only considering the weights of the first two jumps. It considers all cases such as going to a node and coming back to recharge power and jump a highly weighted node. It does work and i do get all the correct answers for the given test cases, but it is SLOW. We are under a two second limit and right now my algorithm takes around 4 seconds for test cases with 50 000 nodes and 100 000 edges.
I'm guessing the problem is within reaching neighbors since there are 3 nested for loops to reach all possible 3 jump away neighbors (while also being able to use the same edges more than once), which basically makes this O(n^3) (But I'm not great with big-oh notation so I'm not sure if it's actually that.)
Does anyone have any ideas to make this algorithm more efficient, or a different algorithm that isn't so slow?
Any help is appreciated!
Here's the code if it's of any help.
long long int HelpStudents::fifthStudent() {
auto start = std::chrono::system_clock::now();
set< pair<long long int,int> >setds;
vector<long long int> dist(totalNodes+15,std::numeric_limits<long long int>::max());
setds.insert(make_pair(0,1));
dist[1] = 0;
bool change = false;
int counter = 0; //these variables were just for checking some things
int max_counter = 0;
int changed_summit = 0;
int operations_after_last_change = 0;
int w1;
int w2;
int db = 0;
vector<int> neighbors;
vector<int> neighbors2;
vector<int> neighbors3;
int u;
while(!setds.empty()){
pair<long long int,int> tmp = *(setds.begin());
setds.erase(setds.begin());
u = tmp.second; //vertex label
if(dist[u] > dist[summit_no]){
continue;
}
if(!change){
counter++;
}else{
counter = 0; //debugging stuff
}
db++;
//cout << db2 << endl;
operations_after_last_change++;
max_counter = max(counter,max_counter);
//cout << "counter: " << counter <<endl;
change = false;
neighbors = adjacency_map[u]; //adjacency map holds a vector which contains the adjacent nodes for the given key
//cout << "processing: " << "(" << tmp.first << ","<< tmp.second << ") " << endl;
for(int nb : neighbors){
w1 = getWeight(u,nb); //this is one jump,
//nb is neighboor
neighbors2 = adjacency_map[nb];
//cout << "\t->" << nb << endl;
if( nb == summit_no){
if(dist[nb] > dist[u] + (w1)){
auto t = setds.find(make_pair(dist[nb],nb));
if(t != setds.end()){
setds.erase(t);
}
dist[nb] = dist[u] + (w1);
change = true;
changed_summit++;
operations_after_last_change = 0;
//cout << "changed summit to " << (dist[u] + (w1)) << endl;
//continue;
}
}
for(int nb2: neighbors2){ //second jump
w2 = getWeight(nb,nb2);
//cout << "\t\t->" << nb2 << endl;
if( nb2 == summit_no){
if(dist[nb2] > dist[u] + (w1+w2)){
auto t = setds.find(make_pair(dist[nb2],nb2));
if(t != setds.end()){
setds.erase(t);
}
dist[nb2] = dist[u] + (w1+w2);
change=true;
changed_summit++;
operations_after_last_change = 0;
//cout << "changed summit to " << (dist[u] + (w1+w2)) << endl;
//continue;
}
}
neighbors3 = adjacency_map[nb2];
for(int nbf: neighbors3){ //third jump, no weight
//cout << "\t\t\t->" << nbf;
if(dist[nbf] > dist[u] + (w1+w2)){
auto t = setds.find(make_pair(dist[nbf],nbf));
if(t != setds.end()) {
setds.erase(t);
}
change = true;
dist[nbf] = dist[u] + (w1+w2);
if(nbf == summit_no){
changed_summit++;
operations_after_last_change = 0;
//cout << endl;
}else{
setds.insert(make_pair(dist[nbf],nbf));
//cout << "\t\t\t\t inserted ("<<dist[nbf]<<","<<nbf<<")" << endl;
}
//cout << "changed " << nbf << " to " << (dist[u] + (w1+w2)) << "; path: "<< u <<" -> "<<nb<<" -> "<<nb2 << " -> " <<nbf << endl;
//setds.insert(make_pair(dist[nbf],nbf));
}else{
//cout << endl;
}
}
}
}
}
auto end = std::chrono::system_clock::now();
std::chrono::duration<double> elapsed_seconds = end-start;
cout << "time passed: "<< elapsed_seconds.count() <<" total loop: "<<db<< endl;
return dist[summit_no];
You make (or more likely imagine) a new directed graph with a node for each unique situation/state that student 5 can be in -- that is combination of original graph node and charge state (0, 1, or 2). Because there are 3 charge states, this graph will have 3 times as many nodes as the original.
Then you use perfectly ordinary Dijkstra's algorithm on this new graph.

Why is problemsPathCoordinate vector of a vector of a pair empty?

I have tried to fill a smaller vector of a vector of pairs with some contents from a bigger vector of a vector of pairs without success. Below is the relevant code with couts and their output. Hopefully this is detailed enough.
/*******************Problems Occur*****************/
int iFirst=problemsStartAt;//first index to copy
int iLast=problemsEndAt-1;//last index -1, 11th stays
int iLen=iLast-iFirst;//10-8=2
//if(problemsStartAt!=0)//I.a
if(problemsStartAt!=0&&problemsEndAt!=0)//I.b
{
v_problem_temp=allPathCoordinates[problemsStartAt];
cout<<"266:"<<v_problem_temp.size()<<endl;
cout<<"267:"<<allPathCoordinates.at(1).size()<<endl;
for(vector<pair<int,int>>::iterator it2=v_problem_temp.begin();
it2!=v_problem_temp.end();
++it2)
{
apair=*it2;
point[apair.first][apair.second]=Yellow;
cout<<apair.first<<","<<apair.second<<endl;
}
problemsPathCoordinate.resize(iLen);
cout<<"iLen*sizeof(problemsPathCoordinate):" <<iLen*sizeof(problemsPathCoordinate)<<endl;
memcpy(&problemsPathCoordinate[0],&allPathCoordinates[iFirst],iLen*sizeof(problemsPathCoordinate));
cout<<"279:problemsPathCoordinate.size():"<<problemsPathCoordinate.size()<<endl;
problemsPathCoordinate.resize(iLen);
memcpy(&problemsPathCoordinate[0],&allPathCoordinates[iFirst],iLen*sizeof(problemsPathCoordinate));
cout<<"283:problemsPathCoordinate.size():"<<problemsPathCoordinate[0].size()<<endl;
cout<<"284:problemsPathCoordinate.size():"<<problemsPathCoordinate[1].size()<<endl;
cout<<"286:allPathCoordinates.size():"<<allPathCoordinates.size()<<endl;
cout<<"287:allPathCoordinates.size():"<<allPathCoordinates.size()<<endl;
//from http://stackoverflow.com/questions/35265577/c-reverse-a-smaller-range-in-a-vector
}
Output:
759: path NOT full-filled, number: 8
755: Problems START here at:8
759: path NOT full-filled, number: 9
700: Problems END here at: 11
266:0
267:0
iLen*sizeof(problemsPathCoordinate):72
279:problemsPathCoordinate.size():3
283:problemsPathCoordinate.size():0
284:problemsPathCoordinate.size():0
286:allPathCoordinates.size():79512
287:allPathCoordinates.size():79512
time:39 seconds
Why are the three problemsPathCoordinate elements empty. How to fix it?
Bo
for (vector< vector > >::iterator it = allPathCoordinates.begin(); it != allPathCoordinates.end(); ++it)
{
allPathCoordinates.erase(allPathCoordinates.begin()+5,allPathCoordinates.end()-2);
v_temp = *it;
//cout<<"v_temp.size():"<
for (vector<pair<int,int> >::iterator it2 = v_temp.begin(); it2 != v_temp.end(); ++it2) {
//v_temp.erase(v_temp.begin()+2);
apair = *it2;
//cout << "(" << apair.first << "," << apair.second << ") ; ";
openPoints[apair.first][apair.second]=0;
closedPoints[apair.first][apair.second]=1;
allObstacles[apair.first][apair.second]=Wall;
point[apair.first][apair.second]=Yellow;
}
/

Red Black Tree Insertion Not Working

I'm working on a red black tree assignment for my class and I'm having some trouble with the insertion function. My problem is that my root node value is being changed somehow between the end of the insert function and the beginning of insert being called again. I ran it through the debugger in Visual Studio and saw no reason why the root key should be altered like it is. I'm sure there are many other errors in my code thus far because I decided to focus on this before the rest of the program. Once this is fixed I will go back and correct other errors. I have not yet implemented the fix-up function for correcting the tree after insertion so don't worry about red-black tree properties being met. If you have any questions or if I haven't given enough info then please let me know.
/ rbtree.cpp
#include <iostream>
#include <iomanip>
#include "rbtree.h"
using std::cout;
using std::setw;
using std::endl;
void RBTree::reverseInOrderPrint(Node *x, int depth) {
if ( x != nil ) {
reverseInOrderPrint(x->right, depth+1);
cout << setw(depth*4+4) << x->color << " ";
cout << *(x->key) << " " << *(x->value) << endl;
reverseInOrderPrint(x->left, depth+1);
}
}
RBTree::RBTree()
{
nil = new Node();
root = nil;
}
RBTree::~RBTree()
{
//delete[] root;
}
void RBTree::rbInsert(const string& key_given, const string& value_given)
{
//if(root != nil)
//cout << *(root -> key) << " <- root key at beginning of insert function" << endl;
Node* input_node = new Node(key_given, value_given, nil);
Node* target = root;
Node* target_parent = nil;
while(target != nil)
{
target_parent = target;
if(input_node -> key -> compare(*(target -> key)) < 0)
target = target -> left;
else
target = target -> right;
}
input_node -> parent = target_parent;
if(target_parent == nil)
root = input_node;
else if(input_node -> key -> compare(*(target_parent -> key)) < 0)
target_parent -> left = input_node;
else
target_parent -> right = input_node;
input_node -> left = nil;
input_node -> right = nil;
input_node -> color = 'R';
/*rbInsertFixup(input_node);
cout << *(root -> key) << " <- root key at end of insert function" << endl;
if(root -> left != nil)
cout << *(root -> left -> key) << " is root's left child" << endl;
if(root -> right != nil)
cout << *(root -> right -> key) << " is root's right child" << endl;*/
}
//void RBTree::rbInsertFixup(
RBTree::Node::Node()
{
parent = NULL;
left = NULL;
right = NULL;
color = 'B';
key = NULL;
value = NULL;
}
RBTree::Node::Node(const string& key_given, const string& value_given, Node* nil_pntr)
{
parent = nil_pntr;
left = nil_pntr;
right = nil_pntr;
color = 'R';
key = &key_given;
value = &value_given;
}
RBTree::Node::~Node()
{
if(left != NULL)
delete left;
if(right != NULL)
delete right;
}
int main()
{
RBTree tree;
tree.rbInsert("Zack", "His Birthday");
tree.rbInsert("Terri", "Her Birthdays");
tree.rbInsert("Zzck", "HBD");
return 0;
}
Here is an example of the output I get when running this code:
Zack <- root key at end of insert function
Terri <- root key at beginning of insert function
Terri <- root key at end of insert function
Terri is root's right child
Zzck <- root key at beginning of insert function
Zzck <- root key at end of insert function
Zzck is root's right child
you need to compare 2 strings, you have to dereference the input_node->key and because you are using compare to check the two strings try using "<" or ">" and i am pretty sure it will work have something like this * (input_node -> key) <*(target_parent -> key)

Resources