Linked List - where to start?

I am doing a doubly linked list. I have essentially found the answer and figured it out but I cant seem to carry over what the different functions are doing. I guess I dont know where or how to start. I was going to start with the createlist function.

The thing I am having a hard time understanding is the pointer to a pointer (**) with two different structs that appear to do different functions (NODE and PNODE?)
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
/*


Instructions:
Please insert the standard header above.
Add the functions in the ADD THESE FUNCTIONS sections below.
Include function descriptions for all your functions.
Add to the input enum to create additional commands.
Do not modify the way the list works.

Here is how the list works:

       head or front                         tail or back

list
  |---> 100
		next ->		200
 					next ->  300
				  			 next ->  400
				           			  next -> NULL
*/

#include <iostream>
using namespace std;

enum INPUTS {
	ADD_NODE,
	PRINT_LIST,
	REMOVE_FIRST_NODE,
	// INSERT YOUR ENUMS HERE - Make sure you change the menu function
	END_APP // keep this as your last enum
};

typedef struct _NODE_ {

	_NODE_ * next;
	int data;

}NODE, *PNODE;

void menu();

void printList(NODE * pList);
void createList(NODE **pList);
NODE * destroyList(NODE * pList);

NODE * pushFront(NODE * pList, NODE * pNode);
NODE * popFront(NODE * pList);

NODE * createNode(int value);

void printListRecursive(NODE * pList); // implementes print recursively
void printBackwards(NODE * pList);     // must be recursive
NODE * pushBack(NODE * pList, NODE * pNode); // adds a node to the back of the list
NODE * front(NODE * pList); // returns the node at the front of the list
NODE * back(NODE * pList);  // returns the node at the back of the list

bool isInList(NODE * pList, int value); // returns true if value is in list, false otherwise
NODE * removeFromList(NODE * pList, int value); // Returns the modified list. 
 
NODE * insertAt(NODE * pList, NODE * pNode, int index);
NODE * removeAt(NODE * pList, int index);

int main(void)
{
	NODE * list;
	NODE * node;
	int input;
	int count = 10;

	createList(&list);

	menu();

	while(1)
	{
		cin.clear(); // clear error bits
		cin.sync();  // empty buffer

		cout << endl << "INPUT: ";
		cin >> input;  // valid inputs only -- no error checking!

		switch(input)
		{
		case ADD_NODE:
			node = createNode(count++);
			list = pushFront(list, node);
			break;
		case PRINT_LIST:
			printList(list);
			break;
		case REMOVE_FIRST_NODE:
			list = popFront(list);
			break;
		case END_APP:
			list = destroyList(list);
			return 0;
		default:
			cout << "Invalid input" << endl;
		}
	}

	return 0;
}

/*
FUNCTION:		menu
PRECONDITION:	None.
POSTCONDITION:	The program menu is output.
*/
void menu()
{
	cout << endl;
	cout << "Inputs: " << endl;
	cout << ADD_NODE << " add a node " << endl;
	cout << PRINT_LIST << " print list " << endl;
	cout << REMOVE_FIRST_NODE << " remove first node " << endl;

	// insert additional enums here


	cout << END_APP << " End application " << endl;
}

/*
FUNCTION:		createList
PRECONDITION:	Address of a list pointer.
POSTCONDITION:	pList points to a valid node.
*/
void createList(NODE **pList)
{
	(*pList) = NULL; // empty list
	int start = NULL;

	struct node *s, *temp;
	temp = new NODE;
	temp->data = value;
	temp->next = NULL;
	if (start == NULL)
	{
		temp->prev = NULL;
		start = temp;
	}
	else
	{
		s = start;
		while (s->next != NULL)
			s = s->next;
		s->next = temp;
		temp->prev = s;
	}

}

/*
FUNCTION:		destroyList
PRECONDITION:	pList is a valid list pointer.
POSTCONDITION:	The list pointer and all nodes in the list are destroyed.
				Returns the empty list. 
*/
NODE * destroyList(NODE * pList)
{
	while(pList = popFront(pList));
	

	return NULL; 
}

/*
FUNCTION:		pushFront
PRECONDITION:	pList is a valid list pointer.  pNode is a valid node pointer.
POSTCONDITION:	pNode is inserted at the front of the list.  Returns the new list. 
*/
NODE * pushFront(NODE * pList, NODE * pNode)
{
	if(pList == NULL) // no list yet
	{
		return pNode; 
	}
	else // the list exists
	{
		pNode->next = pList; 
		pList = pNode; 

		return pList; 
	}
}

/*
FUNCTION:		popFront
PRECONDITION:	pList is a valid list pointer, or NULL.
POSTCONDITION:	returns a new list if there are nodes in the list, NULL (empty list) otherwise. 
*/
NODE * popFront(NODE * pList)
{
	NODE * temp;

	if(!pList) return NULL; 

	temp = pList; // point to first node in list

	pList = pList->next; 

	delete temp; 

	return pList; 
}

/*
FUNCTION:		createNode
PRECONDITION:	A value to store in the list.
POSTCONDITION:	Returns a pointer to a node containing the value.
*/
NODE * createNode(int value)
{
	NODE * temp = new NODE;
	temp->data = value;
	temp->next = 0;
	return temp;
}

/*
FUNCTION:		printList
PRECONDITION:	pList is a valid list pointer, or NULL.
POSTCONDITION:	If the list exists, outputs the list to the console.
*/
void printList(NODE * pList)
{
	NODE * temp;

	if(! pList) return;

	temp = pList; // start with first node

	while(temp != NULL)
	{
		cout << temp->data << endl;
		temp = temp->next;
	}

}
The thing I am having a hard time understanding is the pointer to a pointer (**) with two different structs that appear to do different functions (NODE and PNODE?)
In this case it means that the pointer itself will be modified. Like on line 132.

PNODE is not another struct, it is the same as NODE *. Neither usefull nor used.


Simplified:
1
2
3
4
5
6
7
8
9
10
void createList(NODE **pList)
{
	(*pList) = NULL; // empty list
}

int main(void)
{
	NODE * list; // Now list contains an invalid pointer
	createList(&list); // After the function is called list constains NULL
}


POSTCONDITION: pList points to a valid node.
Actually that is not true. pList will be NULL. The rest of the code within createList(...) doesn't make sense.
Topic archived. No new replies allowed.