Welcome to Code Forum!

Join a community that supports you and your coding journey from day one. We strive to be a friendly, supportive community that empowers everyone to be better developers. By registering with us, you'll be able to discuss, share and private message with other members of our community.

SignUp Now!
  • Guest, before posting your code please take these rules into consideration:
    • It is required to use our BBCode feature to display your code. While within the editor click < / > or >_ and place your code within the BB Code prompt. This helps others with finding a solution by making it easier to read and easier to copy.
    • You can also use markdown to share your code. When using markdown your code will be automatically converted to BBCode. For help with markdown check out the markdown guide.
    • Don't share a wall of code. All we want is the problem area, the code related to your issue.

    GIF shows where to locate </> in the thread and or post editor toolbar.
    To learn more about how to use our BBCode feature, review our "How to post your code into threads" here.

    Thank you, Code Forum.

C++ Please help with Linked list sorted insert (C++)

I am in a C++ object oriented programming class and we were assigned a program that stores a singly linked list with "Fruit" as the data. Each fruit has a *char name and a char code[4]. No matter what I try, when I try to insert a new Fruit into a list that already has one or more fruits in it, the list is completely taken over by the new Fruit that is being added. That is, the list has the correct number of elements, but they are all the most recently added element. We are limited to the exact function that are there for the linked list (type and parameters) but I am allowed to change the inside.
[CODE lang="cpp" title="LList.cpp"]#include "LList.h"
#include "LeakWatcher.h"
using namespace std;
typedef Fruit InfoType;
LList::~LList() {
while (list) {
Node* n = new Node(list->infoPtr, list->next);
if (n->next)
{
list = list->next;
delete n;
}
else
delete list;
}
}
LList::LList(const LList& copyFrom)
{
Node* i = copyFrom.list;
while (i)
{
Node* n = new Node(i->infoPtr, i->next);
if(!this->list)
{
this->list = n;
}
else
{
list->next = n;
list = n;
}
i = i->next;
}
}
bool LList::IsEmpty() const {
return (list == NULL);
}
bool LList::Insert(InfoType* x_ptr)
{
if (IsEmpty())
{
Node* n = new Node(x_ptr, NULL);
list = n;
//cout << "list is: " << list->infoPtr << endl;
return true;
}
else if (list->next == NULL)
{
if (x_ptr < list->infoPtr)
{
Node* n = new Node(x_ptr, NULL);
}
}
else
{
Node *current = list;
while (current->next != NULL && current->next->infoPtr < x_ptr)
current = current->next;
if (current->infoPtr != x_ptr)
{
x_ptr->~Fruit();
return false;
}
else
{
Node* aft = current->next;
Node* w = new Node(x_ptr, NULL);
w->next = aft;
current->next = w;
//cout << "list is: " << list->infoPtr << endl;
return true;
}
}
}
bool LList:😀elete(const InfoType& x)
{
if (list == NULL)
return false;
else
{
Node* toDelete = new Node(list->infoPtr, list->next);
Node* prev = new Node(list->infoPtr, list->next);
while (*toDelete->infoPtr != x || toDelete == NULL)
{
prev = toDelete;
toDelete = toDelete->next;
}
if (toDelete == list)
{
list = list->next;
toDelete->~Node();
return true;
}
else if (toDelete)
{
prev->next = toDelete->next;
toDelete->next = NULL;
toDelete->~Node();
return true;
}
else
{
x.~Fruit();
return false;
}
}
}

void LList:😀isplay(ostream& out_stream) const
{
out_stream << "Below are the fruits currently in the list" << endl;
Node *ptr = list;
while (ptr != NULL)
{
out_stream << ptr->infoPtr << endl;
ptr = ptr->next;
}
out_stream << endl;
}

LList& LList:😱perator=(const LList& assignFrom)
{
this->list = assignFrom.list;
return *this;
}
[/CODE]
[CODE title="Fruit.cpp"]#include "Fruit.h";
#include <stdio.h>
#include <string>
#include "LeakWatcher.h"
using namespace std;
Fruit::Fruit() {
name = NULL;
*code = { 0 };
}
Fruit::~Fruit() {
delete name;
}
Fruit::Fruit(const Fruit& copyfrom)
{
Fruit* temp = new Fruit();
this->name = copyfrom.name;
*this->code = *copyfrom.code;
*this = *temp;
}
bool Fruit:😱perator<(Fruit const& obj)
{
return(strcmp(name, obj.name) < 0);
}
bool Fruit:😱perator==(Fruit const& obj)
{
return(strcmp(name, obj.name) == 0);
}
bool Fruit:😱perator!=(Fruit const& obj)
{
return (strcmp(name, obj.name) != 0);
}

Fruit Fruit:😱perator=(Fruit const& obj)
{
Fruit n = Fruit();
n.name = obj.name;
for (int i = 0; i < CODE_LEN; i++)
n.code = obj.code;
return n;
}

ostream& operator<<(std:😱stream& out, Fruit* f)
{
out << setiosflags(ios::left) << setw(MAX_NAME_LEN) << f->name;
for (int i = 0; i < CODE_LEN; i++)
out << f->code;
return out;
}
istream& operator>>(std::istream& in, Fruit* f)
{
char* temp = new char[MAX_NAME_LEN];
in >> temp;
for (int i = 0; i < CODE_LEN; i++)
in >> f->code;
f->name = temp;
return in;
}[/CODE]
 
Hello!

Lines 47-53:
C++:
   else if (list->next == NULL)
   {
      if (x_ptr < list->infoPtr) // Why are you testing that?
      {
         Node* n = new Node(x_ptr, NULL); // You do nothing with it....
      }
   }

There are a couples of things that does not make much sense. First, when you delete an object allocated with 'new', you must use 'delete'. So replace the following:
x_ptr->~Fruit();
By:
delete x_ptr;

Lines 57-58:
C++:
while (current->next != NULL && current->next->infoPtr < x_ptr)
    current = current->next;
Here: current->next->infoPtr < x_ptr. Why are you comparing the address of the objects? The address does not matter.
 
Hello!

Lines 47-53:
C++:
   else if (list->next == NULL)
   {
      if (x_ptr < list->infoPtr) // Why are you testing that?
      {
         Node* n = new Node(x_ptr, NULL); // You do nothing with it....
      }
   }

There are a couples of things that does not make much sense. First, when you delete an object allocated with 'new', you must use 'delete'. So replace the following:
x_ptr->~Fruit();
By:
delete x_ptr;

Lines 57-58:
C++:
while (current->next != NULL && current->next->infoPtr < x_ptr)
    current = current->next;
Here: current->next->infoPtr < x_ptr. Why are you comparing the address of the objects? The address does not matter.
Yeah, I realized that I should not have kept 47-53 in there after I posted this. As for lines 57-58, I'm still new to the whole pointer thing, so I'm not always 100% sure what to put where. should I make all of the comparisons like this?
*current->next->infoPtr < *x_ptr
 
Oh, did you learn C before? Learning classes is hard if you are not comfortable with the basics such as pointers (Well, it is hard even if you do ahah).

Yes! If you want to compare the Fruit objects, you must do it like that! If you do not 'access' the object by dereferencing the pointer, what will be compared will be its memory address.

Is it your second C++ course/session? If so, your assignment seems pretty complex xD.
 
Oh, did you learn C before? Learning classes is hard if you are not comfortable with the basics such as pointers (Well, it is hard even if you do ahah).

Yes! If you want to compare the Fruit objects, you must do it like that! If you do not 'access' the object by dereferencing the pointer, what will be compared will be its memory address.

Is it your second C++ course/session? If so, your assignment seems pretty complex :laugh:.
yeah this is my second C++ course:laugh:. Thanks for the help, but I'm still not sure why the list is overwriting the Fruit/InfoType part of itself. I trimmed it down to what other sites have said inserting in a single linked list should be, but it still does the same thing
[CODE title="LList.cpp, Insert"]bool LList::Insert(InfoType* x_ptr)
{
if (IsEmpty())
{
Node* n = new Node(x_ptr, list);
list = n;
//cout << "list is: " << list->infoPtr << endl;
return true;
}
/*else if (list->next == NULL)
{
if (*x_ptr < *list->infoPtr)
{
Node* n = new Node(x_ptr, list);
return true;
}
else if (*list->infoPtr != *x_ptr)
{
delete x_ptr;
return false;
}
else
{
Node* n = new Node(x_ptr, NULL);
list->next = n;
return true;
}
}*/
else
{
Node* current = list;
while (current->next != NULL && *current->next->infoPtr < *x_ptr)
current = current->next;
if (*current->infoPtr != *x_ptr)
{
return false;
}
else
{
Node* w = new Node(x_ptr, current->next);
current->next = w;
//cout << "list is: " << list->infoPtr << endl;
return true;
}
}
}[/CODE]
 
I do not understand why you write && *current->next->infoPtr < *x_ptr in the line 32?

At the line 40-41, I think you should write the following instead:
C++:
Node* w = new Node(x_ptr, list);
list = w;
 
Last edited:
I do not understand why you write && *current->next->infoPtr < *x_ptr in the line 32?

At the line 40-41, I think you should write the following instead:
C++:
Node* w = new Node(x_ptr, list);
list = w;
For line 32, we also need to have the list sorted, and for Fruit class I overloaded the < so that it says whether the left is alphabetically before the right or not. For line 40-41, isn't that for if the list is empty? Since I need to sort it, I need to make sure I am putting it in front of current, right?
 
For line 32, we also need to have the list sorted, and for Fruit class I overloaded the < so that it says whether the left is alphabetically before the right or not. For line 40-41, isn't that for if the list is empty? Since I need to sort it, I need to make sure I am putting it in front of current, right?
Yeah ok, I missunderstood how your list was implemented.
 
I figured it out, this inserts and sorts them, while not allowing repeats. Thanks for the help
[CODE title="LList.cpp, Insert"]bool LList::Insert(InfoType* x_ptr)
{
if (IsEmpty())
{
Node* n = new Node(x_ptr, list);
list = n;
return true;
}
else
{
if (*list->infoPtr == *x_ptr)
return false;
else
{
Node* current = list;
while (current->next != NULL && *current->next->infoPtr < *x_ptr)
current = current->next;
if (current->next != NULL && *current->next->infoPtr == *x_ptr)
return false;
else {
Node* w = new Node(x_ptr, current->next);
current->next = w;
return true;
}
}
}
}[/CODE]
 
I figured it out, this inserts and sorts them, while not allowing repeats. Thanks for the help
[CODE title="LList.cpp, Insert"]bool LList::Insert(InfoType* x_ptr)
{
if (IsEmpty())
{
Node* n = new Node(x_ptr, list);
list = n;
return true;
}
else
{
if (*list->infoPtr == *x_ptr)
return false;
else
{
Node* current = list;
while (current->next != NULL && *current->next->infoPtr < *x_ptr)
current = current->next;
if (current->next != NULL && *current->next->infoPtr == *x_ptr)
return false;
else {
Node* w = new Node(x_ptr, current->next);
current->next = w;
return true;
}
}
}
}[/CODE]
I did not help much, but I am glad you found out the problem!
 
Back
Top Bottom