When programming, I often realize that simply knowing the syntax isn’t enough to write good software. It's similar to how knowing the grammar of a language doesn't necessarily make someone a great speaker. Sure, having a solid grasp of grammar helps avoid mistakes, but it doesn't automatically lead to natural or persuasive communication.
The same goes for programming. To build effective and efficient programs, we need more than just syntax, we need to understand how to manage data well. That’s where data structures come into play.
Today, I’m going to explore two of the most fundamental and frequently compared data structures, arrays and linked lists. I’ll take a closer look at how each stores data, what strengths they offer, and in which situations one may be more suitable than the other.
Array
An array is a data structure that stores multiple elements of the same type in a sequential order. Each element is assigned an index number, starting from zero, which determines its position in the array.
One of the main advantages of an array is that you can quickly access any element using its index.
In most programming languages, arrays can only hold elements of the same data type, and once their size is set, it is often difficult to change.
Because arrays store data in contiguous memory locations, accessing a specific position is very fast. Therefore, arrays are commonly used to efficiently manage collections of similar data, such as student scores, daily temperatures, or image pixel information.
However, since the size of an array is fixed, adding or removing elements may require creating a new array, which can be inconvenient.
Java example array code
public class ArrayExample {
public static void main(String[] args) {
// Declare and initialize an integer array with size 5
int[] numbers = new int[5];
// Assign values to each element
numbers[0] = 10;
numbers[1] = 20;
numbers[2] = 30;
numbers[3] = 40;
numbers[4] = 50;
// Print values using a for loop
for (int i = 0; i < numbers.length; i++) {
System.out.println("numbers[" + i + "] = " + numbers[i]);
}
// Declare and initialize a string array with predefined values
String[] fruits = {"Apple", "Banana", "Cherry"};
for (int i = 0; i < fruits.length; i++) {
System.out.println("fruits[" + i + "] = " + fruits[i]);
}
}
}
Java
복사
This code demonstrates the basic way to declare and use arrays in Java. First, an integer array with a fixed size of 5 is created using int[] numbers = new int[5]; and values are assigned to each index in the array. Arrays in Java are zero-indexed, meaning the first element is at index 0. The length of the array can be retrieved using numbers.length.
Next, a string array is declared and initialized at the same time using String[] fruits = {"Apple", "Banana", "Cherry"};. This is a convenient way to create and populate an array with predefined values.
Both arrays are traversed using a for loop to print each element. This example shows how arrays in Java are useful for storing and managing a collection of data of the same type in a sequential and efficient manner. Since arrays have a fixed size, they are best suited for situations where the number of elements is known in advance.
Linked List
A Linked List is a linear data structure used to store elements in sequence, but unlike arrays, the elements are not stored in contiguous memory locations. Each element, called a node, contains both the data and a reference (or pointer) to the next node in the sequence.
Because of this structure, inserting or deleting elements is efficient, as it only requires updating the pointers without shifting other elements in memory.
There are several types of linked lists. The most basic is the Singly Linked List, where each node points only to the next node. A Doubly Linked List allows each node to point to both the previous and the next node, making it possible to traverse in both directions.
A Circular Linked List is a variation where the last node points back to the first node, forming a circular loop with no null end.
However, one downside of linked lists is that they do not support fast random access like arrays.
To retrieve a specific element, you must start from the head and follow the pointers one by one until you reach the desired node, which can be slow.
Therefore, linked lists are most suitable in scenarios where frequent insertion and deletion operations occur, while arrays may be a better choice when fast element access is required.
Understanding Linked Lists Through a Delivery Person Analogy
Imagine a delivery person who operates under a very specific rule.
They can only receive the address of the next delivery location once they arrive at the current one.
This is exactly how a Linked List works. You can’t jump to any element directly, you have to follow the chain one step at a time.
1. Singly Linked List
This delivery person can only move forward.
Once they reach a house, they are handed the address of the next house, but they cannot go back.
If they suddenly realize they need to revisit a previous house, the only option is to start over from the beginning.
→ This reflects how singly linked lists work, each node points to the next, but not the previous.
→ Efficient for forward traversal and insertion, but poor at going backward.
class Node {
int data;
Node next;
Node(int data) {
this.data = data;
this.next = null;
}
}
public class SinglyLinkedList {
public static void main(String[] args) {
// Create nodes
Node head = new Node(10);
head.next = new Node(20);
head.next.next = new Node(30);
// Traverse the list
Node current = head;
while (current != null) {
System.out.println(current.data);
current = current.next;
}
}
}
Java
복사
A Singly Linked List is a linear data structure where each element, called a node, contains a value and a reference (or pointer) to the next node in the sequence. It only moves in one direction, from the first (head) to the last node.
In the code above, we create three nodes and link them by setting the next reference of each node to the next one. To access the data, we start from the head and follow each next pointer until we reach the end (null).
This structure is simple and memory-efficient but lacks backward traversal capability.
2. Doubly Linked List
This delivery person can move both forward and backward.
Each house provides both the next and previous addresses, so the person can freely go back and forth.
If they forget something at the previous house, it’s easy to turn around and go back.
→ In a doubly linked list, each node stores references to both the next and previous nodes.
→ This allows for bidirectional traversal and more flexible insertions/deletions, though it uses slightly more memory.
class DNode {
int data;
DNode prev;
DNode next;
DNode(int data) {
this.data = data;
this.prev = null;
this.next = null;
}
}
public class DoublyLinkedList {
public static void main(String[] args) {
// Create nodes
DNode node1 = new DNode(10);
DNode node2 = new DNode(20);
DNode node3 = new DNode(30);
// Link nodes forward and backward
node1.next = node2;
node2.prev = node1;
node2.next = node3;
node3.prev = node2;
// Traverse the list forward
DNode current = node1;
while (current != null) {
System.out.println(current.data);
current = current.next;
}
}
}
Java
복사
A Doubly Linked List is a type of linked list where each node contains three components, data, a reference to the next node, and a reference to the previous node.
This bidirectional structure allows traversal in both forward and backward directions. In the example, we link nodes both ways using next and prev.
This structure makes certain operations like deletion or backward traversal more efficient than in singly linked lists, but it does use more memory and has slightly more complex management.
3. Circular Linked List
In this case, once the delivery person reaches the last house, they are automatically directed back to the first one.
No matter where they start, the delivery route never ends, it’s a perfect loop.
→ A circular linked list connects the last node back to the first.
→ This is useful in scenarios like cyclic task scheduling, music playlists, or turn-based games.
class CNode {
int data;
CNode next;
CNode(int data) {
this.data = data;
this.next = null;
}
}
public class CircularLinkedList {
public static void main(String[] args) {
// Create nodes
CNode node1 = new CNode(10);
CNode node2 = new CNode(20);
CNode node3 = new CNode(30);
// Link nodes in circular fashion
node1.next = node2;
node2.next = node3;
node3.next = node1; // Last node points to the first node
// Traverse the list in circular manner (limited loop to avoid infinite loop)
CNode current = node1;
int count = 0;
while (count < 6) { // Print two full cycles
System.out.println(current.data);
current = current.next;
count++;
}
}
}
Java
복사
A Circular Linked List is a variation of a linked list where the last node points back to the first node, forming a continuous loop.
It can be implemented using either singly or doubly linked nodes. This structure is useful in applications where the data needs to be cycled through repeatedly (e.g., round-robin scheduling).
In the code above, we link three nodes and point the last node back to the first. Since it never ends, traversal must be controlled manually (e.g., using a counter) to avoid infinite loops.