Linked List Trouble

I'm having trouble displaying this linked list I'm trying to build. I have 2 functions so far to append and print. But all it is returning is a single 0.

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
#include <iostream>

using namespace std;

struct LinkedList
{
	int value;
	LinkedList* next;
};

void append_node(LinkedList** head);
void printlist(LinkedList* head);
//void insert_node()

int main()
{
	//int num = 0;
	int nodes = 0;
	struct LinkedList* head = nullptr;
	cout << "How many do you want to input?  (Atleast one entry.) ";
	cin >> nodes;

	if (nodes < 1)
	{
		cout << "Enter a proper value: ";
		cin >> nodes;
	}

	for (int i = 0; i < nodes; i++)
		append_node(&head);

	cout << "Here is the updated linked list. \n";
	printlist(head);


	return 0;
}

void append_node(LinkedList** head)
{
	int num;
	cout << "Enter a number for a new node to enter to the end of list: ";
	cin >> num;

	LinkedList* Node = new LinkedList();

	if (*head == nullptr)
	{
		*head = Node;
		return;
	}

	Node->value = num;
	Node->next = nullptr;

	LinkedList* ptr = *head;
	while (ptr->next != nullptr)
	{
		ptr = ptr->next;
		ptr->next = Node;

	}
}

void printlist(LinkedList* ptr)
{
	//LinkedList* ptr = *head;
	while (ptr != nullptr)
	{
		cout << ptr->value << endl;
		ptr = ptr->next;
	}

}
You need to refactor your code.

A linked list is the single, complete structure. However, you are using it for individual nodes. Start by calling your elemental struct a Node and not a LinkedList and you won't confuse everybody.

You shouldn't be sending the memory address of pointers - you end up double-dereferencing in append_ node. The whole point of pointers is that they already contain a memory address.

Start by refactoring your code.
Your first problem is line 49. The member next is not set/invalid. Move line 53/54 before line 47.

Currently it is a mix of c and c++. With c++ you could write something like
1
2
3
4
5
struct LinkedList
{
	int value = 0;
	LinkedList* next = nullptr;
};
This would make it safer. Or even:
1
2
3
4
5
6
7
8
9
10
11
struct LinkedList
{
	int value = 0;
	LinkedList* next = nullptr;

LinkedList() = default;
LinkedList(int v) : value{v}
{
}

};
With this you can have this:
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
void append_node(LinkedList** head)
{
	int num;
	cout << "Enter a number for a new node to enter to the end of list: ";
	cin >> num;

	LinkedList* Node = new LinkedList(num);

	if (*head == nullptr)
	{
		*head = Node;
		return;
	}

	Node->value = num;
	Node->next = nullptr;

	LinkedList* ptr = *head;
	while (ptr->next != nullptr)
	{
		ptr = ptr->next;
		ptr->next = Node;

	}
}
If this is not homework consider using std::list instead.
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
#include <iostream>
#include <list>
#include <algorithm>
#include <iterator>

using namespace std;

int main()
{
	int nodes = 0, input = 0;
	list<int> my_list;

	cout << "How many do you want to input?  (At least one entry.) ";
	cin >> nodes;

	if (nodes < 1)
	{
		cout << "Enter a proper value: ";
		cin >> nodes;
	}

	for (int i = 0; i < nodes; i++)
	{
		cout << "Enter value " << i + 1 << ": ";
		std::cin >> input;
		my_list.push_back(input);
	}

	cout << "Here is the updated linked list. \n";
	copy(begin(my_list), end(my_list), ostream_iterator<int>(cout, " "));
}
This is an assignment and he wanted us to build a certain way. I've took in the changes of setting the -> next = nullptr in struct declaration and also the new node after creation. Now the print function is only displaying the first node.
Now the print function is only displaying the first node.
I recommend to use the debugger and go step by step through the code to unsterstand what happens. Or add debug cout.

1
2
3
4
5
6
7
	LinkedList* ptr = *head;
	while (ptr->next != nullptr)
	{
		ptr = ptr->next;
		ptr->next = Node;

	}
What happens the second time you call append_node(...)? Well, ptr->next will be nullptr. So the loop will never have any effect.

Consider this:
1
2
3
4
5
6
7
	LinkedList* last_ptr = nullptr;
	for(LinkedList* ptr = *head; ptr != nullptr; ptr = ptr->next)
	{
		last_ptr = ptr;
	}
	assert(last_ptr);
	last_ptr->next = Node;
Not tested!
Perhaps:

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
#include <iostream>

struct LinkedList {
	int value {};
	LinkedList *next {};

	LinkedList() {};
	LinkedList(int v) : value {v} {}
};

void append_node(LinkedList** head);
void printlist(LinkedList* head);

int main() {
	size_t nodes {};
	LinkedList* head {};

	do {
		std::cout << "How many do you want to input? (At least one entry.): ";
		std::cin >> nodes;
	} while ((nodes < 1) && (std::cout << "Enter a proper value!\n"));

	for (size_t i = 0; i < nodes; ++i)
		append_node(&head);

	std::cout << "Here is the updated linked list. \n";
	printlist(head);
	std::cout << '\n';
}

void append_node(LinkedList** head) {
	int num {};

	std::cout << "Enter a number for a new node to add to the end of list: ";
	std::cin >> num;

	if (*head == nullptr)
		*head = new LinkedList(num);
	else {
		auto ptr{ *head };

		for (; ptr->next != nullptr; ptr = ptr->next);
		ptr->next = new LinkedList(num);
	}
}

void printlist(LinkedList* ptr) {
	for (; ptr != nullptr; ptr = ptr->next)
		std::cout << ptr->value << ' ';
}


Note that if nodes are added to the tail of a list, then it is common to also maintain a tail pointer as well as a head pointer. This allows direct tail insertion without L42 for loop. For large populated lists, this for loop on the performance can be significant.
Topic archived. No new replies allowed.