Help with a linked list problem

(I originally posted this in the beginner forum section but I think it should have been posted here instead after reading the rules more not completely sure though.)

Hello Everyone,

I have a project due for a class and I'm not asking for direct answers but I'm asking for whatever help I can get and coding examples would be appreciated or something to point me in the right direction. This project is over linked lists and dynamic arrays in C++. The part I am stuck on is creating a function to organize "packages" I was given two structs:
// Package_Node struct to create a list of packages
struct Package_Node
{
int bar_code;
float package_weight;
struct Package_Node *next_package;
};

// Key_Node struct to store key information for dynamic array of keys
struct Key_Node
{
int key = 0;
struct Package_Node *next_package;
};

The Key_Node struct is supposed to be used to create a dynamic array based off a user input for a number of keys. I'm supposed to generate the barcodes by doing a random number between 1 and Max Value. The package weights are calculated as a random float between 1 and 500. I'm supposed to organize the packages barcode and weight by placing them in the key generated from barcode % X.

The way it's supposed to look is like this:
Array of keys is created and for example looks like this
0
1
2

Then once I run organize packages, let's say the user entered 4 for X keys. Once the packages are made and done they get placed into the according keys and the table is supposed to look like this when I print all the information:
0 -> 4 - 32.0
1 -> 15 - 405.5
2 -> 14 - 44.5 -> 18 - 200.0

I should note that I was told my ArrayOfKeys function is correct for what I need so I mainly just need to figure out the other part.

I hope this is enough information to give you guys an idea of what I'm looking for. I'm really stuck on this and even though I kind of know how to do some basic linked lists I'm really struggling on how to implement a method to insert things into the specific keys and how it all links together.

If you need more information or anything let me know, I hope I gave enough of what was needed. Thank you for any help I can get, I'd like to improve since right now I'm definitely not very good at this.

The Issues I am having are at the bottom of my code. I wasn't sure how much to take out or leave in so sorry if it's long :(.


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
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282

#include "stdafx.h" // Visual studio
#include <iostream> // NULL, cin, cout etc.
#include <time.h> // time
#include <stdlib.h> // srand, rand
#include <array> // arrays
using namespace std;

// Package_Node struct to create a list of packages
struct Package_Node
{
	int bar_code;
	float package_weight;
	struct Package_Node *next_package;
};

// Key_Node struct to store key information for dynamic array of keys
struct Key_Node
{
	int key = 0;
	struct Package_Node *next_package;
};
//Defines Nodeptr to Package_Node for use to make the linked list
typedef Package_Node* Nodeptr;

//All my functions so far, haven't created the comments to describe each of these but I don't think that'd be an issue
// for the feedback
void menu(int N, int Max_Value, int X, Key_Node *Key_Array, Nodeptr package_info);

void NumOfKeys(int &X, int &Max_Value);

void NumOfPackages(int &N);

void ArrayOfKeys(Key_Node *Key_Array, int X);

void OrganizePackages(Nodeptr package_info, int Max_Value, int X, int N, Key_Node *Key_Array);

void InsertList(Nodeptr& head, Nodeptr& tail, Nodeptr package_info);


int main()
{
	//Initializing variables
	// Total number of packages to create
	int N = 0;
	// Max value for bar codes generated
	int Max_Value = 0;
	//Number of keys for array
	int X = 0;
	//arrayPos to keep track of array index for keys
	Key_Node *Key_Array = nullptr;
	// code and weight to assign values to bar_code and package_weight for Package_Node
	Nodeptr package_info = nullptr;
	menu(N, Max_Value, X, Key_Array, package_info);
	return 0;
}


void menu(int N, int Max_Value, int X, Key_Node *Key_Array, Nodeptr package_info)
{
	// Menu loop to continue loop unless user enters 7
	bool menuLoop = true;
	do
	{
		// base menu
		cout << "What would you like to do?\n";
		cout << "1) Enter number of keys and the Max Value\n";
		cout << "2) Enter number of packages (N)\n";
		cout << "3) Create Array of Keys\n";
		cout << "4) Organize Packages (organizes the N packages)\n";
		cout << "5) Table stats\n";
		cout << "6) Clean table\n";
		cout << "7) Exit\n";

		// User input for choice from menu for use in switch statement
		int choice;
		cin >> choice;

		switch (choice)
		{

			case 1:
			{
				NumOfKeys(X, Max_Value);
				break;
			}

			case 2:
			{
				NumOfPackages(N);
				break;
			}

			case 3:
			{
				ArrayOfKeys(Key_Array, X);
				break;
			}

			case 4:
			{
				// Checks if no keys or number of packages have been entered yet and goes back to menu if not
				if (X == 0 || N == 0)
				{
					cout << "No keys and/or number of packages were entered.\n";
					break;
				}
				else
				{
					OrganizePackages(package_info, Max_Value, X, N, Key_Array);
				}
				break;
			}

			case 5:
			{
				// Extra menu for table choices with another switch statement for user choice
				int tableChoice;
				cout << "What would you like to do with the table?\n";
				cout << "0) Find packages given a bar code\n";
				cout << "1) Total number of objects given a key\n";
				cout << "2) Total weight given a key\n";
				cout << "3) Print List given a key\n";
				cout << "4) Print Entire Table\n";
				cout << "5) Find all package that are greater than a given weight\n";
				cin >> tableChoice;
				switch (tableChoice)
				{
					case 0:
					{
						TableFindPackage();
						break;
					}

					case 1:
					{
						TableTotalNumOfObjects();
						break;
					}

					case 2:
					{
						TableTotalWeight();
						break;
					}

					case 3:
					{
						TablePrintList();
						break;
					}

					case 4:
					{
						TablePrintTable();
						break;
					}

					case 5:
					{
						TableFindGreaterWeight();
						break;
					}

				}
			}

			case 6:
			{
				CleanTable();
				break;
			}

			case 7:
			{
				// Stops loop because user chose to exit
				menuLoop = false;
				break;
			}
		}
	} while (menuLoop == true);
}


void NumOfKeys(int &X, int &Max_Value)
{
	// Asks user for number of keys
	cout << "Please enter the number of keys that will be used: ";
	cin >> X;

	// Asks user for Max Value of barcode
	cout << "\nPlease Enter the Max Value of the barcode: ";
	cin >> Max_Value;
	cout << "\n";
}

void NumOfPackages(int &N)
{
	// Asks user for number of packages
	cout << "Please enter the number of packages (N): ";
	cin >> N;
	// Goes back to menu after user enters information
}

void ArrayOfKeys(Key_Node *Key_Array, int X)
{
	Key_Array = new Key_Node[X];

	// Displays the values in the array created and initializes them to 0, 1 , 2 etc. until user entered key is reached
	cout << "Your array now has the values: \n";
	for (int i = 0; i < X; i++)
	{
		Key_Array->key = i;
		Key_Array->next_package = NULL;
		cout << Key_Array->key << " \n";
	}
}

//** Part where issue starts
void OrganizePackages(Nodeptr package_info, int Max_Value, int X, int N, Key_Node *Key_Array)
{
	// Min value for bar code
	int Min_Value = 1;
	// float values for weight

	//Initializes head and tail to NULL (Not sure if tail is necessary yet)
	Nodeptr head = NULL, tail = NULL;
	//Initialize random seed
	srand(static_cast<unsigned int>(time(NULL)));

	if (package_info->next_package == NULL)
	{
		package_info = new Package_Node;
		// Generate random number between Min_Value and Max_Value for barcode
		package_info->bar_code = rand() % Max_Value + Min_Value;

		// Generate random float weight for package of 1 - 500
		package_info->package_weight = static_cast <float> (rand() % 500 + 1);

		// Places package with information into key
		Key_Array->key = (package_info->bar_code % X);

		// Inserts information into list
		InsertList(head, tail, package_info);
	}

}

//**This is wrong and causes a crash
void InsertList(Nodeptr& head, Nodeptr& tail, Nodeptr package_info)
{
	Nodeptr NewPtr = NULL, tempPtr = NULL;
	while (NewPtr = package_info)
	{
		//Add object to the list
		if (head == NULL)
		{
			//beginning of the list
			head = NewPtr;

			// Current record
			tail = NewPtr;
		}
		else
		{
			//Previous record reference to new record
			{
				tail->next_package = NewPtr;
				// Current Record
				tail = NewPtr;
			}
		}
		// End of the list
		tail->next_package = NULL;

		for (tempPtr = head; tempPtr != NULL; tempPtr = tempPtr->next_package)
		{
			cout << "\n" << (tempPtr->bar_code) << "-" << (tempPtr->package_weight) << "\n";
		}
	}
}
Last edited on
The Key_Node struct is supposed to be used to create a dynamic array based off a user input for a number of keys.

Key_Node is supposed to be an array, but you have it as a list. It needs to be an array of pointers to Package_Node. Ideally you'd use std::vector for this. If you have to code it yourself then Key_Node should be:
1
2
3
4
struct Key_Node {
    int size;
    struct Package_Node **packages;
};


The function prototypes change to:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
//All my functions so far, haven't created the comments to describe each of the\
se but I don't think that'd be an issue
// for the feedback
void menu(int N, int Max_Value, Key_Node &Key_Array);

void NumOfKeys(int &X, int &Max_Value);

void NumOfPackages(int &N);

void ArrayOfKeys(Key_Node &Key_Array, int X);

void OrganizePackages(int Max_Value, int N,
                      Key_Node &Key_Array);

void InsertList(Nodeptr &head, Nodeptr package_info);


ArrayOfKeys just allocates the array:
1
2
3
4
5
6
7
8
9
10
11
12
void
ArrayOfKeys(Key_Node &Key_Array, int X)
{
    Key_Array.packages = new Package_Node*[X];
    Key_Array.size = X;

    cout << "Your array now has the values: \n";
    for (int i = 0; i < X; i++) {
        Key_Array.packages[i] = NULL;
        cout << i << '\n';
    }
}


And OrganizePackages looks like this. Note how I've used package_info->bar_code % Key_Array.size to select which list to insert it in.
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
//** Part where issue starts
void
OrganizePackages(int Max_Value, int N, Key_Node &Key_Array)
{
    // Min value for bar code
    int Min_Value = 1;
    // float values for weight

    //Initialize random seed
    srand(static_cast < unsigned int >(time(NULL)));

    for (int i=0; i<N; ++i) {
        Nodeptr package_info = new Package_Node;
        // Generate random number between Min_Value and Max_Value for barcode
        package_info->bar_code = rand() % Max_Value + Min_Value;

        // Generate random float weight for package of 1 - 500
        package_info->package_weight = static_cast < float >(rand() % 500 + 1);

        // Places package with information into key
        InsertList(Key_Array.packages[package_info->bar_code % Key_Array.size],
                   package_info);
    }

}


And finally, InsertList becomes ridiculously easy, especially since I'm not keeping a tail pointer.
1
2
3
4
5
6
void
InsertList(Nodeptr & head, Nodeptr package_info)
{
    package_info->next_package = head;
    head = package_info->next_package;
}

Maybe I'm missing something here but when I try to display the table with this nothing comes up? This did help me with figuring some things out though I'm just wondering how I would display this information along with the keys like I wrote in the original post because it doesn't seem like the information is stored for that.

What I'm referring to is displaying it like this in the console:
(key)0 -> 4 - 32.0
(key)1 -> 15 - 405.5
(key)2 -> 14 - 44.5 -> 18 - 200.0
Topic archived. No new replies allowed.