## Before you start

This section describes some things you need to know before you start, such as what you need for your hardware and software, the location of the project files in this book, and so on.

## Section I: Overview of data structures and algorithms

This short but important section chapter describes what’s built into the Kotlin standard library and how to use it in building your app. Learn why one algorithm is better than another. You will also learn what Big-O notation is and how to keep answering the question “Can you do better?”

The Kotlin Standard Library contains essential features for the Kotlin language. Within the Kotlin Standard Library, there are various tools and types that can help you build Kotlin apps, such as data structures.

Answer the question “Is it extensible?” Understanding the complexity of the algorithm is everything. Big-O notation is the primary tool used to think about the performance of algorithms in abstract and independent hardware or languages. In this chapter, we will prepare to think in these terms.

## Section II: Basic data structure

This section describes some of the important data structures that form the basis of the more advanced algorithms we will discuss in future sections.

A linked list is a collection of values arranged in a linear unidirectional sequence. Linked lists have some theoretical advantages over contiguous storage options such as arrays, such as inserting and removing from the top of the list for a period of time, and other reliable performance characteristics.

The stack data structure is similar in concept to the physical stack of objects. When you add an item to the stack, put it on the top of the stack. Whenever you remove an item from the stack, you delete the top-level item. The stack is convenient and very simple. The main purpose of building a stack is to enforce how to access the data.

Whether you’re lining up to buy tickets for your favorite movie or waiting for your printer machine to print a document, the queue is everywhere. These real-world scenarios mimic the data structure of a queue. Queues use first-in, first-out order. That is, the first queued element is dequeued first. Queues are useful when you need to maintain the order of the elements you want to process later.

## Section III: Tree

Trees are another way to organize information and introduce the concept of children and parents. Examine the most common tree types and see how they can be used to solve specific computational problems.

Trees are a convenient way to organize information when performance is important. Adding them to your tool belt will definitely prove to be useful throughout your career.

Trees are a very important data structure. It is used to address many recurring challenges in software development, such as representing hierarchical relationships, managing sorted data, and facilitating fast lookup operations. There are many types of wood, and they come in a variety of shapes and sizes.

In the previous chapter we saw a basic tree where each node can have many children. A binary tree is a tree that has up to two children on each node and is often called a left child and a right child. Binary trees serve as the basis for many tree structures and algorithms. In this chapter, you will build a binary tree and learn about the three most important tree scanning algorithms.

Binary search trees facilitate fast search, add, and delete operations. The average time complexity for each operation is O (log n), which is significantly faster than linear data structures such as arrays and linked lists.

In the previous chapter, you learned about the O (log n) performance characteristics of a binary search tree. However, we also learned that an imbalanced tree can degrade tree performance down to O (n). In 1962, George Adelson-Velsky and Evgenii Landis devised the first self-balancing binary search tree, the AVL tree.

A try (pronounced “try”) is a tree that specializes in storing data that can be represented as a collection, such as English words. The benefits of try are best explained by reviewing the try in the context of prefix matching, which is done in this chapter.

Binary search is one of the most efficient search algorithms with O (log n) time complexity. This is equivalent to searching for elements in the self-balancing binary search tree. To perform a binary search, the collection must be able to perform index operations and must be sorted by a certain amount of time.

A heap is a complete binary tree, also known as a binary heap, which can be built using arrays. There are two types of heaps, the maximum heap and the minimum heap. Have you ever seen a movie Toy Story with a claw machine and a tiny green alien that squeaks? Suppose your claw machine is running in a heap structure and you always choose the minimum or maximum value depending on the flavor of the heap.

A queue is a list that maintains the order of elements using first-in, first-out (FIFO) order. The priority queue is another version of the queue that dequeues elements in priority order instead of using FIFO order. Priority queues are especially useful when you need to specify a list of elements to identify the maximum or minimum values.

## Section IV: Sorting algorithm

Organizing lists is a classic computational problem. Sorting has been studied since the days of tubes, and perhaps even earlier. You may not need to write your own sorting algorithm, thanks to the highly optimized standard library, but there are many advantages to studying sorting. For example, we’ll show you some very important techniques: divide and rule, stability, and best and worst case timing.

Studying sorting is a bit academic and may seem to be separate from the real world of app development, but understanding the trade-offs of these simple cases will give you a better understanding. You can analyze any algorithm that leads to.

O (n²) time complexity does not perform well, but the sorting algorithms in this category are easy to understand and useful in some scenarios. These algorithms are space efficient and require only a certain amount of O (1) additional memory space. This chapter describes the bubble sort, selection sort, and insertion sort algorithms.

In this chapter, you will learn one of the most important sorting algorithms based on divide-and-conquer law. Learn how to split the list, sort it recursively, and then merge the two parts.

So far, we have relied on comparisons to determine the sort order. This chapter describes a completely different sorting model. Radix sort is a non-comparative algorithm for sorting integers in linear time. There are multiple radix sort implementations that focus on different issues. To keep things simple, we’ll focus on sorting integers in radix 10 while exploring the least significant digit (LSD) variant of radix sort.

Heapsort is another comparison-based algorithm that uses the heap to sort arrays in ascending order. This chapter is based on the heap concept presented in Chapter 12, “Heap Data Structures”. By definition, heapsort uses a heap, which is a partially sorted binary tree.

Quicksort is a divide-and-conquer method that introduces the concept of partitions and a pivot to implement high-performance sorting. You can see that it is very fast on some datasets, but can be a bit slower on other datasets.

## Section V: Graph

Graphs are a very useful data structure that can be used to model web pages on the Internet, bird movement patterns, protons in the nucleus, and much more. In this section, we will delve (and broadly) think about how to use graphs and graph algorithms to solve real problems. The following chapters provide the basics needed to understand the data structure of graphs. As with the previous section, all other chapters act as challenge chapters so you can practice what you have learned.

What do social networks have in common with booking cheap flights around the world? Both of these real models can be represented graphically. A graph is a data structure that captures the relationships between objects. It consists of vertices connected by edges. In a weighted graph, every edge has a weight associated with it that represents the cost of using this edge. This allows you to choose the cheapest or shortest path between the two vertices.

The previous chapter described how to use charts to capture relationships between objects. There are several algorithms for traversing or retrieving the vertices of a graph. One such algorithm is the breadth-first search algorithm. It can be used to solve a variety of problems, including generating a minimum spanning tree, finding potential paths between vertices, and finding the shortest path between two vertices.

The previous chapter described breadth-first search. This search had to explore all the neighborhoods of the vertices before moving on to the next level. This chapter describes depth-first search that applies to topological sorting, cycle detection, pathfinding in maze puzzles, and searching for connected components in sparse graphs.

Have you ever used the Google or Apple Maps app to find the shortest or fastest route from one location to another? Dijkstra’s algorithm is especially useful in GPS networks, helping to find the shortest path between two locations. Dijkstra’s algorithm is a greedy algorithm that builds the solution step by step and chooses the best path at every step.

The previous chapter described depth-first and breadth-first search algorithms. These algorithms form a spanning tree. This chapter describes the Prim algorithm, which is the greedy algorithm used to build the smallest spanning tree. The minimum spanning tree is a spanning tree with weighted edges that minimizes the total weight of all edges. Learn how to implement a greedy algorithm to build a solution step by step and choose the best path at every step.