Chapters

Hide chapters

Data Structures & Algorithms in Dart

Second Edition · Flutter · Dart 3.0 · VS Code 1.78

Section VI: Challenge Solutions

Section 6: 21 chapters
Show chapters Hide chapters

14. Heaps
Written by Jonathan Sande

Heads up... You’re accessing parts of this content for free, with some sections shown as scrambled text.

Heads up... You’re accessing parts of this content for free, with some sections shown as scrambled text.

Unlock our entire catalogue of books and courses, with a Kodeco Personal Plan.

Unlock now

Heaps are another classical tree-based data structure with special properties to quickly fetch the largest or smallest element.

In this chapter, you’ll focus on creating and manipulating heaps. You’ll see how convenient it is to fetch the minimum or maximum element of a collection.

What’s a Heap?

A heap is a complete binary tree, also known as a binary heap, that can be constructed using a list.

Note: Don’t confuse these heaps with memory heaps. The term heap is sometimes confusingly used in computer science to refer to a memory pool. Memory heaps are a different concept and not what you’re studying here.

Heaps come in two flavors:

  1. Max-heap, in which elements with a higher value have a higher priority.
  2. Min-heap, in which elements with a lower value have a higher priority.

The Heap Property

A heap has an essential characteristic that must always be satisfied. This characteristic is known as the heap property:

69 8 2 0 0 Wuq Yuin 4 3 0 3 1 Xet Riin

The Shape Property

Another essential aspect of a heap is its shape property. There can’t be any holes in a heap. A heap must be a complete binary tree. This means that every level must be filled except for the last level. Additionally, when adding elements to the last level, you must add them from left to right.

7 89 6 9 3 Leyek 8 Tedub 4 Pafur 5

Heap Applications

Some practical applications of a heap include:

Fitting a Binary Tree Into a List

Trees hold nodes that store references to their children. In the case of a binary tree, these are references to a left and right child. Heaps are binary trees, but they are implemented with a simple list.

Hiwiw 1 Qobiq 8 Hecuk 1 Niwoh 1 3 9 8 3 1 36 7 6 5 4 7 5 0 0 9 2

46 9 0 8 2 4 9 8 9 oqsup 8 4 4 8 8 7 7 gabiw 6 siqap 7 rilal 2 gomas 5

Accessing Nodes

It’s now easy to access any node in the heap. Instead of traversing down the left or right branch, you access a node in your list using simple formulas.

67 5 7 3 1 1 4 8 9 urwur 7 1 0 9 9 2 9 i = 4 Qusp: 9o + 1 = 4 u = 7 Sesby: 0u + 7 = 8 Noyy: 2u + 7 = 0 e = 1 Pijsk: 3i + 4 = 1 u = 9

Implementation

Open the starter project for this chapter and add a lib folder to the root of the project. Inside that folder create a file named heap.dart.

Adding a Constructor

Since there are both max-heaps and min-heaps, start by adding the following enum to heap.dart:

Providing Basic Properties

Add the following properties to Heap:

Preparing Helper Methods

Any complex task can be broken down into simpler steps. In this section you’ll add a few private helper methods to make the node manipulation you’ll perform later a lot easier.

Accessing Parent and Child Indices

You’ve already learned the formulas for accessing the indices of the children or parent of a given node. Add the Dart implementation of those formulas to Heap:

Selecting a Priority

When you made the Heap constructor, you allowed the user to pass in a max or min priority. Add the following two helper methods that will make use of that property:

Swapping Values

You’ll add insert and remove methods to the class in just a bit. One of the tricks you’ll perform as part of those procedures is swapping the values of two nodes. Add a helper method to Heap for that:

Inserting Into a Heap

Say you start with the max-heap shown in the image below:

4 8 7 2 0 9 2

4 6 8 8 9 0 2 7

2 7 9 5 4 1 0 3 0 5 5 9 2 2 4 8

1 0 2 4 2 7 9 7 0 7 0 2 3 5 4 7

0 4 5 7 5 3 9 2 1 5 3 0 9 2 1 6

Implementing insert

Now that you’ve got the theory, it’s time to implement it in code. Add the following two methods to Heap:

Making the Heap Printable

It’s time to try out your handiwork, but before you do, override the toString method of Heap so that it’s a little easier to observe what’s happening:

Testing Insertion Out

Replace the contents of bin/starter.dart with the following code:

0 6 1 6 0 7 1

1 8 7 6 1 0 1 8

Removing From a Heap

A basic remove operation removes the root node from the heap.

8 6 4 3 29 2 9 1

5 9 9 9 5 6 5 48

0 6 0 9 8 8 7 86

8 9 3 0 4 4 8 2 3 5 2 1 3 7

4 8 8 7 1 7 0 6 0 5 3 7 5 6

3 8 5 3 4 1 4

Implementing a Down Sift

Go back to lib/heap.dart and add a method to Heap to handle sifting down:

Implementing remove

Now that you have a way to sift down, add the remove method to Heap:

Testing remove

Go back to bin/starter.dart and replace the body of main with the following:

Removing From an Arbitrary Index

Add the following method to Heap:

0 1 3 6 6 31 72 2 5 2 3 3 5 9 Nukeha 0
Dsilvodp er xoma

1 6 3 8 8 Jelivo 1 8 61 7 3 05
Dbubkalh yaqk juhu

Testing removeAt

The code that follows demonstrates the example from the previous image:

Searching for an Element in a Heap

To find the index of the element you wish to delete, you need to perform a search on the heap. Unfortunately, heaps are not designed for fast searches. With a binary search tree, you can perform a search in O(log n) time, but since heaps are built using a list, and the node ordering in a heap is different than BST, you can’t even perform a binary search.

Testing it Out

Go back to bin/starter.dart and replace the body of main with the following:

Accepting a List in the Constructor

You may recall that when you made the Heap constructor, it took a list of elements as an optional parameter. In order to initialize such a list, though, you need to sift all of the values into their proper positions. Now that you have the sift methods, you can implement the full constructor.

Testing it Out

Time to try your new constructor out. Add the following to main:

Challenges

Think you have a handle on heaps? Try out the following challenges. You can find the answers in the Challenge Solutions section or in the supplemental materials that accompany the book.

Challenge 1: Find the Nth Smallest Number

Write a function to find the nth smallest number in an unsorted list. For example, given the following list:

Challenge 2: Step-by-Step Diagram

Given the following unsorted list, visually construct a min-heap. Provide a step-by-step diagram of how the min-heap is formed.

Challenge 3: Combining Two Heaps

Write a method that combines two heaps.

Challenge 4: Is it a Min-Heap?

Write a function to check if a given list is a min-heap.

Key Points

  • The heap data structure is good for maintaining the highest- or lowest-priority element.
  • In a max-heap, the value of every parent node is greater than or equal to that of its child.
  • For a min-heap, the value of a parent is less than or equal to that of its child.
  • Every time you insert or remove items, you must take care to preserve the heap property, whether max or min.
  • There can’t be any holes in a heap. The shape property requires that all of the upper levels must be completely filled, and the final level needs to be filled from the left.
  • Elements in a heap are packed into contiguous memory using simple formulas for element lookup.
  • Here is a summary of the algorithmic complexity of the heap operations you implemented in this chapter:
Itudaceepg Venu Qikdyasowh pufoju 6(fed h) ofziff 6(cet t) coevsg 3(y) jaim 7(3) Liaj Xexu Wfgaxlaxi
Heis epugawiak zamu koxwsinevx

Have a technical question? Want to report a bug? You can ask questions and report bugs to the book authors in our official book forum here.
© 2026 Kodeco Inc.

You’re accessing parts of this content for free, with some sections shown as scrambled text. Unlock our entire catalogue of books and courses, with a Kodeco Personal Plan.

Unlock now