Double pointers - c++

I'm struggling with the following code. I want to create a linked list and keep track of its head. However, when I assign a pointer to the first node created, I am able to access only the first node's data value, and not its next nodes.
ie) the code below produces
0
Why won't it print out all values in the linked list ( 0 - 4 ) ?
#include <iostream>
using namespace std;
struct node
{
int val;
node * next = nullptr;
node(int a)
{
val = a;
}
};
node * t = nullptr;
node * temp;
int main(int argc, const char * argv[])
{
for (int i = 0; i < 5; i++)
{
t = new node (i);
if (i ==0)
{
temp = t;
}
t = t->next;
}
while (temp!=nullptr)
{
cout << (temp)->val;
temp = (temp)->next;
}
return 0;
}

During the creation of the list you need to keep track of the node created previously and set the next pointer of that node to the node you just created.
You probably want this:
int main(int argc, const char * argv[])
{
node *head;
node *previous = NULL;
for (int i = 0; i < 5; i++)
{
node *t = new node(i);
if (i == 0)
{
head = t;
}
if (previous != nullptr) // if not first node
{
previous->next = t; // set next of previous node to current node
}
previous = t;
}
node *temp = head;
while (temp != nullptr)
{
cout << temp->val << endl;
temp = temp->next;
}
return 0;
}
The overall design of this code is still poor but it sticks as closely as possible to the original code.
Output:
0
1
2
3
4

Related

Deleting duplicate elements in a list in c++ [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 4 years ago.
Improve this question
I have a task to delete any duplicate elements from a list. I am using a struct and pointers for my functions. Here is the struct and the function:
struct node
{
int key;
node *next;
}*start = NULL;
int SIZE = 0;
Where size increments when an item is added. There is the function for deleting duplicates:
void del_dup()
{
if (!start) {
return;
}
if (SIZE == 1) {
return;
}
node * pointer = start->next;
node * prev = start;
node * mPointer = nullptr;
node * mPrev = nullptr;
for (int i = 0; i < SIZE - 1; i++)
{
if (pointer->next)
{
mPointer = pointer->next;
mPrev = pointer;
}
for (int j = i + 1; j <= SIZE; j++)
{
if (pointer->key == mPointer->key)
{
mPrev->next = mPointer->next;
delete mPointer;
}
else
{
mPrev = mPointer;
mPointer = mPointer->next;
}
}
prev = pointer;
pointer = pointer->next;
}
}
The thing is I get a crash at the if statement to compare if the two elements match:
if (pointer->key == mPointer->key)
The error is access violation type and nullptr for mPointer.
The list is filled from the user every time he runs the program with the values he wants. Here is the push function:
void push_start(int n) {
elem *p = start;
start = new elem;
start->key = n;
start->next = p;
SIZE++;
}
Any help to fix this would be appreciated. Thanks in forward!
For starters it is a bad idea to declare the variable SIZE outside the structure definition. In this case all functions that deal with the list will suffer from accessing to the global variable. You can not have more than one list in the program.
You could "wrap" the structure node in one more structure as for example
struct node
{
int key;
node *next;
};
struct list
{
node *head;
size_t /*int*/ size;
};
In this case each list would have its one data member size.
The function del_dup looks very confusing and you are using confusing names as for example pointer and mPointer. You should not rely on the variable SIZE that shall be decremented when a node is deleted.
I can suggest the following function implementation.
#include <iostream>
#include <cstdlib>
#include <ctime>
struct node
{
int key;
node *next;
} *head = nullptr;
size_t size;
void push_front( node * &head, int key )
{
head = new node { key, head };
++size;
}
std::ostream & display_list( node * head, std::ostream &os = std::cout )
{
os << size << ": ";
for ( const node *current = head; current; current = current->next )
{
os << current->key << ' ';
}
return os;
}
void del_dup( node * head )
{
for ( node *first = head; first; first = first->next )
{
for ( node *current = first; current->next; )
{
if ( current->next->key == first->key )
{
node *tmp = current->next;
current->next = current->next->next;
delete tmp;
--size;
}
else
{
current = current->next;
}
}
}
}
int main()
{
const size_t N = 10;
std::srand( ( unsigned int )std::time( nullptr ) );
for ( size_t i = 0; i < N; i++ )
{
push_front( head, std::rand() % ( int )N );
}
display_list( head ) << std::endl;
del_dup( head );
display_list( head ) << std::endl;
return 0;
}
The program output might look like
10: 2 2 3 3 8 5 6 2 6 1
6: 2 3 8 5 6 1
At a guess, you're at some point comparing keys with an already deleted node. For example, you're assigning mPointer = pointer->next, then possibly deleting mpointer, then at the end of the inner loop assigning pointer = pointer->next. So wouldn't it be possible for pointer->next to have already been deleted there?
Edit
Acutally it's much more likely that your inner loop condition is the problem. Try just:
for (int j = i + 1; j < SIZE; j++)
instead.

Inserting node to linked list only goes to beginning or end

I've confused myself with this code. I want to insert the node with name "Joshua" into my linked list after the node with "James". However, I have it wrong and it only adds it to the beginning or end of the list based on the integer value in "insert("Joshua", 2);"
#include <string>
#include <iostream>
using namespace std;
struct Node
{
string name;
Node *link;
};
typedef Node* NodePtr;
NodePtr listPtr, tempPtr;
void insert(string name, int n)
{
NodePtr temp1 = new Node();
temp1->name = name;
temp1->link = NULL;
if(n == 1){
temp1->link = listPtr;
listPtr = temp1;
return;
}
NodePtr temp2 = listPtr;
for(int i = 0; i < n; i++){
temp2 = temp2->link;
}
temp1->link = temp2->link;
temp2->link = temp1;
}
void print()
{
NodePtr temp = listPtr;
while(temp != NULL)
{
cout << temp->name << endl;
temp = temp->link;
}
}
/*
*
*/
int main(int argc, char** argv){
listPtr = new Node;
listPtr->name = "Emily";
tempPtr = new Node;
tempPtr->name = "James";
listPtr->link = tempPtr;
tempPtr->link = new Node;
tempPtr = tempPtr->link;
tempPtr->name = "Joules";
tempPtr->link = NULL;
print();
insert("Joshua", 2);
cout << endl;
print();
return 0;
}
for(int i = 0; i < n; i++){
temp2 = temp2->link;
}
if n=2 and you have 3 elements in the linked list, at the end of the above loop, you will be at the last node.Then the below will add the new node at the end.
temp1->link = temp2->link;
temp2->link = temp1;
You want to run the loop 1 less time.

I have a program that works for whole numbers, but I need to get it to work for decimal numbers as well

So my assignment requires us to use doubly linked lists to add or multiply numbers together and print them out. I was able to get it to work for whole numbers, but I can't figure out what to change to make it work for decimal numbers as well. Here's what I've got so far. I know it's not the most efficient or cleanest code, but I can try to clarify stuff if it doesn't make sense to you
For example this program will work fine if I do 50382+9281 or 482891*29734,but I need to get it to work for something like 4.9171+49.2917 or 423.135*59
EDIT: Pretend the int values are doubles. I changed it on my actual code, but the result when I do the math is still giving me a whole number so I need to figure out how to insert the decimal at the right place
#include <iostream>
#include <fstream>
#include <string>
#include <stdio.h>
#include <cstdlib>
#include <cstring>
using namespace std;
// A recursive program to add two linked lists
#include <stdlib.h>
#include <assert.h>
#include <math.h>
#include <string.h>
// A linked List Node
struct node
{
int data;
node* next;
node *prev;
};
typedef struct node node;
class LinkedList{
// public member
public:
// constructor
LinkedList(){
int length = 0;
head = NULL; // set head to NULL
node *n = new node;
n->data = -1;
n->prev = NULL;
head = n;
tail = n;
}
// This prepends a new value at the beginning of the list
void addValue(int val){
node *n = new node(); // create new Node
n->data = val; // set value
n->prev = tail; // make the node point to the next node.
// head->next = n;
// head = n;
// tail->next = n; // If the list is empty, this is NULL, so the end of the list --> OK
tail = n; // last but not least, make the head point at the new node.
}
void PrintForward(){
node* temp = head;
while(temp->next != NULL){
cout << temp->data;
temp = temp->next;
}
cout << '\n';
}
void PrintReverse(){
node* temp = tail;
while(temp->prev != NULL){
cout << temp->data;
temp = temp->prev;
}
cout << '\n';
}
void PrintReverse(node* in){
node* temp = in;
if(temp->prev== NULL){
if(temp->data == -1)
cout << temp->data << '\n';
}
else{
cout << temp->data << '\n';
temp = temp->prev;
PrintReverse(temp);
}
}
// returns the first element in the list and deletes the Node.
// caution, no error-checking here!
int popValue(){
node *n = head;
int ret = n->data;
head = head->next;
delete n;
return ret;
}
void swapN(node** a, node**b){
node*t = *a;
*a = *b;
*b = t;
}
node *head;
node *tail;
// Node *n;
};
/* A utility function to insert a node at the beginning of linked list */
void push(struct node** head_ref, int new_data)
{
/* allocate node */
struct node* new_node = (struct node*) malloc(sizeof(struct node));
/* put in the data */
new_node->data = new_data;
/* link the old list off the new node */
new_node->next = (*head_ref);
/* move the head to point to the new node */
(*head_ref) = new_node;
}
/* A utility function to print linked list */
void printList(struct node *node)
{
while (node != NULL)
{
printf("%d", node->data);
node = node->next;
}
// printf("\n");
}
// A utility function to swap two pointers
void swapPointer( node** a, node** b )
{
node* t = *a;
*a = *b;
*b = t;
}
/* A utility function to get size of linked list */
int getSize(struct node *node)
{
int size = 0;
while (node != NULL)
{
node = node->next;
size++;
}
return size;
}
// Adds two linked lists of same size represented by head1 and head2 and returns
// head of the resultant linked list. Carry is propagated while returning from
// the recursion
node* addSameSize(node* head1, node* head2, int* carry)
{
// Since the function assumes linked lists are of same size,
// check any of the two head pointers
if (head1 == NULL)
return NULL;
int sum;
// Allocate memory for sum node of current two nodes
node* result = (node *)malloc(sizeof(node));
// Recursively add remaining nodes and get the carry
result->next = addSameSize(head1->next, head2->next, carry);
// add digits of current nodes and propagated carry
sum = head1->data + head2->data + *carry;
*carry = sum / 10;
sum = sum % 10;
// Assigne the sum to current node of resultant list
result->data = sum;
return result;
}
// This function is called after the smaller list is added to the bigger
// lists's sublist of same size. Once the right sublist is added, the carry
// must be added toe left side of larger list to get the final result.
void addCarryToRemaining(node* head1, node* cur, int* carry, node** result)
{
int sum;
// If diff. number of nodes are not traversed, add carry
if (head1 != cur)
{
addCarryToRemaining(head1->next, cur, carry, result);
sum = head1->data + *carry;
*carry = sum/10;
sum %= 10;
// add this node to the front of the result
push(result, sum);
}
}
// The main function that adds two linked lists represented by head1 and head2.
// The sum of two lists is stored in a list referred by result
void addList(node* head1, node* head2, node** result)
{
node *cur;
// first list is empty
if (head1 == NULL)
{
*result = head2;
return;
}
// second list is empty
else if (head2 == NULL)
{
*result = head1;
return;
}
int size1 = getSize(head1);
int size2 = getSize(head2) ;
int carry = 0;
// Add same size lists
if (size1 == size2)
*result = addSameSize(head1, head2, &carry);
else
{
int diff = abs(size1 - size2);
// First list should always be larger than second list.
// If not, swap pointers
if (size1 < size2)
swapPointer(&head1, &head2);
// move diff. number of nodes in first list
for (cur = head1; diff--; cur = cur->next);
// get addition of same size lists
*result = addSameSize(cur, head2, &carry);
// get addition of remaining first list and carry
addCarryToRemaining(head1, cur, &carry, result);
}
// if some carry is still there, add a new node to the fron of
// the result list. e.g. 999 and 87
if (carry)
push(result, carry);
}
node* reverse_list(node *m)
{
node *next = NULL;
node *p = m;
node *prev;
while (p != NULL) {
prev = p->prev;
p->prev = next;
next = p;
p = prev;
}
return prev;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void Multiply2(node* n1, node* n2);
int digitsPerNode = 2;
node* result;
node* resultp = result;
node* resultp2 = result;
void Multiply(node* n1, node* n2)
{
if (n2->prev != NULL)
{
Multiply(n1, n2->prev);
}
Multiply2(n1, n2);
resultp2 = resultp = resultp->prev;
}
void Multiply2(node* n1, node* n2)
{
if (n1->prev != NULL)
{
Multiply2(n1->prev, n2);
}
if (resultp2 == NULL)
{
resultp2->data = 0;
result = resultp = resultp2;
}
int m = n1->data * n2->data + resultp2->data;
int carryon = (int)(m / pow(10, digitsPerNode));
resultp2->data = m % (int)pow(10, digitsPerNode);
if (carryon > 0)
{
if (resultp2->prev == NULL)
{
resultp2->prev->data = carryon;
}
else
{
resultp2->prev->data += carryon;
}
}
resultp2 = resultp2->prev;
}
/* int* buffer;
int lenBuffer = 0;
void multiplyHelper(int v, node* , int o);
void addToBuffer(int v, int i);
node* multiply(node* num1, node* num2)
{
if (num1 == NULL || num2 == NULL) return NULL;
int length1 = getSize(num1);
int length2 = getSize(num2);
if (length1 > length2) return multiply(num2, num1);
// initialize buffer
lenBuffer = length1 + length2;
buffer = new int[lenBuffer];
memset(buffer, 0, sizeof(int) * lenBuffer);
// multiply
int offset = 0;
node* anode = num1;
while (anode && anode->data!= -1)
{
multiplyHelper(anode->data, num2, offset);
anode = anode->prev;
offset++;
}
// transfer buffer to a linked list
node* h;
int pos = 0;
while (pos < lenBuffer && buffer[pos] == 0) pos++;
if (pos < lenBuffer)
{
node* temp;
temp->data = buffer[pos++];
h = temp;
anode = h;
while (pos < lenBuffer)
{
node* temp;
temp->data = buffer[pos++];
anode->prev = temp;
anode = anode->prev;
}
}
delete buffer;
lenBuffer = 0;
buffer = NULL;
cout << h->data << endl;
return h;
}
// multiply a single digit with a number
// called by multiply()
void multiplyHelper(int value, node* head, int offset)
{
// assert(value >= 0 && value <= 9 && head != NULL);
if (value == 0) return;
node* anode = head;
int pos = 0;
while (anode != NULL)
{
int temp = value * anode->data;
int ones = temp % 10;
if (ones != 0) addToBuffer(ones, offset + pos + 1);
int tens = temp / 10;
if (tens != 0) addToBuffer(tens, offset + pos);
anode = anode->prev;
cout << anode->data;
pos++;
}
}
// add a single digit to the buffer at place of index
// called by multiplyHelper()
void addToBuffer(int value, int index)
{
// assert(value >= 0 && value <= 9);
while (value > 0 && index >= 0)
{
int temp = buffer[index] + value;
buffer[index] = temp % 10;
value = temp / 10;
index--;
}
}*/
// Driver program to test above functions
int main(int argc, char *argv[])
{
char filename[50];
string name= argv[1];
string dig;
name.erase(0,9);//Parse input to only get input file.
ifstream file;
int digits;
for(int i = 0; i < name.length(); i++){
if(name.at(i) == ';'){
// dig = name.substr(0,name.length()-i);
name = name.substr(0,name.length()-i);
}
}
//cout << dig << endl;
//file.open("input.txt");
file.open(name.c_str());
digits = 2;
///////
///////////////////////////////////////////////////////////////////////
int words = 0;
int numbers = 0;
while(!file.eof()) //Goes through whole file until no more entries to input
{
string word;
getline(file,word); //Inputs next element as a string
// word << file;
//cout << word << '\n';
int x = 0;
node *head1 = NULL, *head2 = NULL, *result = NULL;
int counter = 0;
int t1index = 0; //keep tracks of nodes to multiply
int t2index = 0;
char operatorX;
LinkedList tempList1;
LinkedList tempList2;
while(x<word.length()) //Loops through each string input
{
//if(x<word.length()&&isalpha(word.at(x))) //Checks that x is in bounds and that char at position x is a letter
if(x<word.length()&&isdigit(word.at(x))) //Checks that x is in bounds and that char at position x is a number/digit
{
int start = x;
while(x<word.length()&&isdigit(word.at(x))) //Loops past the number portion
{
x++;
}
string temp = word.substr(start, x).c_str();
// cout << temp << '\n';
for(int i = 0; i < temp.length();i++){
tempList1.addValue(atoi(temp.substr(i, 1).c_str()));
// push(&head1, atoi(temp.substr(i, 1).c_str()));
counter++;
t1index++;
}
//search for the operator
while(x<word.length()){
if(x<word.length()&& (!isspace(word.at(x)) && !isdigit(word.at(x))))
{
while(x<word.length()&&(!isspace(word.at(x)) && !isdigit(word.at(x)))) //Loops past the letter portion
{
// cout << (word.at(x))<< '\n';
operatorX = word.at(x);
x++;
}
//search second value
while(x<word.length()){ //second value find
//start
if(x<word.length()&&isdigit(word.at(x))) //Checks that x is in bounds and that char at position x is a number/digit
{
int start = x;
while(x<word.length()&&isdigit(word.at(x))) //Loops past the number portion
{
x++;
}
string temp = word.substr(start, x).c_str();
for(int i = 0; i < temp.length();i++){
tempList2.addValue(atoi(temp.substr(i, 1).c_str()));
// push(&head2, atoi(temp.substr(i, 1).c_str()));
// cout << atoi(temp.substr(i, 1).c_str());
counter++;
}
//////START READING NUMBERS BACKWARDS
LinkedList finalList;
node* tempA = tempList1.tail;
node* tempB = tempList2.tail;
// multiply(tempA, tempB);
//ADDITION
while(tempA != NULL){
if(tempA->data != -1){
push(&head1,tempA->data);
// cout << tempA->data;
}
tempA = tempA->prev;
}
while(tempB != NULL){
if(tempB->data != -1){
push(&head2, tempB->data);
// cout << tempB->data;
}
tempB = tempB->prev;
}
// multiply(head1, head2);
// result = multiply(head1, head2);
// tempList1.PrintReverse();
addList(head1, head2, &result);
printList(head1);
cout << operatorX;
printList(head2);
cout << "=";
printList(result);
cout << endl;
}
else{
x++;
}
//end
}
}
else{
x++;
}
}
}
else //If char at position x is neither number or letter skip over it
{
x++;
}
}
}
}
Since you're working in C++, use a template/overloaded operators. Cast your ints to a floating point type as necessary. See e.g.:
C++ Template problem adding two data types

Priority Queue using array of linked list C++ [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 7 years ago.
Improve this question
So I'm trying to create a priority queue using an array of linked lists in C++. I'm not finished but if I can fix the constructor I think I can do the rest on my own.
I have a data file, first line has the number of items in the file.
The next line thereafter will have a char and then the priority level starting from 0 to 9.
So I'm sorting the alphabet which has 26 letters (the items). Each letter is given a level of priority.
Ex. Q 5 (the letter Q has the priority 5)
When I run this, it says that the program stopped working and then it starts to look for a solution. Like an error for an infinity loop I think.
#include <iostream>
#include <fstream>
using namespace std;
class Queue
{
private:
struct linkedList
{
char data;
linkedList *next;
};
linkedList* PQ[10];
public:
//bool empty;
//bool empty(int priority);
void add(char info, int lvl);
//void remove();
Queue();
};
int main()
{
int size;
char Info;
int Lvl;
Queue Q;
ifstream dataIn;
dataIn.open("charQueueInput.txt");
if (dataIn.fail())
{
cout << "File does not exist." << endl;
exit(1);
}
dataIn >> size;
dataIn.get();
cout << size;
/*for (int i = 0; i < size; i++)
{
dataIn >> Info;
dataIn >> Lvl;
dataIn.get();
Q.add(Info, Lvl);
}*/
system("pause");
return 0;
}
Queue::Queue()
{
for (int i = 0; i < 10; i++)
{
PQ[i] = NULL;
}
for (int i = 0; i < 9; i++)
{
PQ[i]->next = PQ[i + 1];
}
PQ[9]->next = NULL;
}
void Queue::add(char info, int lvl)
{
if (lvl == 0)
{
PQ[0]->data = info;
linkedList *temp = new linkedList;
temp->next = PQ[1];
PQ[0]->next = temp;
}
else if (lvl == 1)
{
PQ[1]->data = info;
linkedList *temp = new linkedList;
temp->next = PQ[2];
PQ[1]->next = temp;
}
else if (lvl == 2)
{
PQ[2]->data = info;
linkedList *temp = new linkedList;
temp->next = PQ[3];
PQ[2]->next = temp;
}
else if (lvl == 3)
{
PQ[3]->data = info;
linkedList *temp = new linkedList;
temp->next = PQ[4];
PQ[3]->next = temp;
}
else if (lvl == 4)
{
PQ[4]->data = info;
linkedList *temp = new linkedList;
temp->next = PQ[5];
PQ[4]->next = temp;
}
else if (lvl == 5)
{
PQ[5]->data = info;
linkedList *temp = new linkedList;
temp->next = PQ[6];
PQ[5]->next = temp;
}
else if (lvl == 6)
{
PQ[6]->data = info;
linkedList *temp = new linkedList;
temp->next = PQ[7];
PQ[6]->next = temp;
}
else if (lvl == 7)
{
PQ[7]->data = info;
linkedList *temp = new linkedList;
temp->next = PQ[8];
PQ[7]->next = temp;
}
else if (lvl == 8)
{
PQ[8]->data = info;
linkedList *temp = new linkedList;
temp->next = PQ[9];
PQ[8]->next = temp;
}
else if (lvl == 9)
{
PQ[9]->data = info;
linkedList *temp = new linkedList;
temp->next = NULL;
PQ[1]->next = temp;
}
}
Here would be an example of the data file:
7
Q 5
W 3
T 0
Y 4
A 9
B 5
U 0
And you would read it as:
0: T -> U
1.
2.
3. W
4. Y
5. Q -> B
6.
7.
8.
9. A
T, U, W, Y, Q, B, A
The problem is that you access PQ before allocating memory.
class Queue
{
private:
struct linkedList
{
char data;
linkedList *next;
};
linkedList* PQ[10]; // Allocates pointer only
The class only allocates pointers to linkenList but not any instances.
Later you have:
// In constructor
Queue::Queue()
{
for (int i = 0; i < 10; i++)
{
PQ[i] = NULL;
}
for (int i = 0; i < 9; i++)
{
PQ[i]->next = PQ[i + 1]; // PQ[i] is NULL so run time error
}
and also later
void Queue::add(char info, int lvl)
{
if (lvl == 0)
{
PQ[0]->data = info; // Access to non-allocated element!
linkedList *temp = new linkedList;
temp->next = PQ[1];
where you access PQ[0]->data. But the element has not been allocated so you get a run time problem.
Instead of
if (lvl == 0)
{
PQ[0]->data = info;
linkedList *temp = new linkedList;
temp->next = PQ[1];
PQ[0]->next = temp;
}
you need something like:
if (lvl == 0)
{
if (PQ[0] == nullptr)
{
PQ[0] = new linkedList; // If head of queue is null, allocate
// new element for head
PQ[0]->next = nullptr;
}
linkedList *temp2 = PQ[0];
while(temp2->next != nullptr) // Search the linked list
{ // to find last element
temp2 = temp2->next;
}
// Now temp2 points to the last element in the list
temp2->next = new linkedList; // Allocate new element and add it
// to the list after temp2
// to get a linked list
temp2 = temp2->next; // Make temp2 point to the new element
temp2->next = nullptr; // Remember to initialize next of new element
temp2->data = info; // Save info
}
And in the constructor:
Queue::Queue()
{
for (int i = 0; i < 10; i++)
{
PQ[i] = nullptr; // Use nullptr instead of NULL
}
// Remove this block
// for (int i = 0; i < 9; i++)
// {
// PQ[i]->next = PQ[i + 1];
// }
// PQ[9]->next = NULL;
}
It is not the pointers in the array which shall be linked.
Each pointer is a pointer to the HEAD of a linked list, i.e. 10 independent linked lists. So don't link them.
And finally - use the array in the add() function! Don't do the big if-statement.
void Queue::add(char info, int lvl) // Tip: Consider making lvl an unsigned int
{
if ((lvl >= 10) || (lvl < 0)) return; // Ignore if lvl is out of range
if (PQ[lvl] == nullptr) // <---- USE lvl to index array
{
PQ[lvl] = new linkedList; // If head of queue is null, allocate
// new element for head
PQ[lvl]->next = nullptr;
}
linkedList *temp2 = PQ[lvl];
while(temp2->next != nullptr) // Search the linked list
{ // to find last element
temp2 = temp2->next;
}
// Now temp2 points to the last element in the list
temp2->next = new linkedList; // Allocate new element and add it
// to the list after temp2
// to get a linked list
temp2 = temp2->next; // Make temp2 point to the new element
temp2->next = nullptr; // Remember to initialize next of new element
temp2->data = info; // Save info
}
BTW - remember to create a destructor which deletes all elements in the 10 linked lists.

After exiting from function, nodes aren't saved

My program should create a linked list and show it. My problem is when the addelemnt_end function ends, it doesn't update head and last.
I tried with debug and when my function is done, the info and next part from head and last are "unable to read memory".
struct node{
int info;
node *next;
};
node *head, *last;
void addelement_end(node *head, node *last, int element)
{if (head == NULL)
{ node *temp = new node;
temp->info = element;
temp->next = NULL;
last = temp;
head = temp;
}
else {node*temp = new node;
last->next = temp;
temp->info = element;
temp->next = NULL;
last = temp;
}
}
void show(node* head, node *last)
{
if (head==NULL)
cout << "Empty list";
else
while (head != NULL)
{
cout << head->info << " ";
head = head->next;
}
}
int _tmain(int argc, _TCHAR* argv[])
{
int x, n, i;
cout << "how many numbers";
cin >> n;
head = last = NULL;
for (i =1; i <= n; i++)
{
cin >> x;
addelement_end(head, last, x);
}
show(head, last);
return 0;
}
It's a very common error. Here is a similar illustration of the problem:
int change_a(int a) {
a = 42;
}
int main() {
int a = 10;
change_a(a);
printf("%d\n", a);
return 0;
}
This will print 10 because in the function change_a you are only modifying a copy of the value contained in the variable a.
The correct solution is passing a pointer (or using a reference since you are using C++).
int change_a(int *a) {
*a = 42;
}
int main() {
int a = 10;
change_a(&a);
printf("%d\n", a);
return 0;
}
But maybe you're going to tell me: "I'm already using a pointer!". Yes, but a pointer is just a variable. If you want to change where the pointer points, you need to pass a pointer to that pointer.
So, try this:
void addelement_end(node **head, node **last, int element)
{
if (*head == NULL)
{ node *temp = new node;
temp->info = element;
temp->next = NULL;
*last = temp;
*head = temp;
}
else {
node *temp = new node;
(*last)->next = temp;
temp->info = element;
temp->next = NULL;
*last = temp;
}
}