Book Image

C# Data Structures and Algorithms - Second Edition

By : Marcin Jamro
Book Image

C# Data Structures and Algorithms - Second Edition

By: Marcin Jamro

Overview of this book

Building your own applications is exciting but challenging, especially when tackling complex problems tied to advanced data structures and algorithms. This endeavor demands profound knowledge of the programming language as well as data structures and algorithms – precisely what this book offers to C# developers. Starting with an introduction to algorithms, this book gradually immerses you in the world of arrays, lists, stacks, queues, dictionaries, and sets. Real-world examples, enriched with code snippets and illustrations, provide a practical understanding of these concepts. You’ll also learn how to sort arrays using various algorithms, setting a solid foundation for your programming expertise. As you progress through the book, you’ll venture into more complex data structures – trees and graphs – and discover algorithms for tasks such as determining the shortest path in a graph before advancing to see various algorithms in action, such as solving Sudoku. By the end of the book, you’ll have learned how to use the C# language to build algorithmic components that are not only easy to understand and debug but also seamlessly applicable in various applications, spanning web and mobile platforms.
Table of Contents (13 chapters)

Notations for algorithm representation

In the previous section, algorithms were presented in English. However, this is not the only way of specifying and documenting an algorithm. In this section, you will learn about four notations for algorithm representation, namely natural language, flowchart, pseudocode, and programming language.

To make this task easier to understand, you will specify the algorithm for calculating an arithmetic mean in all of these notations. As a reminder, the mean can be calculated using the following formula:

Figure 2.2 – Formula for calculating an arithmetic mean

Figure 2.2 – Formula for calculating an arithmetic mean

As you can see, two inputs are used, namely the provided numbers (a) and the total number of elements (n). If no numbers are provided, null is returned, indicating that no mean is available. Otherwise, you sum the numbers and divide them by the total number of elements to get the result.

Natural language

First, let’s specify the algorithm using a natural language. It is a very easy way of providing information about algorithms, but it can be ambiguous and unclear. So, let’s describe our algorithm in this way:

The algorithm reads the input, which represents the total number of elements from which an arithmetic mean will be calculated. If the entered number is equal to 0, the algorithm should return null. Otherwise, it should read the numbers in the amount equal to the expected total count. Finally, it should return the result as the sum of numbers divided by their count.

Quite simple and understandable, isn’t it? You can use this notation for simple algorithms, but it can be useless for complex and advanced algorithms. Of course, some descriptions in the natural language are often useful, regardless of the complexity of an algorithm. They can give you a brief understanding of what the aim of the algorithm is, how it works, and what aspects should be taken into account while you’re analyzing or implementing the algorithm.

Flowchart

Another way of presenting an algorithm is via a flowchart. A flowchart uses a set of graphical elements to prepare a diagram that specifies the algorithm’s operation. Some of the available symbols are as follows:

Figure 2.3 – The available symbols while designing a flowchart

Figure 2.3 – The available symbols while designing a flowchart

The algorithm should contain the entry point and one or more exit points. It can also contain other blocks, including operation, input, output, or condition. The following blocks are connected with arrows that specify the order of execution. You can also draw loops.

Let’s take a look at a flowchart for calculating the arithmetic mean:

Figure 2.4 – Flowchart for calculating the arithmetic mean

Figure 2.4 – Flowchart for calculating the arithmetic mean

The execution starts in the START block. Then, we assign 0 as a value of the sum variable, which stores the sum of all the entered numbers. Next, we read a value from the input and store it as a value of the n variable. This is the total number of elements used to calculate the arithmetic mean. Next, we check whether n is equal to 0. If so, the YES branch is chosen, null is returned to the output, and the execution stops. If n is not equal to 0, the NO branch is chosen and we assign 0 as a value of the i variable. It stores the number of elements already read from the input. Next, we read the number from the input and save it as a value of the a variable. The following operation block increases sum by the value of a, as well as increments the value of i.

The next block is a conditional one that checks whether i is not equal to n, which means that the required number of elements is not read from the input yet. If i is equal to n, the NO branch is chosen and a value of the result variable is set to a result of a division of sum by n. Then, the result variable is returned and the execution stops. An interesting construction is used when the conditional expression evaluates to true, which means that we need to read another input. Then, the loop is used and the execution comes back just before the input block for reading a. Thus, we can execute some operations multiple times, until the condition is met.

As you can see, a flowchart is a diagram that makes it possible to specify a way of algorithm operation in a more precise way than using natural language. It is an interesting option for simple algorithms, but it can be quite cumbersome in the case of advanced and complex ones, where it is impossible to present the whole operation within a diagram of a reasonably small size.

Pseudocode

The next notation we’ll look at is pseudocode. It allows you to specify algorithms in another way, which is a bit similar to the code written in a programming language. Here, we use the English language to define inputs and outputs, as well as to present a set of instructions clearly and concisely, but without the syntax of any programming language.

Here’s some example pseudocode for calculating the arithmetic mean:

INPUT:
n – total number of elements used for mean calculation.
a – the following numbers entered by a user.
OUTPUT:
result - arithmetic mean of the entered numbers.
INSTRUCTIONS:
sum <- 0
read n
if n = 0 then
   return null
endif
i <- 0
do
   read a
   sum <- sum + a
   i <- i + 1
while i <> n
result <- sum / n
return result

As you can see, the pseudocode provides us with a syntax that is easy to understand and follow, as well as quite close to a programming language. For this reason, it is a precise way of algorithm presentation and documentation that can be later used to transform it into a set of instructions in our chosen programming language.

Programming language

Now, let’s look at the last form of algorithm notation: programming language. It is very precise, can be compiled and run. Thus, we can see the result of its operation and check it using a set of test cases. Of course, we can implement an algorithm in any programming language. However, in this book, you will see only examples in the C# language.

Let’s take a look at the implementation of the mean calculation algorithm:

double sum = 0;
Console.Write("n = ");
int.TryParse(Console.ReadLine(), out int n);
if (n == 0) { Console.WriteLine("No result."); }
int i = 0;
do
{
    Console.Write("a = ");
    double.TryParse(Console.ReadLine(), out double a);
    sum += a;
    i++;
}
while (i != n);
double result = sum / n;
Console.WriteLine($"Result: {result:F2}");

The preceding code contains an if conditional statement and a do-while loop.

If we run the application, we need to enter the number of elements from which we would like to calculate the arithmetic mean. Then, we will be asked to enter the number n times. When the number of provided elements is equal to the expected value, the result is calculated and presented in the console, as follows:

n = 3
a = 1
a = 5
a = 10
Result: 5.33

That’s all! Now, you know what algorithms are, where you can find them in your daily life, as well as how to represent algorithms using natural language, flowcharts, pseudocode, and programming languages. With this knowledge, let’s proceed to learn about different types of algorithms, including recursive and heuristic algorithms.