Search icon CANCEL
Arrow left icon
Explore Products
Best Sellers
New Releases
Books
Videos
Audiobooks
Learning Hub
Conferences
Free Learning
Arrow right icon
C# Data Structures and Algorithms
C# Data Structures and Algorithms

C# Data Structures and Algorithms: Explore the possibilities of C# for developing a variety of efficient applications

eBook
$29.99 $43.99
Paperback
$54.99
Subscription
Free Trial
Renews at $19.99p/m

What do you get with Print?

Product feature icon Instant access to your digital eBook copy whilst your Print order is Shipped
Product feature icon Paperback book shipped to your preferred address
Product feature icon Download this book in EPUB and PDF formats
Product feature icon Access this title in our online reader with advanced features
Product feature icon DRM FREE - Read whenever, wherever and however you want
Table of content icon View table of contents Preview book icon Preview Book

C# Data Structures and Algorithms

Getting Started

Developing applications is certainly something exciting to work on, but it is also challenging, especially if you need to solve some complex problems that involve advanced data structures and algorithms. In such cases, you often need to take care of performance to ensure that the solution will work smoothly on devices with limited resources. Such a task could be really difficult and could require significant knowledge regarding not only the programming language, but also data structures and algorithms.

Did you know that replacing even one data structure with another could cause the performance results to increase hundreds of times? Does it sound impossible? Maybe, but it is true! As an example, I would like to tell you a short story about one of the projects in which I was involved. The aim was to optimize the algorithm of finding connections between blocks on a graphical diagram. Such connections should be automatically recalculated, refreshed, and redrawn as soon as any block has moved in the diagram. Of course, connections cannot go through blocks and cannot overlap other lines, and the number of crossings and direction changes should be limited. Depending on the size and the complexity of the diagram, the performance results differ. However, while conducting tests, we have received results in the range from 1 ms to almost 800 ms for the same test case. What could be the most surprising aspect is that such a huge improvement has been reached mainly by... changing data structures of two sets.

Now, you could ask yourself the obvious question: which data structures should I use in given circumstances and which algorithms could be used to solve some common problems? Unfortunately, the answer is not simple. However, within this book, you will find a lot of information about data structures and algorithms, presented in the context of the C# programming language, with many examples, code snippets, and detailed explanations. Such content could help you to answer the aforementioned questions while developing the next great solutions, which could be used by many people all over the world! Are you ready to start your adventure with data structures and algorithms? If so, let's start!

In this chapter, you will cover the following topics:

  • Programming language
  • Data types
  • Installation and configuration of the IDE
  • Creating the project
  • Input and output
  • Launching and debugging

Programming language

As a developer, you have certainly heard about many programming languages, such as C#, Java, C++, C, PHP, or Ruby. In all of them, you can use various data structures, as well as implement algorithms, to solve both basic and complex problems. However, each language has its own specificity, which could be visible while implementing data structures and accompanying algorithms. As already mentioned, this book will focus only on the C# programming language, which is also the main topic of this section.

The C# language, pronounced as "C Sharp", is a modern, general-purpose, strongly-typed, and object-oriented programming language that can be used while developing a wide range of applications, such as web, mobile, desktop, distributed, and embedded solutions, as well as even games. It cooperates with various additional technologies and platforms, including ASP.NET MVC, Windows Store, Xamarin, Windows Forms, XAML, and Unity. Therefore, when you learn the C# language, as well as getting to know more about data structures and algorithms in the context of this programming language, you can use such skills to create more than one particular type of software.

The current version of the language is C# 7.1. It is worth mentioning its interesting history with the following versions of the language (for example, 2.0, 3.0, and 5.0) in which new features have been added to increase language possibilities and to simplify the work of developers. When you take a look at release notes for particular versions, you will see how the language is being improved and expanded over time.

The syntax of the C# programming language is similar to other languages, such as Java or C++. For this reason, if you know such languages, you should quite easily be able to understand the code written in C#. As an example, similarly as in the languages mentioned previously, the code consists of statements that end with semicolons (;), and curly brackets ({ and }) are used to group statements, such as within the foreach loop. You could also find similar code constructions, such as the if statement, or while and for loops.

Developing various applications in the C# language is also simplified by the availability of many additional great features, such as Language Integrated Query (LINQ), which allows developers to get data from various collections, such as SQL databases or XML documents, in a consistent way. There are also some approaches to shorten the required code, such as using lambda expressions, expression-bodied members, getters and setters, or string interpolation. It is worth mentioning the automatic garbage collection that simplifies the task of releasing memory. Of course, the solutions mentioned are only the very limited subset of features available while developing in C#. You will see some others in the following parts of this book, together with examples and detailed descriptions.

Data types

While developing applications in the C# language, you could use various data types, which are divided into two groups, namely value types and reference types. The difference between them is very simple—a variable of a value type directly contains data, while a variable of a reference type just stores a reference to data, as shown as follows:

As you can see, a Value type stores its actual Value directly in the Stack memory, while a Reference type only stores a Reference here. The actual value is located in the Heap memory. Therefore, it is also possible to have two or more variables of a reference type that reference exactly the same value.

Of course, a difference between value and reference types is very important while programming and you should know which types belong to the groups mentioned. Otherwise, you could make mistakes in the code that could be quite difficult to find. For instance, you should remember to take care while updating the data of a reference type, because the change could also be reflected in other variables that are referencing the same object. Moreover, you should be careful while comparing two objects with the equals (=) operator, because you could compare the reference, not the data itself, in the case of two instances of a reference type.

The C# language also supports pointer types, which can be declared as type* identifier or void* identifier. However, such types are beyond the scope of this book. You can read more about them at: https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/unsafe-code-pointers/pointer-types.

Value types

Structs

Within structs, you have access to many built-in types, which could be used either as keywords or types from the System namespace.

One of them is the Boolean type (the bool keyword), which makes it possible to store a logical value, that is, one of two values, namely true or false.

As for storing integer values, you can use one of the following types: Byte (the byte keyword), SByte (sbyte), Int16 (short), UInt16 (ushort), Int32 (int), UInt32 (uint), Int64 (long), and UInt64 (ulong). They differ by the number of bytes for storing values and therefore by the range of available values. As an example, the short data type supports values in the range from -32,768 to 32,767 while uint supports values in the range from 0 to 4,294,967,295. Another type within the integral types is Char (char), which represents a single Unicode character such as 'a' or 'M'.

In the case of floating-point values, you can use two types, namely Single (float) and Double (double). The first uses 32 bits, while the second uses 64 bits. Thus, their precision differs significantly.

What's more, the Decimal type (the decimal keyword) is available. It uses 128 bits and is a good choice for monetary calculations.

An example declaration of a variable in the C# programming language is as follows:

int number; 

You can assign a value to a variable using the equals sign (=), shown as follows:

number = 500; 

Of course, declaration and assignment could be performed in the same line:

int number = 500; 

If you want to declare and initialize an immutable value, that is, a constant, you can use the const keyword, as shown in the following line of code:

const int DAYS_IN_WEEK = 7; 
More information about the built-in data types, together with the complete list of ranges, is available at: https://msdn.microsoft.com/library/cs7y5x0x.aspx.

Enumerations

Apart from structs, the value types contain enumerations. Each has a set of named constants to specify the available set of values. For instance, you can create the enumeration for available languages or supported currencies. An example definition is as follows:

enum Language { PL, EN, DE }; 

Then, you can use the defined enumeration as a data type, as shown as follows:

Language language = Language.PL; 
switch (language) 
{ 
    case Language.PL: /* Polish version */ break; 
    case Language.DE: /* German version */ break; 
    default: /* English version */ break; 
} 

It is worth mentioning that enumerations allow you to replace some magical strings (such as "PL" or "DE") with constant values and this has a positive impact on code quality.

You can also benefit from more advanced features of enumerations, such as changing the underlying type or specifying values for particular constants. You can find more information at: https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/enum.

Reference types

The second main group of types is named reference types. Just as a quick reminder, a variable of a reference type does not directly contain data, because it just stores a reference to data. In this group, you can find three built-in types, namely string, object, and dynamic. Moreover, you can declare classes, interfaces, and delegates.

More information about the reference types is available at: https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/reference-types.

Strings

There is often the necessity to store some text values. You can achieve this goal using the String built-in reference type from the System namespace, which is also available using the string keyword. The string type is a sequence of Unicode characters. It can have zero chars, one or more chars, or the string variable can be set to null.

You can perform various operations on string objects, such as concatenation or accessing a particular char using the [] operator, as shown as follows:

string firstName = "Marcin", lastName = "Jamro"; 
int year = 1988; 
string note = firstName + " " + lastName.ToUpper()  
   + " was born in " + year; 
string initials = firstName[0] + "." + lastName[0] + "."; 

At the beginning, the firstName variable is declared, and the "Marcin" value is assigned to it. Similarly, "Jamro" is set as a value of the lastName variable. In the third line, you concatenate five strings (using the + operator), namely, the current value of firstName, the space, the current value of lastName converted to the upper-case string (by calling the ToUpper method), the string " was born in ", and the current value of the year variable. In the last line, the first chars from firstName and lastName variables are obtained, using the [] operator, as well as concatenated with two dots to form the initials, that is, M.J., which are stored as a value of the initials variable.

The Format static method could also be used for constructing the string, as follows:

string note = string.Format("{0} {1} was born in {2}",  
   firstName, lastName.ToUpper(), year); 

In this example, you specify the composite format string with three format items, namely the firstName (represented by {0}), upper-case lastName ({1}), and the year ({2}). The objects to format are specified as the following parameters.

It is also worth mentioning the interpolated string, which uses interpolated expressions to construct a string. To create a string using this approach, the $ character should be placed before ", as shown in the following example:

string note = $"{firstName} {lastName.ToUpper()}  
   was born in {year}"; 

Object

The Object class, declared in the System namespace, performs a very important role while developing applications in the C# language because it is the base class for all classes. It means that built-in value types and built-in reference types, as well as user-defined types, are derived from the Object class, which is also available by using the object alias.

As the object type is the base entity for all value types, it means that it is possible to convert a variable of any value type (for example, int or float) to the object type, as well as to convert back a variable of the object type to a specific value type. Such operations are named boxing (the first one) and unboxing (the other). They are shown as follows:

int age = 28; 
object ageBoxing = age; 
int ageUnboxing = (int)ageBoxing; 

Dynamic

Apart from the types already described, the dynamic one is available for developers. It allows the bypassing of type checking during compilation so that you can perform it during the run time. Such a mechanism is useful while accessing some application programming interfaces (APIs), but it will not be used in this book.

Classes

As already mentioned, C# is an object-oriented language and supports declaration of classes together with various members, including constructors, finalizers, constants, fields, properties, indexers, events, methods, and operators, as well as delegates. Moreover, classes support inheritance and implementing interfaces. Static, abstract, and virtual members are available, as well.

An example class is shown as follows:

public class Person 
{ 
    private string _location = string.Empty; 
    public string Name { get; set; } 
    public int Age { get; set; } 
 
    public Person() => Name = "---"; 
 
    public Person(string name, int age) 
    { 
        Name = name; 
        Age = age; 
    } 
 
    public void Relocate(string location) 
    { 
        if (!string.IsNullOrEmpty(location)) 
        { 
            _location = location; 
        } 
    } 
 
    public float GetDistance(string location) 
    { 
        return DistanceHelpers.GetDistance(_location, location); 
    } 
} 

The Person class contains the _location private field with the default value set as the empty string (string.Empty), two public properties (Name and Age), a default constructor that sets a value of the Name property to --- using the expression body definition, an additional constructor that takes two parameters and sets values of properties, the Relocate method that updates the value of the private field, as well as the GetDistance method that calls the GetDistance static method from the DistanceHelpers class and returns the distance between two cities in kilometers.

You can create an instance of the class using the new operator. Then, you can perform various operations on the object created, such as calling a method, as shown as follows:

Person person = new Person("Mary", 20); 
person.Relocate("Rzeszow"); 
float distance = person.GetDistance("Warsaw");  

Interfaces

In the previous section, a class was mentioned that could implement one or more interfaces. It means that such a class must implement all methods, properties, events, and indexers, that are specified in all implemented interfaces. You can easily define interfaces in the C# language using the interface keyword.

As an example, let's take a look at the following code:

public interface IDevice 
{ 
    string Model { get; set; } 
    string Number { get; set; } 
    int Year { get; set; } 
 
    void Configure(DeviceConfiguration configuration); 
    bool Start(); 
    bool Stop(); 
} 

The IDevice interface contains three properties, namely those representing a device model (Model), serial number (Number), and production year (Year). What's more, it has signatures of three methods, which are Configure, Start, and Stop. When a class implements the IDevice interface, it should contain the mentioned properties and methods.

Delegates

The delegate reference type allows specification of the required signature of a method. The delegate could then be instantiated, as well as invoked, as shown in the following code:

delegate double Mean(double a, double b, double c); 
 
static double Harmonic(double a, double b, double c) 
{ 
    return 3 / ((1 / a) + (1 / b) + (1 / c)); 
} 
 
static void Main(string[] args) 
{ 
    Mean arithmetic = (a, b, c) => (a + b + c) / 3; 
    Mean geometric = delegate (double a, double b, double c) 
    { 
        return Math.Pow(a * b * c, 1 / 3.0); 
    }; 
    Mean harmonic = Harmonic; 
    double arithmeticResult = arithmetic.Invoke(5, 6.5, 7); 
    double geometricResult = geometric.Invoke(5, 6.5, 7); 
    double harmonicResult = harmonic.Invoke(5, 6.5, 7); 
} 

In the example, the Mean delegate specifies the required signature of the method for calculating the mean value of three floating-point numbers. It is instantiated with the lambda expression (arithmetic), anonymous method (geometric), and named method (harmonic). Each delegate is invoked by calling the Invoke method.

Installation and configuration of the IDE

While reading the book, you will see many examples presenting data structures and algorithms, together with detailed descriptions. The most important parts of the code will be shown directly in the book. Moreover, complete source code will be available to download. Of course, you can only read the code from the book, but it is strongly recommended to write such code on your own, and then launch and debug the program to understand how various data structures and algorithms operate.

As already mentioned, the examples shown in the book will be prepared in the C# language. To keep things simple, the console-based applications will be created, but such data structures could be used in other kinds of solutions as well.

The example projects will be created in Microsoft Visual Studio 2017 Community. This Integrated Development Environment (IDE) is a comprehensive solution for developing various kinds of projects. To download, install, and configure it, you should:

  1. Open the website https://www.visualstudio.com/downloads/ and choose the Free download option from the Visual Studio Community 2017 section just below the Visual Studio Downloads header. The download process of the installer should begin automatically.
  2. Run the downloaded file and follow the instructions to start the installation. When the screen presenting possible options is shown, choose the .NET desktop development option, as shown in the following screenshot. Then, click Install. The installation could take some time, but its progress could be observed using the Acquiring and Applying progress bars.
  1. When the message Installation succeeded! is shown, click on the Launch button to start the IDE. You will be asked to sign in with the Microsoft account. Then, you should choose suitable Development Settings (such as Visual C#) in the Start with a familiar environment section. Moreover, you should choose the color theme from Blue, Blue (Extra Contrast), Dark, and Light. At the end, click on the Start Visual Studio button.

Creating the project

Just after launching the IDE, let's proceed by creating a new project. Such a process will be performed many times while reading the book to create the example applications according to information provided in particular chapters.

To create a new project:

  1. Click on File | New | Project in the main menu.
  2. Choose Installed | Visual C# | Windows Classic Desktop on the left in the New Project window, as shown in the following screenshot. Then, click on Console App (.NET Framework) in the middle. You should also type a name of the project (Name) and a name of the solution (Solution name), as well as select location for the files (Location) by pressing the Browse button. At the end, click on OK to automatically create the project and generate the necessary files:

Congratulations, you have just created the first project! But what is inside?

Let's take a look at the Solution Explorer window, which presents the structure of the project. It is worth mentioning that the project is included in the solution with the same name. Of course, a solution could contain more than one project, which is a common scenario while developing more complex applications.

If you cannot find the Solution Explorer window, you could open it by choosing the View | Solution Explorer option from the main menu. In a similar way, you could open other windows, such as Output or Class View. If you cannot find a suitable window (for example, C# Interactive) directly within the View option, let's try to find it in the View | Other Windows node.

The automatically generated project (named GettingStarted) has the following structure:

  • The Properties node with one file (AssemblyInfo.cs) that contains general information about the assembly with the application, such as about its title, copyright, and version. The configuration is performed using attributes, for example, AssemblyTitleAttribute and AssemblyVersionAttribute.
  • The References element presents additional assemblies or projects that are used by the project. It is worth noting that you could easily add references by choosing the Add Reference option from the context menu of the References element. Moreover, you could install additional packages using the NuGet Package Manager, which could be launched by choosing Manage NuGet Packages from the References context menu.
It is a good idea to take a look at packages already available before writing the complex module on your own because a suitable package could be already available for developers. In such a case, you could not only shorten the development time, but also reduce the chance of introducing mistakes.
  • The App.config file contains the Extensible Markup Language (XML)-based configuration of the application, including the number of the minimum supported version of the .NET Framework platform.
  • The Program.cs file contains the code of the main class in the C# language. You could adjust the behavior of the application by changing the following default implementation:
using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 
 
namespace GettingStarted 
{ 
    class Program 
    { 
        static void Main(string[] args) 
        { 
        } 
    } 
} 

The initial content of the Program.cs file contains the definition of the Program class within the GettingStarted namespace. The class contains the Main static method, which is called automatically when the application is launched. The five using statements are included as well, namely System, System.Collections.Generic, System.Linq, System.Text, and System.Threading.Tasks.

Before proceeding, let's take a look at the structure of the project in the file explorer, not in the Solution Explorer window. Are such structures exactly the same?

You could open the directory with the project in the file explorer by choosing the Open Folder in File Explorer option from the context menu of the project node in the Solution Explorer window.

First of all, you can see the bin and obj directories, which are generated automatically. Both contain Debug and Release directories, whose names are related to the configuration set in the IDE. After building the project, a subdirectory of the bin directory (that is, Debug or Release) contains .exe, .exe.config, and .pdb files, while the subdirectory in the obj directory—for examplecontains .cache and some temporary .cs files. What's more, there is no References directory, but there are .csproj and .csproj.user files with XML-based configurations of the project. Similarly, the solution-based .sln configuration file is located in the solution's directory.

If you are using a version control system, such as SVN or Git, you could ignore the bin and obj directories, as well as the .csproj.user file. All of them can be generated automatically.

If you want to learn how to write some example code, as well as launch and debug the program, let's proceed to the next section.

Input and output

Many examples shown in the following part of the book will require interaction with the user, especially by reading input data and showing output. You can easily add such features to the application, as explained in this section.

Reading from input

The application can read data from the standard input stream using a few methods from the Console static class from the System namespace, such as ReadLine and ReadKey. Both are presented in the examples in this section.

Let's take a look at the following line of code:

string fullName = Console.ReadLine(); 

Here, you use the ReadLine method. It waits until the user presses the Enter key. Then, the entered text is stored as a value of the fullName string variable.

In a similar way, you can read data of other types, such as int, as shown as follows:

string numberString = Console.ReadLine(); 
int.TryParse(numberString, out int number); 

In this case, the same ReadLine method is called and the entered text is stored as a value of the numberString variable. Then, you just need to parse it to int and store it as a value of the int variable. How can you do that? The solution is very simple—use the TryParse static method of the Int32 struct. It is worth mentioning that such a method returns a Boolean value, indicating whether the parsing process has finished successfully. Thus, you can perform some additional actions when the provided string representation is incorrect.

A similar scenario, regarding the DateTime structure and the TryParseExact static method, is shown in the following example:

string dateTimeString = Console.ReadLine(); 
if (!DateTime.TryParseExact( 
    dateTimeString, 
    "M/d/yyyy HH:mm", 
    new CultureInfo("en-US"), 
    DateTimeStyles.None, 
    out DateTime dateTime)) 
{ 
    dateTime = DateTime.Now; 
} 

This example is more complicated than the previous one, so let's explain it in detail. First of all, the string representation of the date and time is stored as a value of the dateTimeString variable. Then, the TryParseExact static method of the DateTime struct is called, passing five parameters, namely the string representation of the date and time (dateTimeString), the expected format of the date and time (M/d/yyyy HH:mm), the supported culture (en-US), the additional styles (None), as well as the output variable (dateTime) passed by reference using the out parameter modifier.

If the parsing is not completed successfully, the current date and time (DateTime.Now) is assigned to the dateTime variable. Otherwise, the dateTime variable contains the DateTime instance consistent with the string representation provided by the user.

While writing the part of code involving the CultureInfo class name, you could see the following error: CS0246 The type or namespace name 'CultureInfo' could not be found (are you missing a using directive or an assembly reference?). This means that you do not have a suitable using statement at the top of the file. You can easily add one by clicking on the bulb icon shown in the left-hand margin of the line with the error and choosing the using System.Globalization; option. The IDE will automatically add the missing using statement and the error will disappear.

Apart from reading the whole line, you can also get to know which character or function key has been pressed by the user. To do so, you can use the ReadKey method, as shown in the following part of code:

ConsoleKeyInfo key = Console.ReadKey(); 
switch (key.Key) 
{ 
    case ConsoleKey.S: /* Pressed S */ break; 
    case ConsoleKey.F1: /* Pressed F1 */ break; 
    case ConsoleKey.Escape: /* Pressed Escape */ break; 
} 

After calling the ReadKey static method and once any key has been pressed by a user, information about the pressed key is stored as the ConsoleKeyInfo instance (that is, key, in the current example). Then, you use the Key property to get an enumeration value (of ConsoleKey) representing a particular key. At the end, the switch statement is used to perform operations depending on the key that has been pressed. In the example shown, three keys are supported, namely S, F1, and Esc.

Writing to output

Now, you know how to read input data, but how can you ask questions to the user or present results on the screen? The answer, together with examples, is shown in this section.

Similarly as in the case of reading data, operations related to the standard output stream are performed using methods of the Console static class from the System namespace, namely Write and WriteLine. Let's see them in action!

To write some text, you can just call the Write method, passing the text as a parameter. An example of code is as follows:

Console.Write("Enter a name: "); 

The preceding line causes the following output to be shown:

    Enter a name: 

What's important here is that the written text is not followed by the line terminator. If you want to write some text and move to the next line, you can use the WriteLine method, as shown in the following code snippet:

Console.WriteLine("Hello!"); 

After executing this line of code, the following output is presented:

    Hello!

Of course, you can also use Write and WriteLine methods in more complex scenarios. For example, you can pass many parameters to the WriteLine method, namely the format and additional arguments, as shown in the following part of the code:

string name = "Marcin"; 
Console.WriteLine("Hello, {0}!", name); 

In this case, the line will contain Hello, a comma, a space, a value of the name variable (that is, Marcin), as well as the exclamation mark. The output is shown as follows:

    Hello, Marcin!

The next example presents a significantly more complex scenario of writing the line regarding the confirmation of a table reservation at a restaurant. The output should have the format Table [number] has been booked for [count] people on [date] at [time]. You can achieve this goal by using the WriteLine method, as shown as follows:

string tableNumber = "A100"; 
int peopleCount = 4; 
DateTime reservationDateTime = new DateTime( 
    2017, 10, 28, 11, 0, 0); 
CultureInfo cultureInfo = new CultureInfo("en-US"); 
Console.WriteLine( 
    "Table {0} has been booked for {1} people on {2} at {3}", 
    tableNumber, 
    peopleCount, 
    reservationDateTime.ToString("M/d/yyyy", cultureInfo), 
    reservationDateTime.ToString("HH:mm", cultureInfo)); 

The example starts with a declaration of four variables, namely tableNumber (A100), peopleCount (4), and reservationDateTime (10/28/2017 at 11:00 AM), as well as cultureInfo (en-US). Then, the WriteLine method is called passing five parameters, namely the format string followed by arguments that should be shown in the places marked with {0}, {1}, {2}, and {3}. It is worth mentioning the last two lines, where the string presenting date (or time) is created, based on the current value of the reservationDateTime variable.

After executing this code, the following line is shown in the output:

    Table A100 has been booked for 4 people on 10/28/2017 at 11:00 

Of course, in real-world scenarios, you will use read- and write-related methods in the same code. For example, you can ask a user to provide a value (using the Write method) and then read the text entered (using the ReadLine method).

This simple example, which is also useful in the next section of this chapter, is shown as follows. It allows the user to enter data relating to the table reservation, namely the table number and the number of people, as well as the reservation date. When all of the data is entered, the confirmation is presented. Of course, the user will see information about the data that should be provided:

using System; 
using System.Globalization; 
 
namespace GettingStarted 
{ 
    class Program 
    { 
        static void Main(string[] args) 
        { 
            CultureInfo cultureInfo = new CultureInfo("en-US"); 
 
            Console.Write("The table number: "); 
            string table = Console.ReadLine(); 
 
            Console.Write("The number of people: "); 
            string countString = Console.ReadLine(); 
            int.TryParse(countString, out int count); 
 
            Console.Write("The reservation date (MM/dd/yyyy): "); 
            string dateTimeString = Console.ReadLine(); 
            if (!DateTime.TryParseExact( 
                dateTimeString, 
                "M/d/yyyy HH:mm", 
                cultureInfo, 
                DateTimeStyles.None, 
                out DateTime dateTime)) 
            { 
                dateTime = DateTime.Now; 
            } 
 
            Console.WriteLine( 
                "Table {0} has been booked for {1} people on {2}  
                 at {3}", 
                table, 
                count, 
                dateTime.ToString("M/d/yyyy", cultureInfo), 
                dateTime.ToString("HH:mm", cultureInfo)); 
        } 
    } 
} 

The preceding code snippet is based on the parts of code shown and described previously. After launching the program and entering the necessary data, the output could look as follows:

    The table number: A100
    The number of people: 4
    The reservation date (MM/dd/yyyy): 10/28/2017 11:00
    Table A100 has been booked for 4 people on 10/28/2017 at 11:00
    Press any key to continue . . . 

When the code is created, it is a good idea to improve its quality. One of the interesting possibilities associated with the IDE is related to removing unused using statements, together with sorting the remaining ones. You can easily perform such an operation by choosing the Remove and Sort Usings option from the context menu in the text editor.

Launching and debugging

Unfortunately, the written code doesn't always work as expected. In such a case, it is a good idea to start debugging to see how the program operates, find the source of the problem, and correct it. This task is especially useful for complex algorithms, where the flow could be complicated, and therefore quite difficult to analyze just by reading the code. Fortunately, the IDE is equipped with various features for debugging that will be presented in this section.

First of all, let's launch the application to see it in action! To do so, you just need to select a proper configuration from the drop-down list (Debug, in this example) and click on the button with the green triangle and the Start caption in the main toolbar, or press F5. To stop debugging, you can choose Debug | Stop Debugging or press Shift + F5.

You can also run the application without debugging. To do so, choose Debug | Start Without Debugging from the main menu or press Ctrl + F5.

As already mentioned, there are various debugging techniques, but let's start with breakpoint-based debugging, since it is one of the most common approaches offering huge opportunities. You can place a breakpoint in any line of the code. The program will stop as soon as the line is reached, before executing it. Then, you can see the values of particular variables to check whether the application works as expected.

To add a breakpoint, you can either click on the left-hand margin (next to the line on which the breakpoint should be placed) or place the cursor on the line (where the breakpoint should be added) and press the F9 key. In both cases, the red circle will be shown, as well as the code from the given line will be marked with a red background, as shown in line 17 in the following screenshot:

When a line with the breakpoint is reached while executing the program, it stops, and the line is marked with the yellow background and the margin icon changes, as shown in line 15 in the screenshot. Now, you can check the value of the variable by simply moving the cursor over its name. The current value will appear in the ToolTip.

You can also click on the pin icon located on the right-hand side of the ToolTip to pin it in the editor. Its value will then be visible without the necessity of moving the cursor over the name of the variable. Such a value will be automatically refreshed as soon as it has changed. The result is presented in the following screenshot.

The IDE could adjust its appearance and features depending on the operations performed currently. For example, while debugging, you have access to some special windows, such as Locals, Call Stack, and Diagnostic Tools. The first shows available local variables together with their types and values. The Call Stack window presents information about the following called methods. The last one (namely Diagnostic Tools) shows information about memory and CPU usage, as well as events.

Moreover, the IDE supports conditional breakpoints that stop execution of the program only if the associated Boolean expression is evaluated to true. You can add a condition to a given breakpoint by choosing the Conditions option from the context menu, which is shown after right-clicking on the breakpoint icon in the left-hand margin. Then, the Breakpoint Settings window appears, where you should check the Conditions checkbox and specify the Conditional Expression, such as the one shown in the following screenshot. In the example, execution will stop only when the value of the count variable is greater than 5, that is, count > 5:

When the execution is stopped, you can use the step-by-step debugging technique. To move execution of the program to the next line (without incorporating another breakpoint), you can click on the Step Over icon in the main toolbar or press F10. If you want to step into the method, which is called in the line where the execution has stopped, just click on the Step Into button or press F11. Of course, you can also go to the next breakpoint by clicking on the Continue button or by pressing F5.

The next interesting feature, available in the IDE, is called Immediate Window. It allows developers to execute various expressions when the program execution is stopped using the current values of the variables. You just need to enter an expression in the Immediate Window and press the Enter key. The example is shown in the following screenshot:

Here, the lower-case version of the table number is returned by executing table.ToLower(). Then, the total number of minutes between the current date and the dateTime variable is calculated and shown in the window.

Summary

This was only the first chapter of the book, but it contained quite a lot of information that will be useful while reading the remaining ones. At the beginning, you saw that using proper data structures and algorithms is not an easy task, but could have a significant impact on the performance of the developed solution. Then, the C# programming language was briefly presented with a focus on showing various data types, both value and reference ones. Classes, interfaces, and delegates were also described.

In the following part of the chapter, the process of installation and configuration of the IDE was presented. Then, you learned how to create a new project, and its structure has been described in details. Next, you saw how to read data from the standard input stream, as well as how to write data to the standard output stream. The read- and write-related operations were also mixed into one example.

At the end of the chapter, you saw how to run the example program, as well as how to debug it using breakpoints and step-by-step debugging to find the source of the problem. What's more, you learned the possibilities of the Immediate Window feature.

After this introduction, you should be ready to proceed to the next chapter and see how to use arrays and lists, as well as accompanying algorithms. Let's go!

Left arrow icon Right arrow icon
Download code icon Download Code

Key benefits

  • Master array, set and map with trees and graphs, among other fundamental data structures
  • Delve into effective design and implementation techniques to meet your software requirements
  • Explore illustrations to present data structures and algorithms, as well as their analysis in a clear, visual manner

Description

Data structures allow organizing data efficiently. They are critical to various problems and their suitable implementation can provide a complete solution that acts like reusable code. In this book, you will learn how to use various data structures while developing in the C# language as well as how to implement some of the most common algorithms used with such data structures. At the beginning, you will get to know arrays, lists, dictionaries, and sets together with real-world examples of your application. Then, you will learn how to create and use stacks and queues. In the following part of the book, the more complex data structures will be introduced, namely trees and graphs, together with some algorithms for searching the shortest path in a graph. We will also discuss how to organize the code in a manageable, consistent, and extendable way. By the end of the book,you will learn how to build components that are easy to understand, debug, and use in different applications.

Who is this book for?

This book is for developers who would like to learn the Data Structures and Algorithms in C#. Basic C# programming knowledge would be an added advantage.

What you will learn

  • How to use arrays and lists to get better results in complex scenarios
  • Implement algorithms like the Tower of Hanoi on stacks of C# objects
  • Build enhanced applications by using hashtables, dictionaries and sets
  • Make a positive impact on efficiency of applications with tree traversal
  • Effectively find the shortest path in the graph
Estimated delivery fee Deliver to Taiwan

Standard delivery 10 - 13 business days

$12.95

Premium delivery 5 - 8 business days

$45.95
(Includes tracking information)

Product Details

Country selected
Publication date, Length, Edition, Language, ISBN-13
Publication date : Apr 19, 2018
Length: 292 pages
Edition : 1st
Language : English
ISBN-13 : 9781788833738
Vendor :
Microsoft
Category :
Languages :

What do you get with Print?

Product feature icon Instant access to your digital eBook copy whilst your Print order is Shipped
Product feature icon Paperback book shipped to your preferred address
Product feature icon Download this book in EPUB and PDF formats
Product feature icon Access this title in our online reader with advanced features
Product feature icon DRM FREE - Read whenever, wherever and however you want
Estimated delivery fee Deliver to Taiwan

Standard delivery 10 - 13 business days

$12.95

Premium delivery 5 - 8 business days

$45.95
(Includes tracking information)

Product Details

Publication date : Apr 19, 2018
Length: 292 pages
Edition : 1st
Language : English
ISBN-13 : 9781788833738
Vendor :
Microsoft
Category :
Languages :

Packt Subscriptions

See our plans and pricing
Modal Close icon
$19.99 billed monthly
Feature tick icon Unlimited access to Packt's library of 7,000+ practical books and videos
Feature tick icon Constantly refreshed with 50+ new titles a month
Feature tick icon Exclusive Early access to books as they're written
Feature tick icon Solve problems while you work with advanced search and reference features
Feature tick icon Offline reading on the mobile app
Feature tick icon Simple pricing, no contract
$199.99 billed annually
Feature tick icon Unlimited access to Packt's library of 7,000+ practical books and videos
Feature tick icon Constantly refreshed with 50+ new titles a month
Feature tick icon Exclusive Early access to books as they're written
Feature tick icon Solve problems while you work with advanced search and reference features
Feature tick icon Offline reading on the mobile app
Feature tick icon Choose a DRM-free eBook or Video every month to keep
Feature tick icon PLUS own as many other DRM-free eBooks or Videos as you like for just $5 each
Feature tick icon Exclusive print discounts
$279.99 billed in 18 months
Feature tick icon Unlimited access to Packt's library of 7,000+ practical books and videos
Feature tick icon Constantly refreshed with 50+ new titles a month
Feature tick icon Exclusive Early access to books as they're written
Feature tick icon Solve problems while you work with advanced search and reference features
Feature tick icon Offline reading on the mobile app
Feature tick icon Choose a DRM-free eBook or Video every month to keep
Feature tick icon PLUS own as many other DRM-free eBooks or Videos as you like for just $5 each
Feature tick icon Exclusive print discounts

Frequently bought together


Stars icon
Total $ 142.97
C# 7 and .NET Core 2.0 High Performance
$48.99
C# Data Structures and Algorithms
$54.99
Hands-On Design Patterns with C# and .NET Core
$38.99
Total $ 142.97 Stars icon

Table of Contents

8 Chapters
Getting Started Chevron down icon Chevron up icon
Arrays and Lists Chevron down icon Chevron up icon
Stacks and Queues Chevron down icon Chevron up icon
Dictionaries and Sets Chevron down icon Chevron up icon
Variants of Trees Chevron down icon Chevron up icon
Exploring Graphs Chevron down icon Chevron up icon
Summary Chevron down icon Chevron up icon
Other Books You May Enjoy Chevron down icon Chevron up icon

Customer reviews

Top Reviews
Rating distribution
Full star icon Full star icon Full star icon Half star icon Empty star icon 3.7
(7 Ratings)
5 star 42.9%
4 star 14.3%
3 star 14.3%
2 star 28.6%
1 star 0%
Filter icon Filter
Top Reviews

Filter reviews by




Adam Sep 11, 2020
Full star icon Full star icon Full star icon Full star icon Full star icon 5
Overall this book is quite good. The code examples use good fundamentals of object oriented design. They also use built in c# constructs to get to the final data structure.The cons I’ve found so far are Merge sort is not present, and the tree visualization example doesn’t include putting blank space characters to space out the tree. (Add a for loop that looks for null characters and replaces them with spaces gets it to render correctly)Overall though this book explains complicated data structures in a simple way. It introduces recursion in a way that’s easy to implement. I’m happy with this purchase and it’s taught me a few tricks I didn’t know as a full time c# developer.
Amazon Verified review Amazon
Felix Mar 14, 2019
Full star icon Full star icon Full star icon Full star icon Full star icon 5
The books goes through all advanced data structures - Sets, Trees, Graphs, etc. For each of the structures it shows whether C# provides implementation out of the box (eg., for Dictionary), or there is third-party Nuget package (eg., Tree), or you need to develop your own implementation. Unfortunately, some NuGet packages haven't been updated since 2011 and are not compatible with .NET Core... oh well!For the programmers that skipped advanced data structures class, the book gives a refresher for things like AVL trees or Graph traversal. It also gives more algorithm implementations than you ever wanted to know.Finally, the book shows you what data structure fits what problem.
Amazon Verified review Amazon
jose antonio vega ruiz Feb 01, 2022
Full star icon Full star icon Full star icon Full star icon Full star icon 5
Good enough
Amazon Verified review Amazon
Emran Apr 15, 2021
Full star icon Full star icon Full star icon Full star icon Empty star icon 4
I am an experienced C# programmer, but, In our time, there was no C# book for data structure and algorithms. I learned Algorithms using Java. So, I was excited when I saw this book. That's the reason I bought it. But, I found a piece of terrible advice in this book, as you can see from the screenshot I attached. In the chapter on Dictionaries and Sets, when accessing a dictionary with a given key where the key does not exist, the application will crash. The book says, "You can prevent the application from crashing by using a try-catch block". I was shocked to see this advice. Try-Catch should never be the way to handle this situation. There are many better ways, like checking the "ContainsKey(.._) method, or the best way for performance is : dictionary.TryGetValue("keyName", out string foundValue);A book of algorithms should suggest the way that gives the better performance. But, try-catch is .,, I don't know what to say.Anyway, the book teaches some basic C# stuff which will be helpful for beginners, for sure. It talks about many algorithms. It could be more interesting, but can't complain much about that.
Amazon Verified review Amazon
Amazon Customer May 05, 2022
Full star icon Full star icon Full star icon Empty star icon Empty star icon 3
The DS are briefly explained, for more information look up MSDN ...
Amazon Verified review Amazon
Get free access to Packt library with over 7500+ books and video courses for 7 days!
Start Free Trial

FAQs

What is the delivery time and cost of print book? Chevron down icon Chevron up icon

Shipping Details

USA:

'

Economy: Delivery to most addresses in the US within 10-15 business days

Premium: Trackable Delivery to most addresses in the US within 3-8 business days

UK:

Economy: Delivery to most addresses in the U.K. within 7-9 business days.
Shipments are not trackable

Premium: Trackable delivery to most addresses in the U.K. within 3-4 business days!
Add one extra business day for deliveries to Northern Ireland and Scottish Highlands and islands

EU:

Premium: Trackable delivery to most EU destinations within 4-9 business days.

Australia:

Economy: Can deliver to P. O. Boxes and private residences.
Trackable service with delivery to addresses in Australia only.
Delivery time ranges from 7-9 business days for VIC and 8-10 business days for Interstate metro
Delivery time is up to 15 business days for remote areas of WA, NT & QLD.

Premium: Delivery to addresses in Australia only
Trackable delivery to most P. O. Boxes and private residences in Australia within 4-5 days based on the distance to a destination following dispatch.

India:

Premium: Delivery to most Indian addresses within 5-6 business days

Rest of the World:

Premium: Countries in the American continent: Trackable delivery to most countries within 4-7 business days

Asia:

Premium: Delivery to most Asian addresses within 5-9 business days

Disclaimer:
All orders received before 5 PM U.K time would start printing from the next business day. So the estimated delivery times start from the next day as well. Orders received after 5 PM U.K time (in our internal systems) on a business day or anytime on the weekend will begin printing the second to next business day. For example, an order placed at 11 AM today will begin printing tomorrow, whereas an order placed at 9 PM tonight will begin printing the day after tomorrow.


Unfortunately, due to several restrictions, we are unable to ship to the following countries:

  1. Afghanistan
  2. American Samoa
  3. Belarus
  4. Brunei Darussalam
  5. Central African Republic
  6. The Democratic Republic of Congo
  7. Eritrea
  8. Guinea-bissau
  9. Iran
  10. Lebanon
  11. Libiya Arab Jamahriya
  12. Somalia
  13. Sudan
  14. Russian Federation
  15. Syrian Arab Republic
  16. Ukraine
  17. Venezuela
What is custom duty/charge? Chevron down icon Chevron up icon

Customs duty are charges levied on goods when they cross international borders. It is a tax that is imposed on imported goods. These duties are charged by special authorities and bodies created by local governments and are meant to protect local industries, economies, and businesses.

Do I have to pay customs charges for the print book order? Chevron down icon Chevron up icon

The orders shipped to the countries that are listed under EU27 will not bear custom charges. They are paid by Packt as part of the order.

List of EU27 countries: www.gov.uk/eu-eea:

A custom duty or localized taxes may be applicable on the shipment and would be charged by the recipient country outside of the EU27 which should be paid by the customer and these duties are not included in the shipping charges been charged on the order.

How do I know my custom duty charges? Chevron down icon Chevron up icon

The amount of duty payable varies greatly depending on the imported goods, the country of origin and several other factors like the total invoice amount or dimensions like weight, and other such criteria applicable in your country.

For example:

  • If you live in Mexico, and the declared value of your ordered items is over $ 50, for you to receive a package, you will have to pay additional import tax of 19% which will be $ 9.50 to the courier service.
  • Whereas if you live in Turkey, and the declared value of your ordered items is over € 22, for you to receive a package, you will have to pay additional import tax of 18% which will be € 3.96 to the courier service.
How can I cancel my order? Chevron down icon Chevron up icon

Cancellation Policy for Published Printed Books:

You can cancel any order within 1 hour of placing the order. Simply contact customercare@packt.com with your order details or payment transaction id. If your order has already started the shipment process, we will do our best to stop it. However, if it is already on the way to you then when you receive it, you can contact us at customercare@packt.com using the returns and refund process.

Please understand that Packt Publishing cannot provide refunds or cancel any order except for the cases described in our Return Policy (i.e. Packt Publishing agrees to replace your printed book because it arrives damaged or material defect in book), Packt Publishing will not accept returns.

What is your returns and refunds policy? Chevron down icon Chevron up icon

Return Policy:

We want you to be happy with your purchase from Packtpub.com. We will not hassle you with returning print books to us. If the print book you receive from us is incorrect, damaged, doesn't work or is unacceptably late, please contact Customer Relations Team on customercare@packt.com with the order number and issue details as explained below:

  1. If you ordered (eBook, Video or Print Book) incorrectly or accidentally, please contact Customer Relations Team on customercare@packt.com within one hour of placing the order and we will replace/refund you the item cost.
  2. Sadly, if your eBook or Video file is faulty or a fault occurs during the eBook or Video being made available to you, i.e. during download then you should contact Customer Relations Team within 14 days of purchase on customercare@packt.com who will be able to resolve this issue for you.
  3. You will have a choice of replacement or refund of the problem items.(damaged, defective or incorrect)
  4. Once Customer Care Team confirms that you will be refunded, you should receive the refund within 10 to 12 working days.
  5. If you are only requesting a refund of one book from a multiple order, then we will refund you the appropriate single item.
  6. Where the items were shipped under a free shipping offer, there will be no shipping costs to refund.

On the off chance your printed book arrives damaged, with book material defect, contact our Customer Relation Team on customercare@packt.com within 14 days of receipt of the book with appropriate evidence of damage and we will work with you to secure a replacement copy, if necessary. Please note that each printed book you order from us is individually made by Packt's professional book-printing partner which is on a print-on-demand basis.

What tax is charged? Chevron down icon Chevron up icon

Currently, no tax is charged on the purchase of any print book (subject to change based on the laws and regulations). A localized VAT fee is charged only to our European and UK customers on eBooks, Video and subscriptions that they buy. GST is charged to Indian customers for eBooks and video purchases.

What payment methods can I use? Chevron down icon Chevron up icon

You can pay with the following card types:

  1. Visa Debit
  2. Visa Credit
  3. MasterCard
  4. PayPal
What is the delivery time and cost of print books? Chevron down icon Chevron up icon

Shipping Details

USA:

'

Economy: Delivery to most addresses in the US within 10-15 business days

Premium: Trackable Delivery to most addresses in the US within 3-8 business days

UK:

Economy: Delivery to most addresses in the U.K. within 7-9 business days.
Shipments are not trackable

Premium: Trackable delivery to most addresses in the U.K. within 3-4 business days!
Add one extra business day for deliveries to Northern Ireland and Scottish Highlands and islands

EU:

Premium: Trackable delivery to most EU destinations within 4-9 business days.

Australia:

Economy: Can deliver to P. O. Boxes and private residences.
Trackable service with delivery to addresses in Australia only.
Delivery time ranges from 7-9 business days for VIC and 8-10 business days for Interstate metro
Delivery time is up to 15 business days for remote areas of WA, NT & QLD.

Premium: Delivery to addresses in Australia only
Trackable delivery to most P. O. Boxes and private residences in Australia within 4-5 days based on the distance to a destination following dispatch.

India:

Premium: Delivery to most Indian addresses within 5-6 business days

Rest of the World:

Premium: Countries in the American continent: Trackable delivery to most countries within 4-7 business days

Asia:

Premium: Delivery to most Asian addresses within 5-9 business days

Disclaimer:
All orders received before 5 PM U.K time would start printing from the next business day. So the estimated delivery times start from the next day as well. Orders received after 5 PM U.K time (in our internal systems) on a business day or anytime on the weekend will begin printing the second to next business day. For example, an order placed at 11 AM today will begin printing tomorrow, whereas an order placed at 9 PM tonight will begin printing the day after tomorrow.


Unfortunately, due to several restrictions, we are unable to ship to the following countries:

  1. Afghanistan
  2. American Samoa
  3. Belarus
  4. Brunei Darussalam
  5. Central African Republic
  6. The Democratic Republic of Congo
  7. Eritrea
  8. Guinea-bissau
  9. Iran
  10. Lebanon
  11. Libiya Arab Jamahriya
  12. Somalia
  13. Sudan
  14. Russian Federation
  15. Syrian Arab Republic
  16. Ukraine
  17. Venezuela