Essential Problem-Solving Tool | Linked List | LeetCode Notes
🌐 中文版:繁體中文
Introduction to the Linked List

A Linked List is a common data structure, composed mainly of data and the address of the next node, forming a structure where nodes link to each other, with the last node pointing to the NULL address.
The main way we implement it is with C. To implement a Linked List, we must first define the node itself with a struct.
Implementing a Linked List
Defining the node
1 | typedef struct node{ |
Above we define the node struct, which contains integer data data, representing the data the node holds, and a struct-type pointer next, the memory address of the next node of the same struct. This struct is declared as Node for convenience in declaring nodes later.
1 | Node *first_node; |
We can use Node to declare three pointers pointing to the memory addresses of three structs: first_node, current_node, previous_node. The uses of these three pointers:
first_nodepoints to the starting address of the chaincurrent_nodepoints to the current node in the chain, often used when traversing the listprevious_nodepoints to the node before current_node, often used when creating nodes or reversing the whole linked list
Now we can start building the chain from scratch.
Building the Linked List
1 |
|
In the code above, we first provide input to decide the number of nodes to create, then call the create_new_node function, and print each node’s data and the next node’s address in order from the first node, finally moving to the next node via current_node=current_node->next;.
The main thing to do here is build the create_new_node function.
Creating nodes (create_new_node)
1 | void create_new_node(int node_nums){ |
- Inside the function, a
for looprepeats the node creation - Dynamically allocate space of
Nodesize with malloc, and point current_node at its memory address - Let the user manually enter the data content
current_node -> datameans accessing the data variable at this memory address; here we directly store the manually entered data value into the node’s data variable- Then judge whether we’re creating the first node. When creating the first node, remember to update the
first_nodepointer to point to the current node, and since there’s no previous node at this point, also updateprevious_nodetocurrent_node, i.e. the current node - When creating subsequent nodes, make the previous node point to the current node’s memory address so they link up, so
previous_node->next = current_node; - And point
current_node‘s next node memory address to NULL, socurrent_node -> next = NULL; - Finally, update
previous_nodeto the current node
Printing the list (PrintList)
After building the nodes, you inevitably want to print the whole list
1 | // input parameter is node struct |
- The main logic is to run from the first node along the chain, so
node = node -> nextuntil hitting Null - The function’s input is the initial node address
- Need to judge whether the list is empty
Then call it in the main function to print
1 | PrintList(first_node); |
Freeing memory
Since every node is dynamically declared with malloc, the memory addresses occupied must be freed after execution ends, so we likewise need to iterate over each chain node and free() it
1 | void FreeList(Node* first){ |
- The function’s input parameter is likewise the initial node’s address
- Before reaching NULL, we need to put the current node into a temporary memory address to
free()it; if we directlyfree(current), the next node’s memory address stored in it can’t be found - Then let the current node keep going down the list
current = current->next;
Searching for a node
1 | // Return value should be the address of the node |
- The function’s declared type is also
Node*because the return value is a struct pointer, i.e. a node’s memory address - The input parameters also need the list’s initial node address and the data value to find
- Likewise go down the list (
node= node->next;); if a node’s data value equalsitemis found, return the node, until hitting Null
Inserting a node
Inserting a node is split into different functions for different situations:
- Insert into the middle of the list
- Insert at the head of the list
- Insert at the tail of the list
Insert in the middle
1 | void InsertNode(Node* node, int item){ |
- The function’s input parameter is a node, and you also need to provide the inserted node’s data value
- Then create a new node and allocate memory for it
- Put the data value
iteminto the new node’sdatavariable - Put the original input node’s next node address into the new node’s
next - Point the original input node’s
nextat the new node we created
This completes the node insertion.
Insert at the head
1 | // Insert a node to the front of the list |
- Since it’s the head, the input parameter is just the data value
- Likewise create a new node and allocate memory for it
- Put
iteminto the new node’sdata - Point the new node’s
nextat the first node - Update
first_nodeto the new node
Insert at the tail
1 | // Insert a node to the back of the list |
- Likewise the input parameter is the new node’s data value
- Likewise create a new node and allocate memory for it
- Give the new node’s data value
item - Point the new node’s pointer at NULL
- Next is handling the insertion, but first there’s an exception case: judge whether the list is empty; if empty, update
first_nodeto our newly creatednew_node - If the list isn’t empty, first traverse the whole list to find the last node, so update
current_nodetofirst_node - If the last node hasn’t been reached, keep traversing
current_node = current_node->next; - After reaching the last node, point the last node’s pointer at the newly created node
Deleting a node
1 | Node* DeleteNode(Node* first ,Node* node){ |
- The input parameters are the initial node and the node to be deleted
- At the start we likewise need to judge whether
first_nodeis null; if null there’s nothing to delete - Then split into different cases:
- Delete the head
- Delete the middle and tail
- To delete the head, first update
first_nodeto its next node - Then directly use
free()to release the memory - Otherwise, while the chain hasn’t reached the node to be deleted, keep traversing (
ptr = ptr->next) - Once found, point its pointer at the next node’s next node address
- Then directly use
free()to release the memory
Reversing the Linked List (Reverse Linked List)

To reverse a list, you need an extra node to temporarily hold a node’s address.
Explanation
If you first point the initial node (node A)’s pointer at NULL, there’s a problem: the original pointer stored the next node’s address. If you change it to NULL, don’t you then not know the original next node’s address? Without even the node’s address, how do you reverse? So you need an extra node pointing to node B to hold B’s memory address.
So the steps are as shown below:
- Define a pointer pointing to NULL
- Create a temporary node pointing to the current node’s next node
- Change the current node to point to NULL
- Change the next node (node B) to point to the previous node (node A)
- Update the temporary node’s pointer to point to the next node’s address

1 | void Reverse(){ |
current: the pointer to the current node, initialized to the linked list’s first nodefirst_nodeprevious: the pointer to the previous node, initialized to NULL, since there’s no previous node at the startpreceding: the pointer to the current node’s next node, initialized tofirst_node‘s next node- Then in the while loop, loop through the linked list until preceding becomes NULL
current->next = previous;: point the current node’snextpointer at the previous node (reversing the pointer direction)previous = current;: updatepreviousto the current nodecurrent = preceding;: updatecurrentto the next nodepreceding = preceding->next;: updateprecedingto the next node’s next node- Then handle the last node, likewise pointing the last node’s
nextpointer at the previous node (reversing the pointer direction) - Also update the initial node’s pointer to the current node
first_node = current;: update the linked list’s head nodefirst_node; now current points to the original linked list’s last node, i.e. the new head node
Full code
1 |
|
Execution result


Summary: through this writeup, I got more familiar again with the linked-list operations I’d forgotten. Next I’ll just grab related LeetCode problems for practice.
References
[1] https://jacychu.medium.com/leetcode-linked-list-%E9%8F%88%E7%B5%90%E4%B8%B2%E5%88%97-c2edabee9958
[2] https://codimd.mcl.math.ncu.edu.tw/s/B1rd5-sM4#%E6%8F%92%E5%85%A5%E7%AF%80%E9%BB%9E%E5%87%BD%E6%95%B8-InsertNode-








