Array Of Linked Lists (5 Queues) - c++

I would like to implement an array of linked lists to create a printing queue; with an array of five queues. Each queue is meant to represent a user printing a job sent to the printer.
This is the code I currently have:
#include "stdafx.h"
#include <iostream>
using namespace std;
struct node
{
float value;
struct node *next;
};
node *head = NULL;
node* A[5];
int insertNodes(node *head, int value)
{
node *aNode, *Ptr;
aNode = new node;
aNode->value = value;
aNode->next = NULL;
if (head == NULL)
head = aNode;
else
{
Ptr = head;
while (Ptr->next != NULL)
Ptr = Ptr->next;
Ptr->next = Ptr;
}
return head;
}
int _tmain(int argc, _TCHAR* argv[])
{
int num;
for (int i = 0; i < 5; i++)
{
cout << "Insert number";
cin >> num;
A[i] = insertNodes(i, num)
}
return 0;
}
This code does not work as intended, as I am unable to add "jobs" to the queues.
Where have I gone wrong?

There is a number of issues with your code:
You are programming in C++, not C, so instead of struct node *next you should simply write node *next.
Your insertNodes function returns a pointer to the head of the list, so you need to return node*, not int.
When you insert into a list with an existing head, you never insert the item. You have to do Ptr->next = aNode, not Ptr->next = Ptr.
In your main function, you are expected to pass a pointer to the head of the list to insertNodes, but you actually pass it an int. Instead, try A[i] = insertNodes(A[i], num).
You store float in your list nodes, but input int - is that actually desired?
However, since you are in C++, you can probably avoid most of these pitfalls entirely by relying on what the standard library already provides.
Simply #include <deque> and you can use everything that std::deque (a double-ended queue) provides, including push_back to add elements at the end, front to access the first element, and pop_front to remove it - a real queue, no need for custom linked lists:
#include "stdafx.h"
#include <deque>
#include <vector>
#include <iostream>
std::vector<std::deque<float>> A {5};
int _tmain(int argc, _TCHAR* argv[])
{
float input;
for (int i = 0; i < 5; i++)
{
std::cout << "Insert number: ";
std::cin >> input;
A[i].push_back(input);
}
return 0;
}

Related

How can I assign an int array to linkedlist struct?

Hi I'm a beginner at c++ and I'm having trouble solving this issue. I have a linkedlist of nodes and the node contains data of int array and a pointer pointing to the next node.
struct node {
unsigned int numbers[6];
node* next;
};
I also have a class:
private:
ticket* ticketListHead;
ticket* ticketListTail;
and in a public method:
public:
void newNode() {
int arr[6];
for(int i = 0; i < 6; ++i) {
arr[i] = ( std::rand() % 49 ) + 1;
}
node *temp = new node;
temp->numbers=arr;
temp->next=NULL;
}
The problem I believe is with the temp->numbers=arr line as I believe arrays cannot be assigned like that in C++. I'm not sure how to solve the problem in this case and I've tried looking online. Some help would be appreciated!
You're correct about your suspicion that you cannot assign arrays. You could instead use a wrapper type that allows assignment and define
using array = std::array<unsigned,6>; // convenient short hand
struct node {
array numbers;
node* next = nullptr; // ensure next defaults to null
};
when your newNode() method may look like
node* newNode() {
array arr;
for(auto&x: arr)
x = ( std::rand() % 49 ) + 1; // std::rand() cannot be recommended
auto temp = new node;
temp->numbers = arr;
return temp;
}
but you can avoid the temporary object arr altogether by directly writing into the new node's data:
node* newNode() {
auto temp = new node;
for(auto&x: temp->numbers)
x = ( std::rand() % 49 ) + 1; // std::rand() cannot be recommended
return temp;
}
Btw, you shouldn't use std::rand() (see this post and this presentation for reasons why). Instead, use the methods provided by <random>, when your code becomes (see also this answer)
template<typename Generator>
node* newNode(Generator&rng) {
std::uniform_int_distribution<unsigned> uni(1,49);
auto temp = new node;
for(auto&x: temp->numbers)
x = uni(rng); // guaranteed unbiased in [1,49] inclusive
return temp;
}
Welcome to C++, it's awesome that you're taking your first steps into a brighter world! What you'll want to look into are C++ container classes, they'll get you out of the business of managing memory on your own. The closest to your code is std::list and std::vector. I'll neglect random number seeding, that's a complex topic better discussed elsewhere.
#include <vector>
#include <list>
#include <iostream>
#include <random>
#include <limits>
using namespace std;
struct node {
node() : num(6) {
numbers.reserve(num);
for (int i = 0; i < num; ++i)
numbers.push_back(random() % numeric_limits<int>::max());
}
vector<int> numbers;
const int num;
};
int main(int argc, char** argv) {
list<node> nodes;
nodes.push_back(node()); // this replaces your newNode function
nodes.push_back(node()); // another call to better illustrate
for (auto mynode : nodes) {
for (auto mynum : mynode.numbers)
cout << mynum << " ";
cout << endl;
}
}
// Change node struct to this
struct node{
unsigned int *numbers;
node* next;
};
/*
Remember that normal arrays are
implemented through pointers. So you
can use a pointer named numbers in
your node struct and it would behave
as an array.
*/
// Change newNode() to this
void newNode() {
int * arr = new int[6]; //Dynamic memory allocation
for(int i = 0; i < 6; ++i)
{
arr[i] = ( std::rand() % 49 ) + 1;
}
node *temp = new node;
temp->numbers = arr;
temp->next = NULL;
}
U got it ?

Why does this code crash using pointers in map c++ in this implementation of Trie?

#include <iostream>
#include <vector>
#include <map>
#include <utility>
#include <iterator>
using namespace std;
class Node
{
public:
map<char,Node*> characters;
bool endOfWord = false;
Node()
{
}
Node(bool endOfWordBool)
{
this->endOfWord = endOfWordBool;
}
};
class Trie
{
public:
Node* root = nullptr;
Trie()
{
this->root = new Node();
}
This function is the problem here.
Using next node that i set in each iteration crashes does the map stl doesn't support having pointers to object inside?
void insertWord(string word)
{
Node* currentNode = this->root;
for(unsigned int i = 0; i < word.length(); i++)
{
/// character is not in the map
if(currentNode->characters.find(word[i]) !=
currentNode->characters.end())
{
cout << "before create" << endl;
Node* nextNode = new Node();
currentNode->characters.insert(pair<char,Node*>(word[i],
nextNode));
currentNode = currentNode->characters.find(word[i])->second;
}
/// character is in the map
else
{
currentNode = currentNode->characters.find(word[i])->second;
}
}
currentNode->endOfWord = true;
}
};
int main()
{
Trie* t = new Trie();
string s = "ahmed";
t->insertWord(s);
return 0;
}
It crashes in the insertion using the set next Node. any Help? And is it a better convention to use pointers in this case or to put the object in the map?
The issue is that your code does the wrong comparison to see if the element in the map exists.
This:
if (currentNode->characters.find(word[i]) != currentNode->characters.end())
should be:
if (currentNode->characters.find(word[i]) == currentNode->characters.end())
By using the wrong comparison, you wind up using an uninitialized pointer.
This also demonstrates that comments can lie what the code does -- the only thing that is the truth is the code. I'm referring to this comment right before the incorrect code:
/// character is not in the map
and of course the code does not determine if the character is not in the map. It actually tests if the character is in the map.

C++ program ends for no reason ? (Hash table)

I'm trying to implement hash table with Separate chaining collision resolution and I have a problem.
This is my code (little modified to simplify, but error still same):
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <fstream>
#include <cstring>
#include <string>
using namespace std;
int ascii(char character)
{
return character;
}
int hashFunction(string word, int num)
{
char* str = new char[word.length() + 1];
strcpy(str, word.c_str());
return ((3 * ascii(str[0]) + 5 * ascii(str[1]))) % num;
}
typedef struct tab
{
string data;
struct tab* next;
}Node;
typedef struct link
{
Node* head;
Node* tail;
}List;
List* createList()
{
List* list = new List();
if (list)
{
list->head = NULL;
list->tail = NULL;
}
return list;
}
void insert(List* list, string data)
{
//if list is empty
if (list->head == NULL) //!!!!!!!!!!!!!!!!ERROR OCCURE HERE !!!!!!!!!!!!!!!
{
list->head = new Node();
list->head->data = data;
list->head->next = NULL;
list->tail = list->head;
}
//if list already contains some data
else
{
list->tail->next = new Node();
list->tail->next->data = data;
list->tail = list->tail->next;
list->tail->next = NULL;
}
}
int main(int argc, char* argv[])
{
int size = 8; //Size of hash table (number of indexes)
List* table[12];
string A[8] = { "hello","world","car","notebook","science","starwars","lollypop","anything" };
//Insert elements from array A into a hash table
int index;
for (int i = 0; i < size; i++)
{
index = hashFunction(A[i], size);
if (table[index] == NULL)
table[index] = createList();
insert(table[index], A[i]);
}
return 0;
}
When I run the .exe file (or start from cmd), program ends up with message that app.exe has stopped working. I tried debug the program and got this:
http://imgur.com/a/yOhRV
Can anyone help me how to fix this? I've figured out problem must be in insert() function, probably in the condition, but I don't know what is wrong.
you derefernce a pointer without checking it: if (list->head == NULL)...
What you are doing here, is taking list and cheking if the value pointed by it is NULL, but since you haven't checked if (list) then it's possible that list == NULL and that causes segfault when dereferencing it
You are declaring List* table[12] but it is never initialized. So it does contain garbage.
You have to do the following in order to initialize it: List* table[12] = {NULL};
As a general rule you should never have uninitialized variables in your code (unless for optimization purposes when you know exactly what you are doing).
Add default contructors to your structs and make use of initialization list. Also keep you variables as local as possible (move index inside the loop).
You don't need ascii() cause char is integer type. char+char and char*int get promoted to int.

Insert 'n' nodes in a linked list and print their data (C++)

I don't understand what's wrong with my code here:
//Inserting n nodes, then print their values
#include <iostream>
#include <string>
using namespace std;
//Defining a node and it's head pointer
struct node
{
int data;
node *next;
};
node *head=NULL;
node *link;
node *tmp;
int main()
{
int n;
cin>>n;
while (n>0)
{
//Insert n nodes into the list
link=new node;
if (head==NULL)
{
head=link;
}
cin>>link->data;
link=link->next;
n--;
}
link=NULL;
//print data present in those n nodes
tmp=head;
while (tmp!=NULL)
{
cout<<tmp->data;
tmp=tmp->next;
}
return 0;
}
The first part of the code defines a node.
The second part (beginning of main function) is code for creating a linked list with n nodes in it. So I insert n nodes.
Finally, I output them using the pointer tmp. However, instead of getting the data values, I just get an infinite loop. What is going on here?
Thanks
#include <iostream>
#include <string>
using namespace std;
//Defining a node and it's head pointer
struct node
{
int data;
node *next=NULL;
};
node *head=NULL;
node *link;
node *tmp;
int main()
{
int n,limit;
cin>>n;
limit=n;
while (n>0)
{
tmp=link;
link=new node;
link->next=NULL;
cin>>link->data;
if (head==NULL)
{
head=link;
}
if(n!=limit) //check whether tmp is null initially tmp will be null for first element
{
tmp->next=link;
}
n--;
}
//print data present in those n nodes
tmp=head;
while (tmp!=NULL)
{
cout<<tmp->data<<"\n";
tmp=tmp->next;
}
return 0;
}
This code does what you want using std::list. I don't see why you should go on create your own crude and unsafe linked list. (I don't even see why you should use a linked list; in this particular a std::vector would be a more reasonable choice).
#include <iostream>
#include <list>
int main() {
std::list<int> linked_list;
// fill the list
std::cout << "Please enter the number of elements in the list: " << std::endl;
int n {};
std::cin>>n;
while (n-- > 0) {
std::cout << "Please enter the data for this item: " << std::endl;
int data {};
std::cin>>data;
linked_list.push_back(data);
}
// print out data the list
for (auto& data : linked_list)
std::cout << "printing data entry: " << data << std::endl;
return 0;
}
First of all it is c++. I recommend to use std::list:
#include <iostream>
#include <list> // list
int main()
{
int n;
std::cin >> n;
std::list<int> l;
while ( l.size() < n )
{
int data;
std::cin >> data;
l.push_back( data );
}
for ( int data : l )
std::cout << data << std::endl;
return 0;
}
But if you want to di it yourself you have to remember the tail of your list and add each new node as successor of the tail node. Further you should delete the list at the end of your program:
#include <iostream>
struct node
{
int data;
node *next;
};
node *head = NULL;
int main()
{
int n;
std::cin >> n;
node *tail = NULL;
while ( n>0 )
{
node *link = new node;
link->next = NULL; // successor of new node is NULL
std::cin >> link->data;
if ( head==NULL)
head = link; // if list is empty new node is head of list
else
tail->next = link; // successor of tail is new node
tail = link;
n--;
}
node *tmp = head;
while ( tmp != NULL) // delete the list from head to tail
{
std::cout << tmp->data << std::endl;
tmp = tmp->next;
}
while ( head != NULL)
{
tmp = head->next;
delete head;
head = tmp;
}
return 0;
}

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.