codingstuff.io
ExploreTutorialsProblemsCS Subjects
Get Started
ExploreTutorialsProblemsCS Subjects
Get Started
codingstuff.io

Master the art of building software through interactive tutorials, real-world problems, and guided projects.

Pune, Maharashtra, India

codingstuffmail@gmail.com

Product

  • Explore
  • Tutorials
  • Problems
  • CS Subjects

Company

  • About
  • Contact
  • Privacy Policy
  • Terms & Conditions
  • Sitemap

© 2026 codingstuff.io. All rights reserved.

Built with ❤️ for developers everywhere

/
/
All Tutorials
🧮

Data Structures & Algorithms

2 / 65 topics
1Introduction to Data Structures2Types of Data Structures
Tutorials/Data Structures & Algorithms/Types of Data Structures
🧮Data Structures & Algorithms

Types of Data Structures

Updated 2026-04-20
4 min read

Introduction

Data structures are fundamental building blocks in computer science and software engineering. They provide a way to organize, manage, and store data efficiently, enabling efficient access and modification. Understanding different types of data structures is crucial for designing effective algorithms and solving complex problems.

In this tutorial, we will explore various types of data structures, their characteristics, use cases, and best practices. We'll cover the following topics:

  1. Arrays
  2. Linked Lists
  3. Stacks
  4. Queues
  5. Trees
  6. Graphs

1. Arrays

An array is a collection of elements stored at contiguous memory locations. Each element can be accessed using its index, which starts from 0.

Characteristics

  • Fixed Size: The size of an array is determined at the time of creation and cannot be changed.
  • Random Access: Elements can be accessed in constant time \(O(1)\).
  • Efficient Storage: Uses contiguous memory locations for efficient storage.

Use Cases

  • Storing a list of items with known size.
  • Implementing other data structures like matrices and hash tables.

Code Example

// Creating an array
let fruits = ['apple', 'banana', 'cherry'];

// Accessing elements
console.log(fruits[0]); // Output: apple

// Modifying elements
fruits[1] = 'blueberry';
console.log(fruits); // Output: ['apple', 'blueberry', 'cherry']

Best Practices

  • Use arrays when the size of the data is known and fixed.
  • Avoid using arrays for dynamic data sizes as resizing can be costly.

2. Linked Lists

A linked list consists of a sequence of elements, called nodes, where each node contains data and a reference (link) to the next node in the sequence.

Characteristics

  • Dynamic Size: Nodes can be added or removed without changing the size.
  • Sequential Access: Elements must be accessed sequentially from the start.
  • Efficient Insertions/Deletions: Adding or removing nodes is efficient, especially at the beginning or end.

Use Cases

  • Implementing queues and stacks.
  • Managing dynamic data sizes where resizing is frequent.

Code Example

// Node class
class Node {
  constructor(data) {
    this.data = data;
    this.next = null;
  }
}

// Linked List class
class LinkedList {
  constructor() {
    this.head = null;
  }

  // Add a node at the end
  append(data) {
    let newNode = new Node(data);
    if (!this.head) {
      this.head = newNode;
      return;
    }
    let current = this.head;
    while (current.next) {
      current = current.next;
    }
    current.next = newNode;
  }

  // Print the list
  printList() {
    let current = this.head;
    while (current) {
      console.log(current.data);
      current = current.next;
    }
  }
}

// Usage
let list = new LinkedList();
list.append('apple');
list.append('banana');
list.printList(); // Output: apple banana

Best Practices

  • Use linked lists when dynamic resizing is required.
  • Be cautious of memory overhead due to pointers.

3. Stacks

A stack is a linear data structure that follows the Last In, First Out (LIFO) principle. Elements can only be added or removed from the top of the stack.

Characteristics

  • LIFO Principle: The last element added is the first one to be removed.
  • Efficient Operations: Push and pop operations are efficient \(O(1)\).
  • Limited Access: Only the top element can be accessed directly.

Use Cases

  • Implementing function calls in programming languages.
  • Parsing expressions and syntax checking.

Code Example

// Stack class
class Stack {
  constructor() {
    this.items = [];
  }

  // Push an element onto the stack
  push(element) {
    this.items.push(element);
  }

  // Pop an element from the stack
  pop() {
    if (this.isEmpty()) return 'Underflow';
    return this.items.pop();
  }

  // Check if the stack is empty
  isEmpty() {
    return this.items.length === 0;
  }
}

// Usage
let stack = new Stack();
stack.push('apple');
stack.push('banana');
console.log(stack.pop()); // Output: banana

Best Practices

  • Use stacks when LIFO operations are required.
  • Be aware of potential underflow/overflow conditions.

4. Queues

A queue is a linear data structure that follows the First In, First Out (FIFO) principle. Elements can only be added at the rear and removed from the front.

Characteristics

  • FIFO Principle: The first element added is the first one to be removed.
  • Efficient Operations: Enqueue and dequeue operations are efficient \(O(1)\).
  • Limited Access: Only the front and rear elements can be accessed directly.

Use Cases

  • Scheduling tasks in operating systems.
  • Implementing breadth-first search (BFS) algorithms.

Code Example

// Queue class
class Queue {
  constructor() {
    this.items = [];
  }

  // Enqueue an element to the queue
  enqueue(element) {
    this.items.push(element);
  }

  // Dequeue an element from the queue
  dequeue() {
    if (this.isEmpty()) return 'Underflow';
    return this.items.shift();
  }

  // Check if the queue is empty
  isEmpty() {
    return this.items.length === 0;
  }
}

// Usage
let queue = new Queue();
queue.enqueue('apple');
queue.enqueue('banana');
console.log(queue.dequeue()); // Output: apple

Best Practices

  • Use queues when FIFO operations are required.
  • Be aware of potential underflow/overflow conditions.

5. Trees

A tree is a hierarchical data structure consisting of nodes connected by edges. Each node has zero or more child nodes, and one node is designated as the root.

Characteristics

  • Hierarchical Structure: Nodes are organized in a parent-child relationship.
  • Root Node: The topmost node with no parents.
  • Leaf Nodes: Nodes with no children.

Use Cases

  • Representing hierarchical data like file systems.
  • Implementing search algorithms like binary search trees.

Code Example

// Tree Node class
class TreeNode {
  constructor(data) {
    this.data = data;
    this.children = [];
  }

  // Add a child node
  addChild(childNode) {
    this.children.push(childNode);
  }
}

// Usage
let root = new TreeNode('root');
let child1 = new TreeNode('child1');
let child2 = new TreeNode('child2');
root.addChild(child1);
root.addChild(child2);
console.log(root); // Output: { data: 'root', children: [ { data: 'child1', children: [] }, { data: 'child2', children: [] } ] }

Best Practices

  • Use trees when hierarchical relationships are required.
  • Consider using balanced trees for efficient operations.

6. Graphs

A graph is a non-linear data structure consisting of nodes (vertices) and edges connecting these nodes.

Characteristics

  • Nodes and Edges: Nodes represent entities, and edges represent relationships between them.
  • Directed/Undirected: Edges can be directed or undirected.

Use Cases

  • Representing networks like social media connections.
  • Implementing shortest path algorithms like Dijkstra's algorithm.

Code Example

// Graph class
class Graph {
  constructor() {
    this.adjacencyList = {};
  }

  // Add a vertex
  addVertex(vertex) {
    if (!this.adjacencyList[vertex]) {
      this.adjacencyList[vertex] = [];
    }
  }

  // Add an edge between two vertices
  addEdge(vertex1, vertex2) {
    if (this.adjacencyList[vertex1]) {
      this.adjacencyList[vertex1].push(vertex2);
    }
    if (this.adjacencyList[vertex2]) {
      this.adjacencyList[vertex2].push(vertex1);
    }
  }

  // Print the graph
  printGraph() {
    for (let vertex in this.adjacencyList) {
      console.log(`${vertex} -> ${this.adjacencyList[vertex].join(', ')}`);
    }
  }
}

// Usage
let graph = new Graph();
graph.addVertex('A');
graph.addVertex('B');
graph.addEdge('A', 'B');
graph.printGraph(); // Output: A -> B, B -> A

Best Practices

  • Use graphs when modeling relationships between entities.
  • Consider using different graph traversal algorithms like BFS and DFS.

Conclusion

Understanding the different types of data structures is essential for effective problem-solving in computer science. Each data structure has its own strengths and weaknesses, making it suitable for specific use cases. By choosing the right data structure, you can optimize your code for performance and efficiency.

In this tutorial, we covered arrays, linked lists, stacks, queues, trees, and graphs. We provided real-world examples and best practices to help you apply these concepts in your projects.


PreviousIntroduction to Data StructuresNext Arrays

Recommended Gear

Introduction to Data StructuresArrays