I created this code to calculate the sum of the values in a linked list entered by the user, and the expected output is to print the sum but it gives the last value and prints the wrong number of records in linked list
Enter a number : 5
Enter [Y] to add another number : Y
Enter a number : 1
Enter [Y] to add another number : N
List of existing record : 5
1
My code is as below, however it does not print my expected output :
#include <iostream>
using namespace std;
class Node {
public:
int no;
Node* next; //missing code
};
Node* createNode(int num) {
Node* n = new Node();
n->no = num;
n->next = NULL;
return n;
}
void addValue(int no, Node** h) {
//insert first node into linked list
Node* y = createNode(no), * p = *h;
if (*h == NULL)
*h = y;
//insert second node onwards into linked list
else {
while (p->next != NULL) //while not the end
p = p->next; // go next
p->next = y;
}
}
void display(Node* x) {
while (x != NULL) {
cout << x->no << " " << endl;
x = x->next;
}
}
double sumNodes(Node** h) {
double* sum = 0;
Node* x = *h;
while (x != NULL) {
*sum += x->no;
x = x->next;
}
return *sum;
}
int main() {
int num = 0; char choice;
Node* head = NULL;
double s;
do {
cout << "Enter a number : ";
cin >> num;
addValue(num, &head);
cout << "Enter [Y] to add another number : ";
cin >> choice;
} while (choice == 'Y');
cout << "List of existing record : ";
display(head);
cout << endl << endl;
s = sumNodes(&head);
cout << "Sum = " << s << endl;
return 0;
}
In sumNodes(), you are declaring sum as a null pointer and then dereferencing it, which invokes undefined behavior.
double sumNodes(Node** h) {
double* sum = 0; // <-- null pointer
Node* x = *h;
while (x != NULL) {
*sum += x->no; // <-- dereference
x = x->next;
}
return *sum; // <-- dereference
}
There is no need to use a pointer at all. Instead, write:
double sumNodes( const Node** h) {
double sum = 0;
const Node* x = *h;
while (x != NULL) {
sum += x->no;
x = x->next;
}
return sum;
}
change double *sum to double sum, or better to int sum.
Related
I have this task to do. Basically, I have to create a dynamic stack, then I have to choose an element and swap it with a new one which I inserted. The other elements remain the same and I have to display the new data. I've come to a dead end.
#include <iostream>
using namespace std;
struct elem
{
int key;
elem* next;
} *start = NULL, *p;
void push(int n);
int pop(int &n);
int main()
{
int num, counter = 0;
do
{
cout << "Input integers(!=0): ";
cin >> num;
if (num > 0 || num < 0)
{
push(num);
counter++;
}
}
while (num != 0);
cout << "\nStack: ";
while (pop(num))
cout << num << "\t";
cout << "\n";
int element, newValue;
cout << "Input element number: ";
cin >> element;
cout << "New value of element: ";
cin >> newValue;
here I struggle doing the swap
return 0;
}
void push(int n)
{
p = start;
start = new elem;
start->key = n;
start->next = p;
}
int pop(int &n)
{
if (start)
{
n = start->key;
p = start;
start = start->next;
delete p;
return 1;
}
else
return 0;
}
How do you swap a chosen one from a stack of (dinner) plates with the top one?
you pick the topmost, put it aside, then pick all the ones you don't want and put them on a new stack until you reach the chosen one. Pick it, exchange it with the original topmost one, put the chosen one aside.
Then re-stack, one by one, the plates from the new stack to the old one. Lastly, put the one you put aside on top.
Going through an intermediary stack like #Bathsheba suggested is the most straight forward solution here.
You can also save some execution time by simply modifying the "next" var of the previous
element to the element you're going the change.
#include <iostream>
using namespace std;
struct elem
{
int key;
elem* next;
}
*start = NULL, *p,*previous,*curr,*temp;
void push(int n);
int pop(int &n);
int main() {
int num, counter = 0;
do {
cout << "Input integers(!=0): ";
cin >> num;
if (num > 0 || num < 0) {
push(num);
counter++;
}
}
while (num != 0);
/* cout << "\nStack: ";
while (pop(num))
cout << num << "\t";
cout << "\n";
*/
int element, newValue;
cout << "Input element number: ";
cin >> element;
cout << "New value of element: ";
cin >> newValue;
curr = start ;
previous = NULL;
while(curr->next)
{
if(curr->key == element){
if(previous) {
temp = new elem;
temp->key = newValue;
temp->next = curr->next ;
previous->next = temp ;
break;
}
else {
temp = new elem;
temp->key = newValue;
temp->next = curr->next ;
start = temp ;
break;
}
}
else {
previous = curr ;
curr = curr->next;
}
}
while (pop(num))
cout << num << "\t";
cout << "\n";
return 0;
}
void push(int n) {
p = start;
start = new elem;
start->key = n;
start->next = p;
}
int pop(int &n) {
if (start) {
n = start->key;
p = start;
start = start->next;
delete p;
return 1;
}
else
return 0;
}
The following code calculates the sum of the elements of the unidirectional list items greater than 3 and smaller than 8 and the result of the sum is changed the beginning of the list.
#include <iostream>
using namespace std;
struct List
{
int num;
List* nItem;
};
int Input()
{
int number;
cout << "Enter the number: "; cin >> number;
return number;
}
void MakeList(List **head, int n)
{
if (n > 0) {
*head = new List;
(*head)->num = Input();
(*head)->nItem = NULL;
MakeList(&(*head)->nItem, n - 1);
}
}
void Print(List* head)
{
if (head != NULL) {
cout << head->num << " ";
Print(head->nItem);
}
}
List* Add_start(List* head, int index, int elm)
{
List* p = new List;
p->num = elm;
p->nItem = NULL;
if (head == NULL) {
head = p;
}
else {
List* current = head;
for (int i = 0; (i < index - 1) && (current->nItem != NULL); i++)
{
current = current->nItem;
}
if (index == 0)
{
p->nItem = head;
head = p;
}
else {
if (current->nItem != NULL) {
p->nItem = current->nItem;
}
current->nItem = p;
}
}
return head;
}
int Sum(List* head)
{
int sum = 0;
List* p = head;
while(p) {
if ((p->num > 3) && (p->num < 8))
sum += p->num;
p = p->nItem;
}
return sum;
}
void DeleteList(List* head)
{
if (head != NULL) {
DeleteList(head->nItem);
delete head;
}
}
int main()
{
int n = 10;
List* head = NULL;
cout << "Enter 10 number to the list\n" << endl;
MakeList(&head, n);
int sum = Sum(head);
head = Add_start(head, 0, sum);
cout << "\nList: ";
Print(head);
cout << endl;
DeleteList(head);
system("pause");
return 0;
}
How can I do the same operation with a bidirectional list?
Notes:
A bidirectional (or double linked) list, also has a member pointing to the previous node: this is the whole difference between the 2 list types (as a consequence the first element - or the one at the left of the list, will have this member pointing to NULL). So, when such a node is created/inserted into a list, this new member should be set as well (I commented in the code places where this happens), for the new node and for the one following it (if any).
I modified the way of how a list is created - MakeList replaced by _MakeList2 + MakeList2; the underscore(_) in _MakeList2 specifies that it's somehow private (convention borrowed from Python) - it's not very nice, but I thought it's easier this way
I don't have Visual Studio on this computer, so I used gcc. It complained about system function so I had to add #include <stdlib.h>
I renamed some of the identifiers (List -> Node, Add_start -> AddNode, nItem -> nNode) either because the new names make more sense, or their names are consistent
I tried to keep the changes to a minimum (so the solution is as close as possible to your original post)
I enhanced (by adding an additional argument: toRight (default value: 1)) the Print func, so it can iterate the list both ways - I am iterating right to left (for testing purposes) before deleting the list
I corrected some (minor) coding style issues
Here's the modified code:
#include <iostream>
#include <stdlib.h>
using namespace std;
struct Node {
int num;
Node *pNode, *nNode; // Add a new pointer to the previous node.
};
int Input() {
int number;
cout << "Enter the number: "; cin >> number;
return number;
}
Node *_MakeList2(int n, Node *last=NULL) {
if (n > 0) {
Node *node = new Node;
node->num = Input();
node->pNode = last;
node->nNode = _MakeList2(n - 1, node);
return node;
}
return NULL;
}
Node *MakeList2(int n) {
return _MakeList2(n);
}
void Print(Node *head, int toRight=1) {
if (head != NULL) {
cout << head->num << " ";
if (toRight)
Print(head->nNode, 1);
else
Print(head->pNode, 0);
}
}
Node* AddNode(Node *head, int index, int elm) {
Node *p = new Node;
p->num = elm;
p->pNode = NULL; // Make the link between this node and the previous one.
p->nNode = NULL;
if (head == NULL) {
head = p;
} else {
Node *current = head;
for (int i = 0; (i < index - 1) && (current->nNode != NULL); i++) {
current = current->nNode;
}
if (index == 0) {
p->nNode = head;
head->pNode = p; // Make link between next node's previous node and the current one.
head = p;
} else {
if (current->nNode != NULL) {
p->nNode = current->nNode;
}
p->pNode = current; // Make the link between this node and the previous one.
current->nNode = p;
}
}
return head;
}
int Sum(Node* head) {
int sum = 0;
Node *p = head;
while(p) {
if ((p->num > 3) && (p->num < 8))
sum += p->num;
p = p->nNode;
}
return sum;
}
void DeleteList(Node *head) {
if (head != NULL) {
DeleteList(head->nNode);
delete head;
}
}
int main() {
int n = 10;
Node *head = NULL, *tail = NULL;
cout << "Enter " << n << " number(s) to the list" << endl << endl;
head = MakeList2(n);
int sum = Sum(head);
head = AddNode(head, 0, sum);
cout << endl << "List: ";
Print(head);
cout << endl;
tail = head;
if (tail) {
while (tail->nNode != NULL)
tail = tail->nNode;
cout << endl << "List reversed: ";
Print(tail, 0);
cout << endl;
}
DeleteList(head);
system("pause");
return 0;
}
Example:
Linked List A: 1->2->3
Linked List B: 4->5->6
My task is to make a function, that passes List B into List A at any given position (n).
For instance: After "2" = 1->4->5->6->2->3 (output).
I wasn't really sure, how to do this, so I used:
// Function that finds a number in a list and gets an address of that node.
Node* List::find(int i)
{
for (start();!end();next())
if(current->num==i) return current;
return NULL;
};
// Function, that puts freely desired number at position n in the list;
Example cin >> i; // i = 6;
1->2->6->desired number->...
Node* List::addAfter(int pos, int num)
{
Node* p = NULL; i
current = find(pos);
if (current != NULL)
{
p = new Node(num);
p->next = current->next;
current->next = p;
}
if (last == current) last = p;
current = p;
return p;
}
Both things works, but only as:
cout << "After which number?" << endl;
cin >> i; // **2**
l.addAfter(i, 1); // Before: 2->3->4 After: 2->1->3->4
l.print();
This works perfectly! But if I have two lists - l1 (2->3->4 and l2 6->7)
how can I put both together using this function?
Node* List::addAfter(int pos, I HAVE TO PASS L2 VALUES HERE)
How can I give this function l2 values as parameter?
Is there maybe a better way, to do this? I'd appreciate any help.
WHOLE CODE:
#include <iostream>
using namespace std;
class Node
{
public:
int num;
Node *next;
Node (int n) { num = n; next = NULL; };
};
class List
{
protected:
Node *first, *last;
public:
Node *current;
public:
List () { first = last = current = NULL; };
void add_element (int n);
void delete_element ();
void print(); // Izdrukā sarakstu
bool is_empty () { return (first == NULL); };
void start () { current = first; };
bool end () { return (current == NULL); };
void next(){if (!end())current = current -> next;};
Node* find(int i);
Node* addAfter(int i, List * l2);
~List();
};
int main()
{
List l, l2;
int k, i;
cout << "Type number: (0,to stop):\n";
cin >> k;
while (k!=0)
{
l.add_element (k);
cout << "Type number: (0, to stop):\n";
cin >> k;
};
cout << endl;
cout << "Type 2nd list numbers: (0,to stop):\n";
cin >> k;
while (k!=0)
{
l2.add_element (k);
cout << "Type 2nd list numbers: (0,to stop):\n";
cin >> k;
};
cout << endl;
l.print();
l2.print();
cout << "After which element do you want to insert second list?" << endl;
cin >> i;
l.addAfter(i, l2); // GETTING ERROR HERE.
l.print();
return 0;
}
simplest and easiest form is to pour out both stacks into an array
const int size = stackA.size() + stackB.size();
const stackASize = stackA.size();
const stackBSize = stackB.size();
int arrayOfStackA [size];
int arrayOfStackB [stackBSize];
//Pop StackA into ArrayA
for(int i=stackASize-1; i>0; i++)
{
arrayOfStackA[i] = stackA.pop();
}
//Pop StackB into ArrayB
for(int i=stackBSize-1; i>=0; i++)
{
arrayOfStackB[i] = stackB.pop();
}
Now find the index where you want to insert the data in array A.
In your case you want to enter stack b after 1 which in case of array is the index:1
int count = 0
for(int i=0;i<size;i++){
if(i<requiredIndexNumber){
//do nothing
}
else if(i>=requiredIndexNumber && count!=stackBSize){
int temp = arrayOfStackA[i];
arrayOfStackA[i] = arrayOfStackB[count++];
arrayOfStackA[stackASize+i] = temp;
}
}
This is the most easiest from of popping one stack into an other at any index
#include <iostream>
using namespace std;
struct node {
int item;
node* l;
node* r;
node (int x) {
item = x;
l = 0;
r = 0;
}
node(int x, node* l, node* r) {
item = x;
this->l = l;
this->r = r;
}
};
typedef node* link;
class QUEUE {
private:
link* q;
int N;
int head;
int tail;
public:
QUEUE(int maxN) {
q = new link[maxN + 1];
N = maxN + 1;
head = N;
tail = 0;
}
int empty() const {
return head % N == tail;
}
void put(link item) {
q[tail++] = item;
tail = tail % N;
}
link get() {
head = head % N;
return q[head++];
}
};
link head = 0; // Initial head of the tree
link find(int x) {
if (head == 0) {
cout << "\nEmpty Tree\n";
return 0;
}
link temp = head;
// To find the node with the value x and return its link
QUEUE q(100);
q.put(temp);
while (!q.empty()) {
temp = q.get();
if (temp->item == x) {
return temp;
}
if (temp->l != 0) q.put(temp->l);
if (temp->r != 0) q.put(temp->r);
}
return 0;
}
void print(link temp) {
QUEUE q(100);
q.put(temp);
while (!q.empty()) {
temp = q.get();
cout << temp->item << ", ";
if (temp->l != 0) q.put(temp->l);
if (temp->r != 0) q.put(temp->r);
}
}
void deleteAll(link h) {
// This deletes the entire binary tree
QUEUE q(100);
q.put(h);
while (!q.empty()) {
h = q.get();
if (h->l != 0) q.put(h->l);
if (h->r != 0) q.put(h->r);
delete h;
}
}
int main() {
link temp = 0;
char c;
int n1, n2;
cout << "\n\nPlease enter the input instructions (X to exit program) : \n\n";
do {
cin >> c;
switch (c) {
case 'C': cin >> n1;
if (head == 0) {
head = new node(n1);
cout << "\nRoot node with item " << n1 << " has been created\n\n";
} else {
cout << "\nError: Tree is not empty\n\n";
}
break;
case 'L': cin >> n1 >> n2;
temp = find(n1);
if (temp != 0) {
if (temp->l == 0) {
temp->l = new node(n2);
cout << "\nNode with item " << n2 << " has been added\n\n";
}
else {
cout << "\nError: The specified node already has a left child\n\n";
}
}
else {
cout << "\nError: The specified node doesn't exist\n\n";
}
break;
case 'R': cin >> n1 >> n2;
temp = find(n1);
if (temp != 0) {
if (temp->r == 0) {
temp->r = new node(n2);
cout << "\nNode with item " << n2 << " has been added\n\n";
}
else {
cout << "\nError: The specified node already has a right child\n\n";
}
}
else {
cout << "\nError: The specified node doesn't exist\n\n";
}
break;
case 'P': cin >> n1;
temp = find(n1);
if (head != 0) {
cout << "\nLevel-order traversal of the entire tree: ";
print(temp);
}
else {
cout << "\nError: No elements to print\n\n";
}
break;
case 'D': cin >> n1;
temp = find(n1);
deleteAll(temp);
temp = 0;
break;
case 'X': cout << "\nExiting Program\n\n";
break;
default: cout << "\nInvalid input entered. Try again.\n\n";
}
} while (c != 'X');
system("pause");
return 0;
}
Sample Input:
C 9
L 9 8
R 9 6
L 8 3
R 8 5
R 6 2
L 3 4
L 4 10
L 5 1
R 5 11
L 1 12
R 1 7
It all works fine until I delete a subtree and print when it prints garbage value before crashing. Please help me figure out the bug because I've been trying in vain for hours now.
It all works fine until I delete a subtree and print when it prints garbage value before crashing. Please help me figure out the bug because I've been trying in vain for hours now.
Try the recursive function:
void Delete(link h)
{
if(h)
{
if(h->l) Delete(h->l);
if(h->r) Delete(h->r);
delete(h);
}
}
When you delete a node, you call deleteAll(temp) which deletes temp, but it doesn't remove the pointer value from the l or r of temp's parent node.
This leaves you with a invalid pointer, causing garbage printing and crashing.
Unfortunately, the way your find works currently, you don't know what the current temp node's parent is when you get around to checking its value.
One way to fix it is to have a different type of find (called something like remove) that looks in l and r at each iteration for the value and sets l or r to NULL before returning the pointer. You might have to have a special case for when the value is found in the root.
Edit (sample code added):
I am assuming you are not using recursion for some reason, so my code uses your existing queue based code. I only changed enough to get it working.
findAndUnlink find the node with the value given and "unlinks" it from the tree. It returns the node found, giving you a completely separate tree. Note: it is up to the caller to free up the returned tree, otherwise you will leak memory.
This is a drop in replacement for find in your existing code, as your existing code then calls deleteAll on the returned node.
link findAndUnlink(int x) {
if (head == 0) {
cout << "\nEmpty Tree\n";
return 0;
}
link temp = head;
if (temp->item == x) {
// remove whole tree
head = NULL;
return temp;
}
// To find the node with the value x and remove it from the tree and return its link
QUEUE q(100);
q.put(temp);
while (!q.empty()) {
temp = q.get();
if (temp->l != NULL) {
if (temp->l->item == x) {
link returnLink = temp->l;
temp->l = NULL;
return returnLink;
}
q.put(temp->l);
}
if (temp->r != NULL) {
if (temp->r->item == x) {
link returnLink = temp->r;
temp->r = NULL;
return returnLink;
}
q.put(temp->r);
}
}
return 0;
}
My problem is that I'm trying to insert a letter into a linked list based on users input at a specific position given by the int h...However every time I run the program only the second character in the list changes regardless of the number the user puts into the program.
Example:
./h
Name: koala
a<-l<-a<-o<-k
Change the position: 2
To the character: 3
a<-l<-3<-o<-k
Insert the Character: F
To the Postion: 3
a<-F<-l<-3<-o<-k
I want it to look like.
./h
Name: koala
a<-l<-a<-o<-k
Change the position: 2
To the character: 3
a<-l<-3<-o<-k
Insert the Character: F
To the Postion: 3
a<-l<-3<-F<-o<-k
I know my problem is in the insert_char() function in my lists.cpp but just can't figure out what i'm doing wrong...
List.h
#include <iostream>
using namespace std;
struct Node;
Node* new_list();
void insert_front(Node** plist,char x);
void insert_char(Node* plist, char x, int p);
void change_char(Node* plist, char x, int p);
void print_list(Node* list);
void delete_front(Node** plist);
void delete_list(Node** plist);
//void delete_char(Node* plist,int p);
struct Node {
char x;
Node *next;
};
main.cpp
struct Node {
char x;
Node *next;
};
int main(){
Node *list;
list = new_list(); //new empty list
cout<<"Name: ";
string name;
cin>> name;
for (int i =0; i < name.length(); i++)
insert_front(&list, name[i]);
//---------print list-------------------------
print_list(list);
cout <<"Change the position: ";
int z;
cin>> z;
cout<< "To the character: " ;
char x;
cin>> x;
change_char(list, x, z);
print_list(list);
cout <<"Insert the Character: ";
char y;
cin>> y;
cout<< "To the Postion: ";
int h;
cin>> h;
insert_char(list, y, h);
print_list(list);
return 0;
}
lists.cpp
Node* new_list()
{
Node* list = 0; //in C++ it is better to use 0 than NULL
return list;
}
void insert_front(Node** plist,char x){
Node* t;
t = new Node;
t->x = x;
t->next = *plist;
*plist = t;
return;
}
void change_char(Node* plist, char x, int p)
{
Node* s = plist;
for (int i=1; i<p && 0!=s;i++)
s = s->next;
if (0 != s)
s->x = x;
return;
}
void insert_char(Node* plist, char x, int p){
Node* s = plist;
Node* a = new Node();
for (int i=1; i<p && s; i++)
a->next=s->next;
s->next=a;
if (0 !=s)
a->x=x;
return;
}
//void delete_char(Node* plist,int p)
void print_list(Node* list){
Node* p;
p = list;
if(p == 0)
cout << "--- empty list ---" << endl;
while(p !=0){
cout << p->x<<"<-";
p = p->next;
}
cout << endl;
}
void delete_front(Node** plist){
Node* t;
if( *plist != 0){ // list is not empty
t = (*plist);
*plist = (*plist)->next;
delete t;
}
}
void delete_list(Node** plist){
while(*plist != 0) //while list not empty
delete_front(plist);
}
bool is_empty(Node* list){
return (list == 0);
}
The for loop in insert_char is just "inserting" the character over and over. I think you meant to advance s to the starting point of the insertion (as determined by h).
Update:
This part is wrong for a few reasons:
for (int i=1; i<p && s; i++)
a->next=s->next;
s->next=a;
Note that the indentation is misleading. Since you don't have braces, only the middle line is part of the loop. Effectively, you've written:
for (int i=1; i<p && s; i++) {
a->next=s->next;
}
s->next=a;
Personally, I always use braces on blocks, even if they consist of only one statement.
So you set a->next a bunch of times instead of advancing to the point in the list you want to go.
You need to advance to the position you want the new element in the loop, and then do the actual insertion.
// Advance s to index p.
for (int i = 1; i < p && s->next; i++) {
s = s->next;
}
// Insert a at s.
a->next = s->next;
s->next = a;