singly linked list simulated with dynamic arrays - c++

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.

Related

Multiple constructors in a C++ LinkedList class: non-class type "ClassName"

I have a LinkedList constructor where I can pass in an array and it builds. Then I can add additional nodes to it by passing in integers.
However, I also want the option to construct the LinkedList, without any arguments. In my LinkedList.h file I've tried to create a constructor that sets the first and last pointers. My add method should construct a Node.
But in my main() function, when I try to use this constructor, I get an error:
request for member ‘add’ in ‘l’, which is of non-class type ‘LinkedList()’
Same error for the other methods called in the main.cpp.
Where am I going wrong in how I structure my two constructors?
main.cpp
#include <iostream>
#include <string>
#include "LinkedList.h"
using namespace std;
int main()
{
//int A[] {1, 2, 3, 4, 5};
//LinkedList l(A, 5);
LinkedList l();
l.add(8);
l.add(3);
cout << l.getCurrentSize()<<endl;
l.display();
return 0;
}
LinkedList.h
#ifndef LINKED_LIST_
#define LINKED_LIST_
#include "IList.h"
class LinkedList: public IList
{
protected:
struct Node
{
int data;
struct Node *next;
};
struct Node *first, *last;
public:
//constructor
LinkedList(){first=nullptr; last=nullptr;}
LinkedList(int A[], int n);
//destructor
virtual ~LinkedList();
//accessors
void display();
virtual int getCurrentSize() const;
virtual bool add(int newEntry);
};
#endif
LinkedList.cpp
#include <iostream>
#include <string>
#include "LinkedList.h"
using namespace std;
//constructor
LinkedList::LinkedList(int A[], int n)
{
Node *t;
int i = 0;
first = new Node;
first -> data = A[0];
first -> next = nullptr;
last = first;
for(i = 1; i < n; i++) {
t = new Node;
t -> data = A[i];
t -> next = nullptr;
last -> next = t;
last = t;
}
};
//destructor
LinkedList::~LinkedList()
{
Node *p = first;
while (first) {
first = first -> next;
delete p;
p = first;
}
}
void LinkedList::display()
{
Node *p = first;
while(p) {
cout << p -> data << " ";
p = p -> next;
}
cout <<endl;
}
int LinkedList::getCurrentSize() const
{
Node *p = first;
int len = 0;
while(p) {
len++;
p = p -> next;
}
return len;
}
bool LinkedList::add(int newEntry)
{
Node *temporary;
temporary = new Node;
temporary -> data = newEntry;
temporary -> next = nullptr;
if (first==nullptr) {
first = last = temporary;
}
else {
last -> next = temporary;
last = temporary;
}
return true;
}
The problem has nothing to do with your constructors themselves.
LinkedList l(); is a declaration of a function named l that takes no arguments, and returns a LinkedList. That is why the compiler is complaining about l being a non-class type.
To default-construct a variable named l of type LinkedList, drop the parenthesis:
LinkedList l;
Or, in C++11 and later, you can use curly-braces instead:
LinkedList l{};

Define String Node in Linked List

#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;
}
}

C++: Implementing insert function for a linked list, prev_ptr ends up being NULL

node.h:
#ifndef NODE_H
#define NODE_H
#include <iostream>
namespace mdm{
class node{
public:
typedef int value_type;
node(const value_type& init_data = value_type(), node *init_link = NULL){
data = init_data;
link = init_link;
}
void setData(const value_type& newData){
data = newData;
}
void setLink(node *newLink){
link = newLink;
}
value_type getdata() const {
return data;
}
const node *linker() const {
return link;
}
node *linker(){
return link;
}
private:
value_type data;
node *link;
};
}
#endif // !node_h
linked_list.h:
#ifndef linked_list_h
#define linked_list_h
#include <iostream>
#include "node.h"
namespace mdislamwork_at_gmail_com{
class llist{
public:
llist(node *head = NULL){
head_ptr = head;
}
size_t list_length(const node *head_ptr);
void insert(const node::value_type& entry, size_t position);
void remove(node del);
void insert_to_head(node *&head_ptr, const node::value_type &entry);
private:
node *head_ptr;
};
}
#endif // !linked_list.h
linked_list.cpp:
#include <iostream>
#include "linked_list.h"
#include <assert.h>
using namespace std;
namespace mdm{
size_t llist::list_length(const node *head_ptr){
const node *cursor;
size_t count = 0;
for (cursor = head_ptr; cursor != NULL; cursor = cursor->linker()) {
count++;
}
return count;
}
void llist::insert(const node::value_type& entry, size_t position){
node* prev_ptr = head_ptr;
if (list_length(head_ptr) == 0)
insert_to_head(head_ptr, entry);
else{
assert(prev_ptr != NULL);
size_t count = 0;
while (count < position){
prev_ptr = prev_ptr->linker();
count++;
}
}
node *m_head_ptr;
assert(prev_ptr != NULL);
m_head_ptr = prev_ptr->linker();
insert_to_head(m_head_ptr, entry);
prev_ptr->setLink(m_head_ptr);
}
void llist::remove(node del){
}
void llist::insert_to_head(node *&head_ptr, const node::value_type &entry){
head_ptr = new node(entry, head_ptr);
}
}
main.cpp
#include <iostream>
#include "node.h"
#include "linked_list.h"
using namespace std;
using namespace mdm;
int main() {
node *head_ptr = NULL;
llist linked_list(head_ptr);
linked_list.insert_to_head(head_ptr, 44);
cout << linked_list.list_length(head_ptr) << endl;
linked_list.insert_to_head(head_ptr, 49);
cout << linked_list.list_length(head_ptr) << endl;
linked_list.insert(5,2);
//linked_list.insert(5, 2);
cout << linked_list.list_length(head_ptr) << endl;
return 0;
}
I posted the entirety of the code. I am having trouble inserting at an n-th position. For some reason in the insert implementation, the prev_ptr is NULL when it should have the memory address of where the new node will be placed.
Its hard to tell what the problem is what with head_ptr and its operations out of the scope of your posted method. What is head_ptr? A node*? a node? How are your nodes inserted initially? The scope of this method in relation to your problem is hard to understand.
Check to see if the head_ptr variable is null throughout the whole of your program. Is it always null? Does it become null? What other operations for your linked list have you implemented? Do they work ok? Its just really hard to tell what is wrong when you provide one method to an entire implementation.

Adding random numbers into a linked-list using loop

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.

Linked List Segmentation Fault

Why does this cause a SegFault Error? I've tried to run a backtrace with gdb, but it has given me no help.
Any help would be appreciated, I've been pulling my hair out over this for hours.
my node.h
#ifndef NODE_H
#define NODE_H
#include <string>
using namespace std;
class Node
{
public:
Node(const string, const int) ;
~Node() { }
void setNext(Node *);//setter for the next variable
Node * getNext();// getter for the next variable
string getKey();// getter for the key variable
int getDistance(); // getter for the dist variable
private:
Node *next;
int dist;
string key;
};
#endif
My Node.cpp
#include "node.h"
#include <string>
Node::Node(string k, int d){
key = k;
dist = d;
}
void Node::setNext(Node * n){
next = n;
}
Node * Node::getNext(){
return next;
}
string Node::getKey(){
return key;
}
int Node::getDistance(){
return dist;
}
My list.h
#ifndef LIST_H
#define LIST_H
#include "node.h"
class SLL
{
public:
SLL();
~SLL() { }
void Insert (string searchKey, int distance);
bool Delete (string searchKey);
void Print();
int Search(string searchKey);
private:
int count;
Node *head;
Node *iterator;
Node *temp;
};
#endif
my List.cpp
#include "list.h"
#include <iostream>
SLL::SLL():head(0){}
void SLL::Insert(string searchKey, int distance){
Node * temp = new Node(searchKey, distance);
if(head == 0){
head = temp;
}
else{
temp->setNext(head);
head = temp;
}
}
bool SLL::Delete(string searchKey){
if(head == 0){
cout << "An attempt was made to delete a node from an empty list" << endl;
}
else{
Node* iterator = head;
Node* last = 0;
while(iterator != 0){
if (iterator->getKey() == searchKey){
break;
}
else{
last = iterator;
iterator = iterator->getNext();
}
}
if (iterator == 0){
return false;
}
else{
if(head == iterator){
head = head->getNext();
}
else {
last->setNext(iterator->getNext());
}
delete iterator;
}
}
}
void SLL:: Print(){
iterator = head;
while(iterator != 0){
cout << iterator->getKey() << "-" << iterator->getDistance() << endl;
iterator = iterator->getNext();
}
}
int SLL::Search(string searchKey){
}
My main.cpp
#include "list.h"
#include "node.h"
#include <iostream>
using namespace std;
int main(int argc, char* argv[]) {
SLL * sll;
sll->Insert("test", 1);
sll->Insert("test2", 2);
sll->Delete("test");
sll->Print();
}
Hint: Segfault happens here:
int main(int argc, char* argv[]) {
SLL * sll;
sll->Insert("test", 1); // BIG segfault here.
...
(No full answers as this looks like homework.)
In your main function, the pointer to SSL is not initialised, but you dereference it. This is undefined behaviour. In your particular case, this is causing a segmentation violation. Try changing you code to create a SSL object, either on the stack:
int main(int argc, char* argv[]) {
SLL sll;
sll.Insert("test", 1);
// ...
}
or the heap:
int main(int argc, char* argv[]) {
SLL * sll = new SLL();
sll->Insert("test", 1);
// ...
}
BTW, you are never using the temp, iterator, ... fields of the SLL class, never initialise them. In your implementation, you define local variables that hide them, so I'd suggest removing the fields or initialising them in the constructor.