The following code will not print the last line which displays the maximum element in the linked list below.
In the following code, I sum the linked list, print the entire linked list, print the length of the linked list, and would like to print the maximum value found in the linked list.
For some reason, the compiler does not print the last line.
#include <iostream>
#include <stdio.h>
using namespace std;
struct Node{ //if you want to convert to class, you need to assign access specifiers to public since they're private on default
int data;
struct Node *next;
}*first = NULL;
void create(int A[], int n)
{
struct Node *t; //create a temporary pointer t
struct Node *last; //pointer, points to the last node - helps me add a new node at the END of a linked list
//as of now, the linked list is empty, so we must create the first node!
first = new Node;//create new node on the heap, and first will be pointing on that new node
first -> data = A[0]; // Assign first the first element on the array
first -> next = NULL;//Should point to a null value as it is the only element on the list to start/currently
last = first; //last points on first node
for (int i = 1; i <n; i++)// i starts at element 1 since first has been assigned the 1st element in the array
{
t = new Node; //create a new node
t->data = A[i]; //fill up the data of t from A[i] which will be iterated through and assigned to data
t->next = NULL; // the next node should be pointing to NULL, as there is nothing at the moment when the iteration begins that it is initially pointing to
last -> next = t;
last = t;
}
}
int length (struct Node *p)
{
int l = 0;
while (p)
{
l++;
p = p->next;
}
return l;
}
int sum (struct Node *p){
int s= 0;
while(p){
s+=p->data;
p = p->next;
}
return s;
}
int max (struct Node *p){
int max = -32767;
while(p){
if(p->data > max){
max = p->data;
p = p->next;
}
}
return max;
}
void display (struct Node *p)
{
while (p != 0 )
{
cout<<p->data<<" ";
cout<<p->next<<" ";
p = p->next;
}
}
int main() {
int A [] = {1,2,3,18,5, 6, 7};
create (A,7);
display(first);
cout<<endl;
cout<<"The length of the linked list (the number of nodes) is: "<< length(first)<<endl;
cout<<"The sum of the linked list values (nodes) is: "<< sum(first)<<endl;
cout<<"The maximum value in the linked list (of the nodes) is: "<< max(first)<<endl;
return 0;
}
What am I doing wrong?
You have a little problem in your max function,your function never goes through the entire list since you put the p = p->next inside of the if block, you must edit it as below
int max (struct Node *p){
int max = -32767;
while(p !=nullptr ){
if(p->data > max){
max = p->data;
}
p = p->next;
}
return max;
}
It's because of that you put the p = p->next inside of the maximum checking scope and because of that if max set to 18, you couldn't point to the next of the list, since you don't have any data in the list that is bigger than 18,so list never finished and your iterator will be stopped in a fixed point and while loop will run forever!!
Your max() function is not incrementing the node pointer on every iteration, like your other functions do. If it encounters a data value that is not greater than the current max then it gets stuck in an endless loop.
You need to move the iteration out of the inner if block:
int max (struct Node *p){
int m = -1;
while (p){
if (p->data > max){
max = p->data;
}
p = p->next;
}
return m;
}
Related
I have this problem, where user inputs n and my program needs to remove any elements form a linked list that come after n and are not equal to n. For example, if my list is 1,2,4,8,4,6,1 and user inputs 4 it should output 1,2,4,4.
So far I only have this code (if list is 1,2,4,8,4,6,1 it outputs 4 8 4 6 1):
#include <iostream>
#include <algorithm>
using namespace std;
struct elem
{
int num;
elem *next;
elem(int n){num = n; next= NULL;}
};
void append(elem *&first, elem *&last, int n){
elem *p = new elem(n);
if(first==NULL)
first=last=p;
else {
last->next=p;
last = p;
}
}
void deleteListItems(elem *&first, int n){
elem *p;
while(first){
if(first->num==n){
break;
}
else{
p = first->next;
delete first;
first=p;
}
}
}
void print(elem *first){
elem *p = first;
while(p!=NULL){
cout<<p->num<<" ";
p = p->next;
}
cout<<endl;
}
int main () {
int aa[] = {1,2,4,8,4,6,1};
elem *first=NULL;
elem *last=NULL;
elem *p;
int n;
for(int i=0; i<7; ++i){
append(first, last, aa[i]);
}
print(first);
cout<<"Input n: "<<endl;
cin>>n;
elem *prev;
print(first);
deleteListItems(first, n);
print(first);
/// delete list
p = first;
while (p!=NULL){
first = first->next;
delete p;
p = first;
}
};
Your problem needs to be broken down into two parts
Find the first instance of the target value.
If found, advance to the node past it, and delete every node not the target value.
This is made trivial with a pointer to pointer approach. The code to do that is shown below, and I did my best to document how it works in comments.
void deleteListItems(elem *&first, int n)
{
// start at head of the list
elem **pp = &first;
// find the first instance of n
while (*pp && (*pp)->num != n)
pp = &(*pp)->next;
// if we found one...
if (*pp)
{
// advance past it
pp = &(*pp)->next;
// now walk the rest of the list
while (*pp)
{
// if this does NOT match the target value
if ((*pp)->num != n)
{
// remember the node, overwrite the list pointer
// referring to it with it's own 'next', and then
// delete now-unhitched node.
elem *p = *pp;
*pp = p->next;
delete p;
}
else
{
// otherwise, it's another instance of the target
// value, so just skip to the next node.
pp = &(*pp)->next;
}
}
}
}
This will work in every case I could think of, including lists without duplicates, lists entirely of duplicates, empty lists, single-node lists etc. Worth mentioning, the tail pointer in main can easily end up dangling, but that was an original problem with your code, and I suspect you'll address that soon enough.
not able to understand the steps in [else statement] block .
please someone help me with it.I am trying to insert a node at the nth place keeping in mind the node at the nth position cannot be created unless node at (n-1)th has been created.
EDIT:-Now I have posted the complete code(working),
#include<iostream>
using namespace std;
struct Node{
int data;
Node*next ;
};
void insertlinkedlist(Node**head,int data,int position)
{
int k = 1;
Node *p,*q,*newNode;
newNode=(Node*)malloc(sizeof(Node));
if(!newNode)
{
cout<<"Memory leak";
return;
}
newNode->data = data;
p=*head;
if(position ==1)
{
newNode ->next = p;
*head = newNode;
}
else {
while(p!=NULL&k<position){
k++;
q=p;
p = p->next;
}
q->next = newNode;
newNode ->next = p;
}
}
void display(Node*head)
{
Node*ptr = head;
while(ptr!=NULL)
{
cout<<ptr->data<<" ";
ptr=ptr->next;
}
}
int main(){
Node*head = NULL;
insertlinkedlist(&head, 34, 1);
insertlinkedlist(&head, 3, 2);
insertlinkedlist(&head, 13, 3);
display(head);
cout<<endl;
}
output
34 3 13
The else statement is executed, when an element is not inserted at the first position. In your code referred with 1. I think it would be a better approach to declare the first position with a 0.
The while statement p!=null returns true (=0), when the pointer is valid. This value gets bitwise-anded with the return value of k<position. The while statement breaks therefore, when you are at your last element of the linked list or at your specified position.
After the while statement is executed you insert your new Node at the end or at the actual specified position at q, which gets calculated in the while-statement. After that you insert the next element after your newNode. Imagine a new element at position 3. Then this element is at position 3 and everyhting what comes after 3, starts at position 4.
I am creating a linked list program, and one of the functions is supposed to remove a node at a given index.
My idea is to locate the node one before the node at the index I wish to remove, then set it's next pointer to the ->next pointer of the node I wish to remove, therefore "skipping" it and removing it from the list.
At the moment my for loop does not seem to be working. After the the for loop has run, the value of temp->data is always the data of the second node in the list.
for example, with the list of nodes
15
14
13
12
11
10 (10 being the start of the list)
if I want to remove at the index of 4.
temp->data returns 11, instead of 14.
Here is the code I have:
NODE * removeAt(NODE * pList, int index)
{
NODE * temp = pList;
for (int i = 0; i < index - 1; i++)
{
temp = temp->next;
}
NODE * next = temp->next->next;
temp->next = next;
return temp;
}
Any help is appreciated!
First of all, you have an indexing convention problem. If you say you expect the-next-after-removed to be 14, that means you want to remove the number 13. But it is a number 3 if you start from 0.
You say "My idea is to locate the node one before the node at the index I wish to remove". Imagine you want to remove the start node (data=10), will your idea work here? There is no any "one before" node in this case. Same about the last. There would be no the-next-after-removed.
Also, you need to check for null pointers everywhere. And you must destroy the removed node to avoid memory leaks.
And you need to check how do you insert nodes. Is the start one really 10?
I would improve your code like this:
#include <iostream>
#include <vector>
using namespace std;
struct NODE
{
int data;
NODE * next;
};
NODE * removeAt(NODE * pList, int index)
{
if (!pList)
return nullptr;
NODE * temp = pList;
if (index == 0)
{
temp = pList->next;
std::cout << "removing " << pList->data << endl;
delete pList;
return temp;
}
// after this loop temp points to the node before
for (int i = 0; i < index -2; i++)
{
temp = temp->next;
if (!temp || !temp->next) // to guarantee both the-node-before and the-node-to-remove exist
return nullptr;
}
NODE * next = temp->next->next;
std::cout << "removing " << temp->next->data << endl;
delete temp->next;
temp->next = next;
return next;
}
int main()
{
std::vector<int> vec {15, 14, 13, 12, 11, 10};
NODE * root = nullptr;
for (const int v : vec)
{
std::cout << v << ' ' << endl;
NODE * cur = new NODE;
cur->data = v;
cur->next = root;
root = cur;
}
removeAt(root, 4);
return 0;
}
This is my attempt
// Return a pointer to node with the largest value.
// You may assume list has at least one element
Node * pointerToMax(LinkedList *list) {
assert(list!=NULL);
assert(list->head != NULL);
Node *p, *q;
p = list->head;
q = list->head;
int max = q->data;
while(p != NULL){
if(p->data > max){
max = p->data;
}
return p;
p = p->next;
}
}
Here are the struct definitions.
struct Node {
int data;
Node *next;
};
struct LinkedList {
Node *head;
Node *tail;
};
I'm trying to figure out how to return a pointer that points to the largest value, but I can't exactly figure out how to return the pointer to variable max, and I'm not even sure if the max variable is being updated correctly.
You want something like this:
Node *maxNode = p;
int max = p->data;
while(p != NULL){
if(p->data > max){
max = p->data;
maxNode = p;
}
p = p->next;
}
return maxNode;
There is no reason to return in your while loop. We don't know what the max Node is until we've looped through all the nodes.
I have a list and I want to display it's values.
I want to see 1 2 3 4, but I have a endless loop like 1 2 3 4 1 2 3 4 1 2..
Can't understand, why?
struct node
{
int item;
node *next;
node(int x, node *t)
{
item = x;
next = t;
}
};
int main()
{
node *firstElement = new node(1, NULL);
firstElement->next = firstElement;
node *lastElement = firstElement;
for (int i = 2; i < 5; i++)
lastElement = (lastElement->next = new node(i, firstElement));
for (node *first = lastElement; first != 0; first = first->next)
cout << first->item << " ";
delete firstElement;
return 0;
}
Try using this code:
struct node
{
int item;
node *next;
node(int x, node *t)
{
item = x;
next = t;
}
};
int main()
{
node *firstElement = new node(1, NULL);
node *lastElement = firstElement;
for (int i = 2; i < 5; i++)
lastElement = (lastElement->next = new node(i, nullptr));
for (node *first = firstElement; first != 0; first = first->next)
cout << first->item << " ";
return 0;
}
IdeOne live code
The problem is that you set the "next" link of your last node to this node itself, not nullptr.
Also, it's better to delete the memory allocated
The problem is that your data structure has an infinite loop in itself: this line
firstElement->next = firstElement;
makes firstElement point back to itself, creating a circular list. When you add more elements, your list remains circular, so exit condition first == 0 is never achieved.
If you want your list to remain linear, not circular, your insertion code should be modified as follows:
node *firstElement = new node(1, NULL);
node *lastElement = firstElement;
for (int i = 2; i < 5; i++) {
lastElement->next = new node(i, lastElement->next)
lastElement = lastElement->next;
}
The printing code should start with firstElement:
for (node *current = firstElement; current != 0; current = current->next)
cout << current->item << " ";
Finally, deleting a single firstItem is not sufficient. You need a loop to traverse the whole list. Alternatively, you could chain deletion in the destructor by calling delete next, but this is dangerous, because recursive invocation of destructors may overflow the stack.
You have a loop in your list, because lastElement->next always points to firstElement. This is why first will never be equal to 0.
If you really need a loop I think you should write something like this:
node* p = firstElement;
do {
cout << p->item << " ";
p = p->next;
} while (p != firstElement);
The problem is that you create every node with firstElement as its next.
This would make sense if you were adding nodes to the front of the list, but you're adding them at the back, so the last node will point back to the start.
Since you're adding to the back, terminate the list on every insertion instead:
lastElement->next = new node(i, nullptr))