The List data structure is one of the most used data structures in any programming language. Therefore, it is important to learn what it is and how to use it.
What is a data structure?
In Computer Science, we consider a data structure as a way to organize data to enable us to efficiently access the data. You can read more about it at this link.
Computer programs work with data. We give data as input and expect a certain output as a result. Because of this, it is important how we represent the data we get as input. Using this data representation, we have support to solve problems and give the output that a user needs or is expecting.
What is a list?
A list is simply a collection or group of objects, where each object has a position.
Let’s examine some examples so you get a better idea:
- Several people standing in line next to each other. In this case, you will be able to see the first person, the second person, a third person and so on. First, second and third is the position. In this case, we have a list of people.
- Several cars standing one behind another in a one-way street. You can see a first car, a second car, etc. Here you can see that all of them have a position. In this case, we have a list of cars.
- The result of the Olympic games. There is a first country, a second country, and so on. In this case, we have a list of countries.
- The rank of the students in your class according to the average marks. Here, you will see a first student (with the highest average marks), a second student (with the second-highest average marks), and so on. In this case, you have a list of students.
Now that you understand what a list is, let’s see the list data structure.
The List Abstract Data Type
“In computer science, an abstract data type (ADT) is a mathematical model for data types. An abstract data type is defined by its behaviour (semantics) from the point of view of a user, of the data, specifically in terms of possible values, possible operations on data of this type, and the behaviour of these operations” Source Wikipedia.
When using any programming language, you can usually specify the type of data you are going to store in the list. I will show later several examples of how to specify the type of objects you want to store.
Without regard to the programming language you are using, you can use common operations that are implemented as a part of the ADT List:
- Count: returns the number of elements in the list
- isEmpty: returns if the list is empty
- Contains(element): returns if the list contains a certain object
- Add(element): add an element to the list
- Remove(element): removes the given element from the list
- Remove(index): removes the element at the given index
- Get(index): return the element at the specified position in the list
- Set(index, element): sets the given element at the given position
- IndexOf(element): returns the position of the given element on the list
Most programming languages have an implementation of the ADT List. So, we can just go straight and use the classes provided by the programming language to use different types of lists.
Notice that one of the definitions of a class in Object-Oriented Programming is the following: A class is an ADT equipped with a possible partial implementation.
Therefore, we must look at the programming language we are using, for a class that implements the ADT List. Once we found the name, we can start using it to store lists of objects. The methods can vary slightly depending on the programming language you are using, but most of the basic methods will be available.
We already have arrays, why do we need a List ADT implementation?
Let’s think about the following situation: you must solve a problem, using OOP, in which you must deal with three different collections. A collection of students, a collection of marks and a collection of countries.
If you use arrays to model this situation, you will have to implement a way to add students, a way to add marks and a way to add countries to the three different arrays. As you can see, the three implementations will be the same, except for the type of object you are handling. This will result in repeated code, harder to maintain.
Now, the implementation of the ADT List comes to the rescue. You use the class list to store the objects you want to store, and then use the methods already implemented in that class.
Working in this way has the following benefits:
- You are following one of the main principles in OOP: code reuse. You don’t write the code to add an element to the collection twice. You actually don’t write a code for that at all.
- You don’t have repeated code in your program.
- You use code that is already tested and bug-free. A great advantage for your program.
- You write your code faster, focusing on what matters, to solve a problem. Instead of spending time on writing data structures that are already outside there for a long time.
- The code of your program will be shorter, and easier to understand and maintain.
- Among others.
List data structure example
In this case, we are going to use C# as a programming language, but the implementation should be similar to other programming languages.
Problem 1
Create a console application that stores a collection of integer numbers and prints it’s average.
/*
Create a console application that stores a collection of
integer numbers and print it's average.
*/
List<int> list = new List<int>();
list.Add(6);
list.Add(6);
list.Add(6);
list.Add(6);
list.Add(5);
list.Add(5);
int total = 0;
foreach (int value in list) {
total += value;
}
float average = (float) total / list.Count;
Console.WriteLine($"The average value is {average}");
The explanation of the code above is simple. You add values to the list using the Add method.
The second part of the code is the implementation of the basic algorithm for summing. You can find the 5 basic algorithms in this post.
See an example of output below.
In the picture above, I printed all the decimal digits. However, you can see examples about how to print a certain decimal number of digits in C#. This is useful in certain situations.
Problem 2
Create a console application that stores a collection of students and prints if a certain student is part of the collection or not. Students have a student number and the country they were born in.
In this case, we must implement a class that represents students. Then, we can implement the console application.
public class Student
{
private string studentNumber;
public string StudentNumber{
get => studentNumber;
}
private string name;
private string country;
public Student(string studentNumber, string name, string country)
{
this.studentNumber = studentNumber;
this.name = name;
this.country = country;
}
}
List<Student> list = new List<Student>();
list.Add(new Student("1", "Joe", "USA"));
list.Add(new Student("2", "Jane", "USA"));
list.Add(new Student("3", "Josh", "China"));
list.Add(new Student("4", "Jack", "China"));
Console.Write("Enter the student number: ");
string sn = Console.ReadLine();
bool found = false;
for (int i = 0; i < list.Count; i++) {
if (list[i].StudentNumber == sn) {
found = true;
break;
}
}
if (found)
Console.WriteLine("The student is in the list");
else
Console.WriteLine("The student is not in the list");
See an example of output below.
Always remember that in programming there are several ways to solve the same problem.
I added elements to the list one by one and fixed them in the code. You can ask the user for the info that you need to create the objects. In this case, student number, name and country. Then use a console menu to ask the user if wants to add more students. You can also create an auxiliary method to populate the list.
After having some data in the list of students, we have to ask the user for a student number. Again, you can test the code by fixing a certain student number.
Then we check every element of the list, comparing the student number of each student with the input we got from the user. To do this, we are going to use the basic algorithm for searching.
If we find the student number, we change the value of the variable found to true. Then we can use that value outside of the for-loop to print that we find it. After that, we don’t need to keep searching because we already found the student, so we exit the loop with the instruction “break”.
Summary
The use of data structures is very important in programming.
When we use ADT implementations, we reuse code that is already tested and bug-free. Therefore, our code becomes more robust.
There are many benefits to using lists implementations instead of arrays. We avoid code repetition and create more robust code to solve problems. Also, our code is shorter, clean, and easy to understand.
H@ppy coding!
Related posts:
- Stack data structure implementation in C# (using linked lists)
- Using the Stack data structure in C# (with examples)
- Using the Graph Data Structure to solve real-world problems in C#
- Using the Queue Data Structure in C# (with examples)
- General Tree Data Structure implementation in C# (with examples)
- General Tree Data Structure Example in C#: Printing levels of the Tic-tac-toe Game Tree