Linked List - no errors but a few warning

Hello again, I have been working on this linked list code for the last few hours and at first it read in garbage and all which I'm use to seeing, but now that I've completed the code it doesn't return 0, I receive some long negative value and my output file has zero data in it. Not even my headers. If you don't mind would you kindly assist in helping me find my bug?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
#include <iostream>
#include <iomanip>
#include <fstream>
#include <stdio.h>

using namespace std;

ifstream inf("List.in");
ofstream out("List.out");

struct Node
{
    int num;
    int cnt;
    Node* link;
};

class List
{
    public://allows everything access to the following data
    List();//Constructor
    Node *head;//start of the Link List
    int sz();//Size of the Link List
    void insrt(int val);//Inserts value into the Link List
    double average();//Avg of the Link List
    void del(int val);//Deletes value from Link List
    void print();//Prints the data
    void Remove5s();//Removes the Multiples of 5's
    ~List();//Destructor
};

List::List()
{
    //Constructor initializes head to nullptr.
    List* head = nullptr;
}

int List::sz()
{
    int cnt = 0;
    Node* cur = head;
    while(cur != nullptr)
    {
        cnt++;
        cur=cur->link;
    }
    return cnt;
}

void List::insrt(int val)
{
    Node* prev = nullptr;
    Node* curr = head;
    while(curr != nullptr && val < curr->num)//finds location to insert
    {
        if(val == curr->num)
        {
            curr->cnt++;
            return;
        }
        else
        {
            prev = curr;
            curr = curr->link;
        }
    }
    Node* New = new Node();//Creates new node to be inserted
    New->num = val;
    New->cnt = 1;
    New->link = curr;

        if(prev = nullptr)
            head = New;
        else
            prev->link = New;
}

double List::average()
{
    double avg = 0;
    int n = sz();
    Node* curr = head;
    while(curr != nullptr)
    {
        avg += curr->num;
        curr = curr->link;
    }
    if(n != 0)
    {
        avg /= n;
    }
    return avg;
}

void List::del(int val)
{
    Node* prev = nullptr;
    Node* curr = head;
    while(curr != nullptr)
    {
        if(val == curr->num)
            return;
        else if(val < curr->num)
            return;
        else
        {
            prev = curr;
            curr = curr->link;
        }
    }
    if(curr == nullptr)
        return;
    if(prev == nullptr)
        head = curr->link;
    delete curr;
}

void List::Remove5s()
{
    Node* prev = nullptr;
    Node* curr = head;
    while(curr != nullptr)
    {
        if(curr->num % 5 == 0)
        {
            if(prev == nullptr)
                head = curr->link;
            else
                prev->link = curr->link;
                Node* next = curr->link;
                delete curr;
                curr = next;
        }
        else
        {
            prev = curr;
            curr = curr->link;
        }
    }
}

void List::print()
{
    int n = sz();
    Node* curr = head;
    for(int i=1; i<=n; i++)
    {
        out << curr->num << "-" << curr->cnt << "\t";
        curr = curr->link;
        if(i%10 ==0)
        {
            out << endl;
        }
    }
    out << endl;
}

List::~List()
{
    Node* t;
    while(head != nullptr)
    {
        t = head->link;
        head = t;
    }
}

int main()
{
    List order;
    int num;
    while(inf >> num)
    {
        order.insrt(num);
    }
    out << "Number of NODES = " << order.sz()
        << "\nAverage = " << order.average()
        << "\nMultiples of 5 have been deleted\n";
    order.Remove5s();
    order.print();
    out << "Number of NODES = " << order.sz()
        << "\nAverage = " << order.average() << endl;

    inf.close();
    out.close();
    return 0;
}

INFILE //Deleted over half to save room
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
2 28 15 21 10 5 39 39 3 25 26 26 2 28 2 12 36 23 28 37 32 5 23 34 13
23 22 37 39 16 8 7 12 19 30 33 28 20 36 15 24 12 3 14 34 25 22 32 14 29
28 5 23 38 38 20 4 22 10 19 37 36 31 3 9 27 1 23 25 9 7 6 11 10 11
31 7 22 34 29 30 24 5 35 37 1 7 17 12 29 25 40 27 4 18 19 39 3 10 22
34 36 40 19 25 11 18 27 34 27 22 26 5 33 31 30 18 14 18 33 27 11 2 37 36
8 16 15 32 13 31 31 22 5 7 31 28 32 8 18 18 8 34 24 26 30 10 39 22 29
23 27 27 31 14 9 21 32 3 16 11 40 25 18 29 4 36 2 3 31 12 37 15 21 37
22 29 40 29 5 2 15 14 40 19 19 21 29 8 28 9 14 9 4 8 22 31 18 14 35
30 17 16 12 1 10 40 37 39 24 25 9 5 10 30 23 36 6 14 24 4 28 35 24 9
1 19 19 21 37 39 2 30 39 10 38 33 23 19 13 39 20 31 18 39 32 16 9 37 32
3 35 33 16 9 7 3 7 36 34 30 23 5 17 2 39 3 12 22 20 38 37 13 30 36
33 1 31 4 30 22 9 2 30 16 24 3 26 23 6 9 27 18 38 33 13 10 35 2 30
17 10 9 13 26 36 35 30 2 33 26 21 39 34 20 24 40 37 8 10 30 38 27 30 34
36 18 17 7 26 9 3 16 15 35 22 37 32 27 24 34 36 26 14 33 9 33 26 34 37
2 39 7 23 2 25 37 23 10 2 16 11 14 27 5 20 13 40 14 25 35 31 26 10 27
34 35 23 9 19 28 26 39 32 3 26 38 15 35 25 15 35 13 40 34 31 8 18 39 18
14 31 4 29 33 26 23 1 14 28 3 20 8 26 24 5 24 13 22 22 4 33 26 34 6
32 13 23 23 7 25 21 28 1 14 15 31 11 36 34 32 1 17 28 6 31 21 15 16 25
20 6 17 15 19 23 12 27 39 34 12 5 19 25 40 33 1 8 21 7 11 38 11 36 17
28 4 39 5 30 3 7 6 8 18 35 26 28 30 9 24 1 23 3 4 37 18 22 36 6
25 21 3 37 31 7 12 12 12 28 34 1 31 5 29 4 21 12 23 30 21 34 39 19 6
8 38 1 19 40 24 1 38 5 38 29 34 8 2 11 21 29 34 25 6 21 32 25 36 37
33 31 24 6 37 17 27 38 7 38 18 32 30 2 17 23 18 33 38 17 26 2 24 10 30
6 40 13 17 16 14 3 25 15 15 13 18 10 13 4 8 4 32 36 28 9 36 19 24 23
35 32 22 16 20 26 22 31 27 15 6 24 11 39 40 22 34 15 38 15 37 34 17 26 3
29 2 21 14 2 16 16 23 23 12 38 25 39 33 4 17 34 1 34 36 33 19 11 18 13
33 16 10 32 1 9 6 11 18 30 31 26 34 35 12 21 5 19 16 40 33 6 25 22 24
30 16 9 13 38 30 37 2 28 28 22 10 1 14 15 2 38 16 4 14 33 25 2 33 40
31 29 28 5 36 27 19 11 8 8 5 24 22 24 27 4 11 12 10 1 5 23 20 34 32


Assignment

I have a list of numbers that I need to know two things, what numbers I have in the list and how many of each number do I have in the list. So you are to read in each number and add the number to an ordered link list. Now, if you are adding a number to the list and you find that number, then you will just count it. If you do not find the number in the link list, then you will add a new node to the link list with the new number and set the count to one.

The structure/class will have three fields; the number, a counter, the counter is used to keep count of how many of this number exist and of course a link field.

1. Print out the values and their counts say 8 per line.
Example 5 – 22 8 – 15 13 – 5 22 – 3 25 – 18 where the 5 is the number and 22 is its count (ie there were 22 number 5’s in the list). Label output please.

2. Print out the number of nodes in the link list and the average for the values. (5-22 is 5 values
to count in sum and average.)
3. Now, go through the link list and delete any node with a value that is a multiple of 5.
4. Print out the number of nodes in the new link list.
5. Travers the new link list and print out the number of values in the list and the average.
||=== Build file: "no target" in "no project" (compiler: unknown) ===|
|18|warning: 'class List' has pointer data members [-Weffc++]|
|18|warning: but does not override 'List(const List&)' [-Weffc++]|
|18|warning: or 'operator=(const List&)' [-Weffc++]|
||In constructor 'List::List()':|
|32|warning: 'List::head' should be initialized in the member initialization list [-Weffc++]|
|35|warning: unused variable 'head' [-Wunused-variable]|
||In member function 'void List::insrt(int)':|
|72|warning: suggest parentheses around assignment used as truth value [-Wparentheses]|
||=== Build finished: 0 error(s), 6 warning(s) (0 minute(s), 1 second(s)) ===|
Last edited on
if it compiles and runs, the first error is a mystery, as it tells me the IDE may not be set up correctly, but then it worked, so maybe its fine, unclear what that is about? Does it compile and run?

the bulk of those warnings are harmless. Lets ignore them until you get it working, then you can fix on them. the 18s are rather important long term, but in the short term, if you don't use the affected items, they won't make trouble for you.

you are doing too much to debug it.
take it one bit at a time in main, see what works, and what does not.
can you read the file and print it back to the screen? change line 174 to cout << num << endl; and see if you get the file's contents back out.
if that works, put it back, and call order.print() after you read the file and inserted all the data. Does your list have the data in it? If so, then we can look deeper.
Just some things I noticed in a quick perusal. There's probably more problems.
* You don't need to include stdio.h.
* List 35: get rid of List*
* List 56: this will never be true
* Line 72: change = to ==.
Those compiler warnings are not all that mysterious, and they are not a sign that the IDE is not setup properly.

Those first few warnings are not necessarily harmless either. They are telling you that you haven't taken precautions required to insure proper deep copy or assignment of your class objects.

That last warning is telling you that you're using the assignment operator= where the comparison operator== is normally seen and is probably an error.


Never ignore warnings, always, always fix them.

Either add the copy and assignment operators or mark them as not necessary.

Learn to use initialization lists in your class constructors, they can avoid unnecessary copying of member variables during construction.

Either add the suggested parentheses or change the operator in your if() statement.

And lastly you really should avoid global variables whenever possible learn to properly pass the required values to and from your functions.
after dutch's fixes your insert seems to be working; I got the list to print using my own function but not yours.
Im not sure what that for loop is supposed to DO, so I leave you with mine:

1
2
3
4
5
6
7
8
9
10
void List::print()
{	
	Node* curr = head;
	while(curr)
	{
	 cout << curr->num << endl;
         curr = curr->link;	 
	} 
}
	


Never ignore warnings, always, always fix them.
Better advice than mine, it seems -- the == problem was right there and I missed it in the clutter. I was just trying to suggest fixing what you have before trying to add fixes for the copy problems. I work these kind of problems by getting it to compile and run first, before adding more stuff to broken code, is all.
Last edited on
@Jonin, Dutch, JIB; thank you all for the input, the program at least returns 0 and produces something. It's not quite how I need it yet, but I'll get there.

Here's a condensed print out, as it's a lot of data to scroll through.
OUTPUT
1
2
3
4
5
6
7
8
9
10
11
12
13
14
40-1	40-1	40-1	40-1	40-1	40-1	40-1	40-1	40-1	40-1	
40-1	40-1	40-1	40-1	40-1	40-1	40-1	40-1	40-1	40-1	
40-1	40-1	40-1	40-1	40-1	40-1	40-1	40-1	40-1	40-1	
40-1	40-1	40-1	40-1	40-1	40-1	40-1	40-1	40-1	40-1	
40-1	40-1	40-1	40-1	40-1	40-1	40-1	40-1	40-1	40-1	
40-1	40-1	40-1	40-1	40-1	40-1	40-1	40-1	40-1	40-1	
40-1	40-1	40-1	40-1	40-1	40-1	40-1	40-1	40-1	40-1	
40-1	40-1	40-1	40-1	40-1	40-1	40-1	40-1	40-1	40-1	
40-1	40-1	40-1	40-1	40-1	40-1	40-1	40-1	39-1	39-1	
39-1	39-1	39-1	39-1	39-1	39-1	39-1	39-1	39-1	39-1	
39-1	39-1	39-1	39-1	39-1	39-1	39-1	39-1	39-1	39-1	
39-1	39-1	39-1	39-1	39-1	39-1	39-1	39-1	39-1	39-1	
39-1	39-1	39-1	39-1	39-1	39-1	39-1	39-1	39-1	39-1	
39-1	39-1	39-1	39-1	39-1	39-1	39-1	39-1	39-1	39-1	

As you can see the nodes aren't incrementing when it reads the same value.

EDIT: I think the issue is in the Insert function. I think when it notices the value of the number it just adds a new link rather than add it to count.
Last edited on
I found the issue. It is within the Insert function. Can someone further explain why this is happening?

Original Code
1
2
3
4
5
6
7
8
9
10
11
12
13
 while(curr != nullptr && val < curr->num)//finds location to insert
    {
        if(val == curr->num)
        {
            curr->cnt++;
            return;
        }
        else
        {
            prev = curr;
            curr = curr->link;
        }
    }

New Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
while(curr != nullptr)//finds location to insert
    {
        if(val == curr->num)
        {
            curr->cnt++;
            return;
        }
        else if(val < curr->num)
            break;

        else
        {
            prev = curr;
            curr = curr->link;
        }
    }


Last edited on
Now the only concern I see is that the second average of the nodes is just an int value, when it's set at double.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
		Linked List Program
1-99	2-111	3-93	4-102	5-89	6-101	7-83	8-97	
9-110	10-96	11-104	12-100	13-94	14-112	15-81	16-109	
17-93	18-95	19-103	20-79	21-89	22-109	23-112	24-102	
25-107	26-101	27-101	28-94	29-97	30-112	31-106	32-96	
33-107	34-112	35-101	36-97	37-98	38-104	39-116	40-88	
Number of NODES = 40
Average = 20.5

Multiples of 5 Removed
1-99	2-111	3-93	4-102	6-101	7-83	8-97	9-110	
11-104	12-100	13-94	14-112	16-109	17-93	18-95	19-103	
21-89	22-109	23-112	24-102	26-101	27-101	28-94	29-97	
31-106	32-96	33-107	34-112	36-97	37-98	38-104	39-116	
Number of NODES = 32
Average = 20
Presumably the average is exactly 20, so no decimals are shown.
If you want a fixed number of decimals to be displayed, try:
 
out << fixed << setprecision(2);  // show 2 positions after the decimal point 

It only needs to be done once, so put it before your first out << ....
IN the snippet above I use break, is there an alternative to break?
Well if you used the correct comparison operation in that first snippet it would probably do the trick. After all when will curr ever be a nullptr AND val < curr->num?

Perhaps you meant OR?


Thank you jib! I forget about all the things one can utilize in the code.
I tried the or and still receive return -some large number.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
 while((cur != nullptr) || (val < cur->num))//finds location to insert
    {
        if(val == cur->num)
        {
            cur->cnt++;
            return;
        }

        else
        {
            prev = cur;
            cur = cur->link;
        }
    }
Please show the output and be sure to explain what is wrong with that output.

Edit: Also post the entire code so I can be sure I'm looking at the same thing you are working with.




Last edited on
when I put the ||(or) into the while statement instead of the &&, the output is nothing it returns a large negative number which inturn makes the outfile empty. But if I leave the statement with the "break" it works just fine.

You are looking at the same thing, the OP code is still relatively the same code just a few changes that were suggested by others.

I just wanted to find an alternative than using break(prof dislikes the use of that)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
#include <iostream>
#include <iomanip>
#include <fstream>

using namespace std;

ofstream out("List.out");

struct Node
{
    int num;
    int cnt;
    Node* link;
};

class List
{
    public://allows everything access to the following data
    List();//Constructor
    Node *head;//start of the Link List
    int sz();//Size of the Link List
    void insrt(int val);//Inserts value into the Link List
    double average();//Avg of the Link List
    void del(int val);//Deletes value from Link List
    void print();//Prints the data
    void Remove5s();//Removes the Multiples of 5's
};

List::List()
{
    //Constructor initializes head to nullptr.
    head = nullptr;
}

int List::sz()
{
    int cnt = 0;
    Node* cur = head;
    while(cur != nullptr)
    {
        cnt++;
        cur=cur->link;
    }
    return cnt;
}

void List::insrt(int val)
{
    Node* prev = nullptr;
    Node* cur = head;
    while(cur != nullptr)//finds location to insert //Tried to use || but it doesn't 
    {                                                              //return 0.
        if(val == cur->num)
           {
               cur->cnt++;
               return;
           }
        else if(val < cur->num)   //This statement is what I would like to 
            break;                       //change to be used without break
        else
        {
            prev = cur;
            cur = cur->link;
        }
    }
    Node* New = new Node();//Creates new node to be inserted
    New->num = val;
    New->cnt = 1;
    New->link = cur;

        if(prev == nullptr)
            head = New;
        else
            prev->link = New;
}

double List::average()
{
    double avg = 0;
    int temp = sz();
    Node* cur = head;
    while(cur != nullptr)
    {
        avg += cur->num;
        cur = cur->link;
    }
    if(temp != 0)
        avg /= temp;
    return avg;
}

void List::del(int val)
{
    Node* prev;
    Node* cur ;
    while(cur != nullptr)
    {
        prev = cur;
        cur = cur->link;
    }
    if(prev == nullptr)
        head = cur->link;
    else
        prev->link = cur->link;
    delete cur;
}

void List::Remove5s()
{
    Node* prev = nullptr;
    Node* cur = head;
    while(cur != nullptr)
    {
        if(cur->num % 5 == 0)
        {
            if(prev == nullptr)
                head = cur->link;
            else
                prev->link = cur->link;
                Node* next = cur->link;
                delete cur;
                cur = next;
        }
        else
        {
            prev = cur;
            cur = cur->link;
        }
    }
}

void List::print()
{
    int n = sz();
    Node* cur = head;
    for(int i=1; i <= n; i++)
    {
        out << cur->num << "-"
            << cur->cnt << "\t";

        cur = cur->link;
        if(i%8 == 0)
            out << endl;
    }
}

int main()
{
    ifstream inf("List.in");
    if(!inf)
        cout << "Error Opening Specs File";

    out << "\t\tLinked List Program\n";

    List order;
    int num;

    while(inf >> num)
        order.insrt(num);

    order.print();//Prints and orders the infile
    out << "Number of NODES = " << order.sz()
        << "\nAverage = " << order.average()
        << "\n\nMultiples of 5 Removed\n";

    order.Remove5s();
    order.print();
    out << "Number of NODES = " << order.sz()
        << "\nAverage = " << order.average();

    inf.close();
    out.close();
    return 0;
}

/*
OUTPUT:
    		Linked List Program
1-99	2-111	3-93	4-102	5-89	6-101	7-83	8-97
9-110	10-96	11-104	12-100	13-94	14-112	15-81	16-109
17-93	18-95	19-103	20-79	21-89	22-109	23-112	24-102
25-107	26-101	27-101	28-94	29-97	30-112	31-106	32-96
33-107	34-112	35-101	36-97	37-98	38-104	39-116	40-88
Number of NODES = 40
Average = 20.5

Multiples of 5 Removed
1-99	2-111	3-93	4-102	6-101	7-83	8-97	9-110
11-104	12-100	13-94	14-112	16-109	17-93	18-95	19-103
21-89	22-109	23-112	24-102	26-101	27-101	28-94	29-97
31-106	32-96	33-107	34-112	36-97	37-98	38-104	39-116
Number of NODES = 32
Average = 20
*/
Last edited on
Topic archived. No new replies allowed.