I want to add a completely random number into a linked-list, but instead of having all of my code in main, I want to use the object-oriented approach. I have my standard Node class and it's header, and then in main I want a loop that runs through 20 times and then stops adding more. I was given my insert function and how it would be called in main, but I can't seem to get the random numbers to work. I understand that you can't assign an int to a class, but I don't really know how else to incorporate my random number into my function in order to insert it into my list.
Here is my code. Observe the error on line 20 of main. Any insight would be great. Thanks!
Main.cpp
#include <iostream>
#include <iomanip>
#include <time.h>
#include "Node.h"
using namespace std;
int main()
{
srand(time(NULL));
Node link_head;
Node instance;
for (int i = 0; i < 20; i++)
{
int random = rand() % 100;
instance.insert(&link_head, &random);
}
}
Node.h
#include <iostream>
#include <iomanip>
#ifndef NODE_H
#define NODE_H
typedef int ElementType;
class Node
{
public:
Node();
ElementType data;
Node *next;
int insert(Node *, Node *);
};
#endif NODE_H
Node.cpp
#include <iomanip>
#include <iostream>
#include "Node.h"
using namespace std;
Node::Node()
{
this -> data = 0;
this -> next = NULL;
}
int Node::insert(Node *link_head, Node *newNode)
{
Node *current = link_head;
while (true)
{
if(current->next == NULL)
{
current->next = newNode;
break;
}
current = current->next;
}
return 0;
}
You are sending the address of an int to a function requiring a pointer on a Node. Allocate a new node first then send it to the function.
for (int i = 0; i < 20; i++)
{
int random = rand() % 100;
Node* newNode = new Node;
newNode->data = random;
instance.insert(&linkHead, newNode);
}
As stated, insert method should really be static of even a free function since it access only public members of the struct.
Your code is flawed in several ways.
instance.insert(&link_head, &random); &random doesn't point to a Node, thus the compiler error
int insert(Node *, Node *); should be static int insert(Node **, Node *); and used as follows
Node* head = NULL;
for (int i = 0; i < 20; i++)
{
Node* newNode = new Node;
newNode->data = rand() % 100;
Node::insert(&head, newNode);
}
Where the implementation looks like:
int Node::insert(Node** link_head, Node *newNode)
{
if(!link_head) {
return -1;
}
if(!(*link_head)) {
*link_head = newNode;
}
else {
newNode->next = (*link_head)->next;
(*link_head)->next = new_node;
}
return 0;
}
The difference is you use a head reference as an anchor for the linked list and you'll not have a useless instance that always needs to be sorted out from the actual values stored in the list.
Related
I was wondering if it would be possible to create a function that would create a linked list, here is my attempt, I would appreciate if anyone could tell me if this is correct or not.
The logic is as follows:
Take in a starting node, the created linked list will be connected to this node
Create all the nodes that need to be created and store their memory addresses in a vector
Loop through the vector linking together all of the nodes
#include <iostream>
#include <vector>
using namespace std;
class node{
public:;
int value;
node *next;
node():value(0),next(NULL){};
};
void CreateList(node& starting_node, int number_of_nodes_to_create){
// Keep track of all the nodes addresses that need to be created
vector <node*> nodes = {};
// Create the nodes
for (int i = 0; i < number_of_nodes_to_create;i++){
node *temp = new node;
nodes.push_back(temp);
}
// Attach the first created node to the starting node
starting_node.next = nodes[0];
// We now have all the new nodes, now we just need to link them all up with pointers
for (int i = 0; i < nodes.size()-1;i++){
nodes[i] ->next = nodes[i+1];
}
}
I am very much a beginner, all criticism is welcome!
You don't need the vector at all. Your function can be simplified to something like this:
#include <iostream>
#include <vector>
using namespace std;
class node{
public:
int value;
node *next;
node() : value(0), next(NULL) {}
};
void CreateList(node* &starting_node, int number_of_nodes_to_create){
// if the list already exists, find the end of it...
node **n = &starting_node;
while (*n) {
n = &((*n)->next);
}
// Create the nodes
while (number_of_nodes_to_create > 0) {
*n = new node;
n = &((*n)->next);
--number_of_nodes_to_create;
}
}
void DestroyList(node *starting_node) {
while (starting_node) {
node *n = starting_node->next;
delete starting_node;
starting_node = n;
}
}
int main() {
node* head = NULL;
CreateList(head, 5);
...
DestroyList(head);
}
Online Demo
Though, it is not usual for a list creation to take an existing node as input. Usually the creation should create the list and then return the 1st (head) node, eg:
#include <iostream>
#include <vector>
using namespace std;
class node{
public:
int value;
node *next;
node() : value(0), next(NULL) {}
};
node* CreateList(int number_of_nodes_to_create){
node *head = NULL, **n = &head;
while (number_of_nodes_to_create > 0) {
*n = new node;
n = &((*n)->next);
--number_of_nodes_to_create;
}
return head;
}
void DestroyList(node *head) {
while (head) {
node *n = head->next;
delete head;
head = n;
}
}
int main() {
node* head = CreateList(5);
...
DestroyList(head);
}
Online Demo
This is my first post on StackOverflow, as I am genuinely stuck.
My issue is that everytime I run the following code, at the first call for the function InsertNode(), the return temp node has the correct values for next node and data. However, when the function is called again, for some reasons the head gets reset to data NULL and next pointer recursively pointing to the same address. I'm having a hard time implementing this in OOP, I have done this using plain structs successfully. But with OOP I'm confused as how to declare the Node* Node::InsertNode(Node* head), method in main, as I get an error that InsertNode is undeclared. So as workaround I declared InsertNode outside of the Node class as an independent function. I have a feeling that is what may be causing the issue. would appreciate some help on what is going on or what I should change in my code. Thank you!
hashtable.cpp
#include "Hashtable.hpp"
using namespace std;
Node::Node(){
data = NULL;
Node* nextP = NULL;
};
Node::~Node(){
}
Node* InsertNode(Node* head, int data){
Node* temp = new Node();
if(head->nextP == NULL){
head->data = data;
temp->nextP = head;
head = temp;
} else if(head->nextP!=NULL){
temp->nextP = head;
temp->data = data;
head = temp;
}
return head;
};
void Node::printNode(Node* head){
Node* temp = new Node();
temp = head;
while(temp->nextP != NULL){
printf("%d\n", temp->data);
temp = temp->nextP;
}
}
Hashtable.hpp
#ifndef Hashtable_hpp
#define Hashtable_hpp
#include <stdio.h>
class Node
{
public:
Node* nextP;
Node();
~Node();
void printNode(Node* head);
int data = NULL;
private:
};
Node* InsertNode(Node* head, int data);
#endif /* Hashtable_hpp */
main.cpp
#include <iostream>
#include "stdio.h"
#include <string>
#include "Hashtable.hpp"
using namespace std;
Node head;
//Node* head = new Node();
int main(int argc, const char * argv[]) {
// insert code here...
std::cout << "Hello, World!\n";
head = *InsertNode (&head, 10);
// head = temp2;
head = *InsertNode (&head, 20);
// head = temp2;
head = *InsertNode (&head, 30);
// head = temp2;
//InsertNode(head, 20);
Node printNode(head);
return 0;
}
So I finally figured out the issue. Since initially I was referencing the class function InsertNode() directly, I was trying avoid the error that I was other getting with the undeclared identifier. So as a work around I moved the function outside of the class declaration, which then caused more problems as you saw above post. Now I realized that when the function exists inside the Class, I have reference it by first de-referencing (my terminology is probably wrong) the function using the following: head->InsertNode(head, data);
I was initially trying different iterations of InsertNode(&head, data) or Node* InsertNode(&head, data) ... etc. Basically trying to brute force my way through the compiler :).
I am attaching the code below, please let me know your comments on what I can improve.
Hashtable.cpp
#include "Hashtable.hpp"
#include <iostream>
using namespace std;
Node::Node(){
data = NULL;
Node* nextP = NULL;
};
Node::~Node(){
}
Node* Node::InsertNode(Node* head, int data){
Node* temp = new Node();
if(head->nextP == NULL){
head->data = data;
temp->nextP = head;
} else if(head->nextP!=NULL){
temp->nextP = head;
temp->data = data;
}
return temp;
};
void Node::printNode(Node* head){
Node* temp = new Node();
temp = head;
while(temp->nextP != NULL){
printf("%d\n", temp->data);
temp = temp->nextP;
}
}
Hashtable.hpp
#ifndef Hashtable_hpp
#define Hashtable_hpp
#include <stdio.h>
#include <iostream>
using namespace std;
class Node
{
int data = NULL;
Node* nextP;
public:
Node();
~Node();
Node* InsertNode(Node* head, int data);
void printNode(Node* head);
private:
};
#endif /* Hashtable_hpp */
main.cpp
#include <iostream>
#include "stdio.h"
#include <string>
#include "Hashtable.hpp"
using namespace std;
Node* head = new Node();
int main(int argc, const char * argv[]) {
// insert code here...
std::cout << "Hello, World!\n";
Node temp2;
head = head->InsertNode (head, 10);
head = head->InsertNode (head, 20);
head = head->InsertNode (head, 30);
head = head->InsertNode (head, 40);
head = head->InsertNode (head, 50);
head = head->InsertNode (head, 60);
head = head->InsertNode (head, 70);
head->printNode(head);
return 0;
#include<iostream>
#include<stdlib.h>
#include<conio.h>
#include <ctime>
#include <fstream>
#include <windows.h>
#include <string>
using namespace std;
/* data variable is used to store data as name
suggests,the "next" is a pointer of the type node
that is used to point to the next node of the
Linked List*/
/*
* Node Declaration
*/
struct node
{
string info;
struct node *next;
}*start;
/*
* Class Declaration
*/
class single_llist
{
public:
node* create_node(string);
void insert_begin();
void insert_pos();
void insert_last();
void delete_pos();
void sort();
void search();
void update();
void reverse();
void display();
single_llist()
{
start = NULL;
}
};
/*
* Inserting element in beginning
*/
void single_llist::insert_begin()
{
string value;
cout<<"Enter the value to be inserted: ";
cin>>value;
struct node *temp, *p;
temp = create_node(value);
if (start == NULL)
{
start = temp;
start->next = NULL;
}
else
{
p = start;
start = temp;
start->next = p;
}
cout<<"Element Inserted at beginning"<<endl;
}
I'm developing my program with Dev C ++ program.I trying to entering specific words to txt file and save them.Therefore I'm dealing with string.The program gives this error: undefined reference to single_llist::create_node(std::string) and showing me that there is mistake here, temp = create_node(value);I still researching what I need to do for solving this problem?
Thanks for #NathanOliver I think I tried to wrong way without creating node first.For creating node check following code fragment.
/*
* Creating Node
*/
node *single_llist::create_node(string value)
{
struct node *temp, *s;
temp = new(struct node);
if (temp == NULL)
{
cout<<"Memory not allocated "<<endl;
return 0;
}
else
{
temp->info = value;
temp->next = NULL;
return temp;
}
}
Good Evening! I am trying to create a C++ Linked List that will create a random number & store randoms in 100 nodes. I haven't gotten any errors in the code I created but when I run the program, the output loops the number "42" to the point where I have to terminate the program. Please help. The code is below.
#include <iostream>
#include <stdlib.h>
using namespace std;
struct Node{
int xdata;
Node* next;
};
struct Node *head;
void insert_node(int y)
{
Node* temp = new Node;
temp-> xdata = y;
temp-> next = NULL;
if(head==NULL)
{
head=temp;
}
else{
temp->next=head;
head=temp;
}
};
int main(){
int z =rand()%100 + 1;
for(int i=0; i<100; i++)
{
insert_node(z);
}
while(head!=NULL)
{
cout<<head->xdata<<" "<<endl;
}
return 0;
}
You need to advance your head pointer.
while(head!=NULL)
{
cout<<head->xdata<<" "<<endl;
head = head->next;
}
my code is suppose to create a singly linked list using and array of nodes.
each Node has variable item which hold data and variable next which holds the index of the next node in the list. the last node has -1 in its next data field to simulate a nullptr. head holds the index of the first node in the list.
for some reason when i create a pointer to point to a certain node in the array it it gives the following error:
error: cannot convert 'Node' to 'Node*' in initialization|
#include "ArrayList.h"
#include <iostream>
using namespace std;
ArrayList::ArrayList(char ch){
array = new Node[Size];
(array[0]).item = ch;
(array[0]).next = 1;
free = 1;
head = 0;
}
int ArrayList::length() const{
if (head == -1) return 0;
int counter =0;
Node* current = array[head]; // problem occurs here
while(current->next != -1 ){
counter++;
int index = current->next;
current = current[index];
}
counter++;
return counter;
}
////////////////////
#ifndef ARRAYLIST_H
#define ARRAYLIST_H
#include <iostream>
using namespace std;
class Node{
public:
char item;
int next;
Node(){
next = -1;
}
Node(char input){
this->item = input;
next = -1;
}
};
class ArrayList{
public:
ArrayList();
ArrayList(char ch);
Node& operator[](int index);
int length() const;
char getFirst() const;
void print() const;
private:
Node* array;
int Size = 5;
int head = -1;
int free = 0;
};
#endif
////////////////////////
#include <iostream>
#include "ArrayList.h"
using namespace std;
int main(){
ArrayList list('1');
list.print();
return 0;
}
current should be an int or a size_t, since the code is using indices instead of pointers. Since it's an array, you can only use new for a one time allocation of a fixed maximum size, if this is to be similar to std::array.