Disclaimer: This is for an assignment. I would like pointers in the right direction (no pun intended) rather than straight code solutions.
I'm attempting to implement a max winner tree (a binary tree in which the node's value is the max of it's children's values, so that the root eventually has the max value of all the bottom leaves). My current MaxWinnerTree initializes a tree full of -1s, just as place holders for values to be inserted later on.
MaxWinnerTree.cpp
#include "MaxWinnerTree.h"
MaxWinnerTree::MaxWinnerTree(int elements)
{
int size = 1;
while (size<elements)
size = size * 2; //gets closest power of 2 to create full bottom row
*a = new Node[size];
for (int i = (2*elements-1); i>0; i--)
{
if (i > elements-1) //leaf
{
//Create new nodes with data -1, store pointer to it in array
*a[i] = (newNode(i,-1,NULL,NULL,NULL));
}
else // not leaf
{
//Create node with data = max of children, store pointer
*a[i] = newNode(i,-1,a[i*2],a[i*2 +1], NULL); //create
a[i]->data = max(a[i*2]->data, a[i*2+1]->data); //gets max
a[i]->right->parent = a[i];
a[i]->left->parent = a[i];
}
}
}
Node MaxWinnerTree::newNode(int key, int data, Node *left, Node *right, Node *parent)
{
Node *n = new Node;
key = key;
data = data;
left = left;
right = right;
parent = parent;
return *n;
}
In my Main, I attempt to create a MaxWinnerTree object to perform actions on (insertion, etc), but I know the way I'm doing it is incorrect. My MaxWinnerTree method doesn't return a value, and the only objects I'm creating are an array and then a linked mess of nodes. As I type this, I'm going to go back and attempt to return a linked list as my tree and go from there, but is this the direction that I should be going in?
Main.cpp
int main (){
bool quit;
int command, elements, binSize;
cout<<"Welcome to assignment 6!"<<endl;
while (!quit)
{
cout<<"Choose an option for the test: 1-> First fit, 2-> Best Fit, 3-> Quit"<<endl;
cin>>command;
if(command==1)
{
cout<<"First Fit!";
cout<<"Enter number of objects: ";
cin>> elements;
cout<<"\n Enter capacities of bins: ";
cin>> binSize;
cout<<"\n";
MaxWinnerTree* tree = new MaxWinnerTree(elements); //Throws x86 error, also throws error when not decared as a pointer
tree->insert(7);
//Irrelevant rest of non-applicable code
In essence, what do I need to do differently to get a tree object that I can operate on after calling my constructor?
Also: I'm shaky on pointers, so if something looks off or bad practice, please let me know.
Related
So I'm trying to work on a project for my C++ class where I read a .txt file that has 53 lines of cities, states, and superfluous information afterwards.
(example: Port Jervis,NY,New York,36071,Orange,36071,41.3782,-74.6909,16410.0,1317)
After reading the file, I separate out the city name (example: Port Jervis) and state code (example: NY) and uses the value of the two letters in the state code as the key for a hash table of 13 elements. So N=13 + Y=24 = key of 37, and since the hash has 13 elements it's 37 % 13 = hash-key of 11.
So far so good and I'm able to get all that done correctly, however when it comes to displaying the results is where I'm running into an issue as each element of the hash-table is missing one link in the linked list. So it only displays 40 outputs of the 53, with 1 missing per element and I'm really not sure why.
So I e-mailed my professor my code and he said that my insert method is not correct which he believes is causing this error. My current insert method looks like
void insert(int key, string city, string state)//insert value
{
int hash = KeyModFunction(key); //function that's %13 for hash-key
Node* tmpInsert = new Node(key, city, state); //create node to work with
if(table[hash]==NULL)//checks if table is empty
{
table[hash] = tmpInsert; //if empty, make new node with key/city/state values
}
else//if not empty
{
Node *runner = table[hash]; //made node to run through the list
while(runner->next != NULL)//make it to the end
{
runner=runner->next; // go go go
}
runner->next = tmpInsert; //and point the end at the new node to be inserted
}
} //end insert
And my professor suggested it should look something more like
if(table[hash]->next == NULL)
{
table[hash]->next = tmpInsert;
table[hash]->myCity = city;
table[hash]->myState = state;
}
else
{
// You can figure out the else code based on the above
However, whenever I put that into my code, it no longer compiles and says there is a segment fault. But when I run it through a debugger it says "[Inferior 1 (process 5453) exited normally]" which I'm not going to lie, I'm not sure what the means and have been unable to find a concrete answer online for. But I'm assuming the exited normally is a good thing, however, nothing is displayed.
I've been beating my head against this all week trying to figure out a solution and it's finally come to the point where I know I'm just getting too in my own head about it, so I've come here hoping to find some guidance, advice, or at the very least someone to point me in the right direction. If more of my code is needed on here, let me know, I just didn't want to dump my whole project on here cause I legitimately want to figure it out instead of having someone just do it for me, but yeah, I'm stuck. Thanks in advance for any help!
****2:12PST - 5/17/2020 UPDATE****
So in all fairness the insert code was plucked and modified from other peoples code I've found online looking into how to do this, so that might be why it looks better than my professor (also I'm pretty sure he mention C++ isn't his most familiar language). And yes, we are supposed to implement the hash table ourselves.
So here is the full program:
class Node{
public:
int key;
string myCity;
string myState;
Node *next;
Node(int key, string myCity, string myState)//constructor
{
this->key = key;
this->myCity = myCity;
this->myState = myState;
this->next = NULL;
}
};//end Node
class Hash{
private:
int BUCKET; //number of over all values
Node** table;
public:
//Constructor
Hash(int V)
{
this->BUCKET = V; //setting the BUCKET size to max number of enteries
table = new Node*[BUCKET]; //create table with size of BUCKET
for(int i = 0; i < BUCKET; i++) //fill table with NULL values
{
table[i] = NULL;
}
} //end constructor
//KeyModFunction
int KeyModFunction(int x) //getting the hash key value
{
return (x % BUCKET);
} //end KeyModFunction
//Insert Function
void insert(int key, string city, string state)//insert value
{
int hash = KeyModFunction(key); //function that's %13 for hash-key
Node* tmpInsert = new Node(key, city, state); //create node to work with
if(table[hash]==NULL)//checks if table is empty
{
table[hash] = tmpInsert; //if empty, make new node with key/city/state values
}
else//if not empty
{
Node *runner = table[hash]; //made node to run through the list
while(runner->next != NULL)//make it to the end
{
runner=runner->next; // go go go
}
runner->next = tmpInsert; //and point the end at the new node to be inserted
}
} //end insert
//Display function
void displayHash()
{
for(int loop = 0; loop < BUCKET; loop++)
{
cout<<loop;
if(table[loop]->next != NULL)
{
Node* tmp;
tmp = table[loop]->next;
do
{
cout<<" -->"<<tmp->myCity<<"/"<<tmp->myState;
tmp = tmp->next;
}while(tmp!=NULL);
}
cout<<endl;
}
}//end displayHash
}; //end Hash Class
int main() {
cout << "CSP 31B - Read and Process Assignment\n\n";
char myAlpha[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; //the key array for all the letter values
Hash myTbl(13); //create hashmap with BUCKET size of 13
string fCity, fState, fExtra; //string variables to hold info
int key = 0; //hash value of the state code (two letters added together)
ifstream myfile("CityOut.txt");
while ( getline(myfile, fCity, ',') && getline(myfile, fState, ','))
{
getline(myfile, fExtra);
for(int i = 0; i < sizeof(myAlpha)/sizeof(myAlpha[0]); i++)
{
if(fState.at(0) == myAlpha[i])
{
key += i;
}
else if(fState.at(1) == myAlpha[i])
{
key += i;
}
}
int checkNum = 1;
cout << "DEBUGGER: City name: "<<fCity <<" State code: " << fState.at(0) << fState.at(1) <<" key = "<<key<<endl; //temporary statement for debugging purposes
myTbl.insert(key, fCity, fState);
key = 0; //reset hash number to zero for next line of CityOut.txt
}
cout<<endl<<endl<<endl;
myTbl.displayHash();
return 0;
}//end main
Then the output should look something like:
but each table element should have 1 more output
Your print code skips the first element of your hash table.
This code:
cout<<loop;
if(table[loop]->next != NULL)
{
Node* tmp;
tmp = table[loop]->next;
do
{
cout<<" -->"<<tmp->myCity<<"/"<<tmp->myState;
tmp = tmp->next;
}while(tmp!=NULL);
}
Should be :
cout<<loop;
if(table[loop] != NULL)
{
Node* tmp;
tmp = table[loop];
do
{
cout<<" -->"<<tmp->myCity<<"/"<<tmp->myState;
tmp = tmp->next;
}while(tmp!=NULL);
}
I am working on a pretty basic binary tree implementation in C++, but I am currently having a problem that deleting a pointer to the root node crashes the program. In Dev-C++ debug mode the error returned is: "Program received signal SIGTRAP, Trace/breakpoint trap", but when I check with "info breakpoints", it says there are no breakpoints or watchpoints. I'm pretty confused about this and have been spending a lot of time checking if I have used and declared all the pointers correctly, any help would greatly be appreciated!
#include <iostream>
#include <vector>
using namespace std;
class Node {
public:
int key;
Node * left_child = NULL;
Node * right_child = NULL;
};
class Tree {
public:
int num_nodes;
vector<Node> nodes;
int read() {
cin >> num_nodes;
nodes.resize(num_nodes);
int input_key, input_left, input_right, root_node = 0;
for (int i = 0; i < num_nodes; i++) {
cin >> input_key >> input_left >> input_right;
if(input_key >= nodes.size()) {
nodes.resize(input_key+1);
}
if(i==0) {
root_node = input_key;
}
nodes[input_key].key = input_key;
if(input_left >= 0) {
nodes[input_key].left_child = &nodes[input_left];
}
if(input_right >= 0) {
nodes[input_key].right_child = &nodes[input_right];
}
}
return root_node;
}
};
int main() {
Tree t;
int root_index = 0;
root_index = t.read();
Node * root_ptr = new Node;
root_ptr = &(t.nodes[root_index]);
delete root_ptr; //when I take this line out, it works
}
Sample Input (no output expected):
3
4 2 5
2 -1 -1
2 -1 -1
Firstly, this line is useless:
Node * root_ptr = new Node;
You immediately reassign root_ptr to something else. So the line does nothing but allocate memory. You then assign root_ptr as follows:
&(t.nodes[root_index]);
The variable t you declared on the stack. You end up getting a pointer to a vector element, an element you never allocated yourself. If you did not allocate it yourself, you cannot delete it. Any allocation by the vector will be handled by the vector, and the vector itself is a stack-allocated, so you cannot delete it.
That is why the delete line crashes.
Additionally, you say it is a simple binary tree implementation, but it is not. You have a vector in there, and you have a strange way of assigning the tree elements, so you've created some kind of hybrid data structure.
I have a txt file that contains a matrix of chars(1 or 2 at each position in matrix)
C P O Hr S A
N Hw N L Z R
W T O O Ta A
I O S S E T
Something like this. What I managed to do is to create a linked list and store every element of this matrix in that list (separately).
struct DataNode{
char data[3];
struct DataNode *nextData;
};
void initNode(DataNode *head, char x[3]) {
for(int i=0; i<3; i++)
head->data[i]=x[i];
head->nextData=NULL;
}
void addNode(DataNode *head, char x[3]) {
DataNode *newNode = new DataNode;
for(int i=0; i<3; i++)
newNode->data[i]=x[i];
newNode->nextData=NULL;
DataNode *curr = head;
while(curr) {
if(curr->nextData==NULL) {
curr->nextData = newNode;
return;
}
curr = curr->nextData;
}
}
int main() {
char input[3];
if(in.is_open()) {
in>>input;
initNode(head,input);
for(int i=0; i<3; i++)
dieSide[i]=input[i];
while(in>>input) {
addNode(head,input);
}
in.close();
}
}
So far, this works as it should, and I guess I'm happy with it.
What I need now, it another linked list, where the elements would still be char[3] types, but there has to be first a list containing a row of 6 elements, and then, another list, containing all of those 6 element lists.
I hope I made myself clear about my wishes.
I'm thinking about creating another struct, with next pointers to each of two active lists, but still not sure about that idea.
How would you recommend me to go about doing this?
EDIT
Just a little help, please...
I have re-implemented all of the functions to suit the struct you (#Daniel) suggested, and they appear to work. However, I need a way to "reset" the DataNode* I want to use for creating small lists. This way I only get entire matrix printed as many times as there are lines in the file.
What I have is>
char input[3];
int counter=0;
struct DataNode *head = new DataNode; //creates a list of all elements
struct DataNode *head_side = new DataNode; //want to use this one to create smaller lists
struct DieSideNode *head_die = new DieSideNode; //creates a list of smaller lists
if(in.is_open()) {
in>>input;
initNode(head,input);
initNode(head_side, input);
counter++;
while(in>>input) {
addNode(head,input);
addNode(head_side, input);
counter++;
if( counter == 6 ) {
initSide(head_die, head_side);
head_side=0;
}else if(counter%6==0) {
addSide(head_die, head_side);
head_side=0;
}
}
in.close();
}
This code successfully extracts first six elements, and puts it as a first element of the list, but then it stops working there.
I'll give you a little hint to get started. As you know, a linked-list node contains some data and a pointer to the next element of the list. What you call a "2-d linked list" would actually simply be implemented as a linked-list of linked-lists. Each node in the list points to another linked list. So you will need to define a new type:
struct ListNode {
DataNode* dataRowHead;
struct ListNode* nextRow;
};
What you are trying to do would have 6 ListNodes connected as a linked-list. Each ListNode contains a pointer to a DataNode which is the head of a linked-list for the row that corresponds to the ListNode that points to it.
I will leave the implementation up to you.
I want to perform BFS on a tree, to find out a certain leaf, but the graph is dynamic in nature, when I land on a leaf and that leaf isn't the one I am looking for, then its children are computed from the leaf (The leaf is no longer a leaf it is a node).
I tried two implementations , and both produced erronous results. I think the pointers are getting invalidated or this is an incorrect implementation. My code is as follows
int y=0;
while(graph.end() - graph.begin() < 262145 and graph.end() - graph.begin() < y){
if(found(graph[y])){
clock2 = graph[y];
break;
}
else{
if(graph[y].b[0] < 4) graph.push_back(move1(graph[y]));
if(graph[y].b[1] < 4) graph.push_back(move2(graph[y]));
}
y++;
}
and the next implementation was something like this
for(vector<foo> :: iterator i = graph.begin();i!=graph.end();i++){
if(found(*i)){
clock2 = *i;
break;
}
else{
if(i->b[0] < 4) graph.push_back(move1(*i));//move1 and move2 are
if(i->b[1] < 4) graph.push_back(move2(*i));//functions of return type foo
}
}
Both of these are causing the programme to crash. What is wrong with them, how to implement these? Please comment with additional queries.
I am a little confused as too what exactly is going on and what exactly you are asking. But if you are asking how to preform a simple BFS on a graph here is some sample code that I find pretty easy to read.
Comment further and I will change it to try and match the exact criteria of the question (once I have some more clarity that is)
struct node{
std::vector children<node*>;
int data;
}
void bfs(node* root, int value){ // THIS IS CHECK FOR INTS so change for whatever value
if(!root) return;
std::queue myq;
myq.push(root);
node* toCheck;
while(!myq.Empty()){
toCheck = myq.top();
myq.pop();
if(toCheck->data == value){
//do whatever you want with that information
}else{
/*
//forloop/whileloop as many times as necessary to set all the new children
//Example:
node* newNode = new node();
newNode->data = someValue; // just some information that you want to add
toCheck->children.push_back(newNode);
*/
}
for(int i = 0; i < toCheck->children.size(); i++){
myq.push(toCheck->children[i]);
}
}
}
I am currently working on the knights tour project. My goal ultimately is to create this project using backtracking (by implementing stack) and Warnsdorff's heuristic. I am not allowed to use any libraries that has stack functions already created such as push and pop. I am also not allowed to resolve the problem using recursion. With that being said, I am pretty stuck right now and my next big milestone would be to solve the problem by only backtracking.
I am not going to sugar coat this at all, but right now my code is one big mess. I have pretty much created all the tools I need to make the program run, but now I just need to put all the pieces together.
The following is my code:
#include<iostream>
using namespace std;
class linkedList{
struct node
{
int data;
node *next;
};
node *top;
public:
linkedList()
{
top = NULL;
}
void push(int coordinates)
{
node *p = new node;
p -> data = coordinates;
p -> next = top;
top = p;
}
int pop()
{
node *temp = top;
top = temp -> next;
return temp -> data;
}
int display()
{
cout<<"\n"<< top -> data;
top = top-> next;
}
};
// Linked List ================================================
class Board{
public:
int next;
int status[8][8];
Board();
void print();
};
Board::Board(){
for(int i=0; i<8; i++){
for(int j=0; j<8; j++){
status[i][j] = -1;
}
}
}//constructor
void Board::print(){
for (int j=0; j<8; j++){
for(int i=0; i<8;i++){
cout << status[i][j] << " ";
}
cout << endl << endl;
}
}
//BOARD========================================================
class Knight {
private:
public:
int vertical[8] = {2,-2,1,-1,2,-2,1,-1}; // possible knight moves x coordinate
int horizontal[8] = {1,1,2,2,-1,-1,-2,-2}; // possible knight move y coordinate
int counter;
int currentPos[2];
Knight();
};
Knight::Knight(){
currentPos[0] = 7; // x-coordiante
currentPos[1] = 7; // y-coordinate
counter = 0;
}//constructor
/* Use this later
int Knight::changePos(int i,int j){
Knight::currentPos[0] = (Knight::currentPos[0] + i);
Knight::currentPos[1] = (Knight::currentPos[1] + j);
counter++;
return counter;
*/
int main(){
Board b;
Knight k;
b.status[k.currentPos[0]][k.currentPos[1]] = k.counter;
b.print();
linkedList obj;
int coordinates;
}
So my idea at this point is to do the following:
Create a loop that will change the current position of the knight using the horizontal and vertical array (the possible moves of the knight). Once the position has changed, the counter will increment and the -1 will be replaced with the current counter value. When the knight has been moved, the information of the new coordinates needs to be passed to the linked list using the push function I created. In order to do this, I need to figure out a way to pass an array (x,y) or multiple values to push. I will also need to create some bound checking which I am currently working on (make sure the knight doesn't move to a spot that he has been to and doesn't go off the board). Then finally if the knight does get stuck, I need to use the pop function I created to go back a step and try to continue with a different move.
I really really appreciate any help, corrections, places to start or other suggestions that are given! I am so stuck..
Let me get this straight. You're having difficulty implementing the Stack structure that allows you to undo moves.
C++ isn't really my forte but here's how I'd approach the Stack
Define a struct that stores the coords (and possibly backtracking info)
Update 'node' to store a pointer to an instance of your new struct.
Update the 'push()' definition to use it.
Update the 'pop()' definition to return it.
Profit...