More Collections - Stacks and Queues

Although the majority of collections you work with as a beginner developer will be arrays, lists, and dictionaries, it is right for you to understand two specialty collections. Stacks and Queues have specific rules regarding add and remove records from the collection. This post will clarify some of those rules and provide examples of the collections.


Stacks

A STACK is a unique type of collection that does not allow you to use or view any of the elements it contains, other than the elements that were last placed in the collection. This process is often referred to as Last In First Out (LIFO). Once elements are placed into the stack, you can only access an element that was most recently placed into the collection.


It may help to think of a physical stack of plates.

When you dry your dishes and put them away, you are placing the plates on top of each other. Doing this creates a stack. When setting the table, you first need to use the last plate that was stacked. This example demonstrates LIFO in the real world. You can’t get to the bottom plate without removing the other plates from the stack. Attempting to pull out the middle plate would more than likely result in some broken dishes.


For our Stack examples, we are going to pretend we have an event coming up for which we need a guestlist. We aren’t sure how many people the venue will allow, so we are going to populate our stack with the most important people first. This way, if we have to trim down our guest list, we can just remove the guests that were invited last.


Declaration and Initialization

You declare and initialize a stack in the same way you would a List object.

 Stack<string> guestList = new Stack<string>();

Stack Methods

The Stack object has it’s own methods to add and remove elements to the collection.


Push

To add elements into a stack, you “push” them into the collection.

 guestList.Push("Bear");
 guestList.Push("Pippa");
 guestList.Push("Tron");
 guestList.Push("Benson");
 guestList.Push("Ichabob");
 guestList.Push("John");
 guestList.Push("Scott");

When this code executes “Bear” will be at the bottom of the stack and “Scott” will be on top.


Contains

There is no way to access the elements in the middle of the stack, but you can check to see if a value exists by using Contains.

 if (guestList.Contains("mom") == false)
 {
 guestList.Push("mom");
 }

Count

As with the List object, the Count property will tell you how many elements are in the collection.

 Console.WriteLine($"You have invited {guestList.Count} guests.");

Pop

To utilize an element of the stack, you have to “pop” the last entered value out of the stack. When you pop an element from the stack, it is no longer part of that collection.

 Console.WriteLine($"You have invited {guestList.Count} guests.");
 Console.WriteLine($"Your last invited guest is {guestList.Pop()}.");
 Console.WriteLine($"You have invited {guestList.Count} guests.");

When the second WriteLine is executed, “mom” is removed from the collection. The count property will decrease by one.


If you want that value back in the collection, you will have to “push” it back in.


Peek

To remedy the earlier situation where all we wanted to do is see the last element added but not remove it from the list, the Peek method can be used. Peek allows you to see the top element without actually removing it.

 Console.WriteLine($"You have invited {guestList.Count} guests.");
 Console.WriteLine($"Your last invited guest is {guestList.Peek()}.");
 Console.WriteLine($"You have invited {guestList.Count} guests.");

This code will display the same information but will not change the number of guests on the list. The Peek method is convenient to see the top element, but there is no way to access any of the lower elements without popping it from the collection.


Clear

The Clear method will remove all of the elements from the collection.

 guestList.Clear();

Looping Through a Stack


Foreach Loop

If you want to see what is in the stack but not do anything with the elements, you can use the foreach loop. Since a foreach restricts changing the collection while looping through it, it allows you to read each element.


In a way, it’s letting you “peek” into the entire collection.

 foreach (var item in guestList)
 {
 Console.WriteLine(item);
 }

For Loop

Since a for loop access each element individually, you can not use it read through the elements of the collection. The following code will not run. You will get a compile error stating, “Cannot apply indexing with [] to an expression of type ‘Stack<string>’”.

 for (int i = 0; i < guestList.Count; i++)
 {
 Console.WriteLine(guestList[i]);
 }

While Loop

The while is useful for looping through the collection to remove items. For example, let’s say the venue has contacted us. They have informed us that the venue will only accommodate four guests. We need to remove guests from our list until we get to the four most important.

 while (guestList.Count > venueLimit)
 {
 Console.WriteLine($"{guestList.Pop()} is being removed from the list.");
 }

The Pop method allows us to read and remove the element from the collection in a single action.

Queues

Queues are very similar to stacks. However, instead of a “last in first out” method of processing the collection, a queue uses “first in first out” (FIFO). For this collection, you can only access the first element in the collection.


For a real-world example of a queue, think of the line you stand in to get into a popular event.

What happens if the guy at the end of the line tries to go through the gate first. Chaos ensues!


To prevent this kind of chaos from effecting your application, use the queue collection to ensure that the first element is used before the last one.


For our queue example, we are going to pretend the venue for our event has contacted us and removed the limit of people we can invite. We have settled on inviting our original eight guests. However, there is a limit to the number of dinner options at our event. There are three steak dinners, three chicken dinners, and three vegetarian dinners available. We want to provide our guests with the option to choose the dinner they want, but we want to make sure our favorite guests get to chose first.


Declaration and Initialization

You declare and initialize a queue in the same way you would a List object.

 Queue<string> guests = new Queue<string>();

Queue Methods

The Queue object has it’s own methods to add and remove elements to the collection.


Enqueue

To add elements into a queue, you use the Enqueue method.

 guests.Enqueue("Bear");
 guests.Enqueue("Pippa");
 guests.Enqueue("Tron");
 guests.Enqueue("Benson");
 guests.Enqueue("Ichabob");
 guests.Enqueue("John");
  guests.Enqueue("Scott");

When this code executes “Bear” will be first in line and “Scott” will last.


Contains

There is no way to access the elements in the middle of the queue, but you can check to see if a value exists by using Contains.

 if (guests.Contains("mom") == false)
 {
 guests.Enqueue("mom");
 }

Count

As with the List object, the Count property will tell you how many elements are in the collection.

 Console.WriteLine($"You have invited {guests.Count} guests.");

Dequeue

To utilize an element of the queue, you have to “dequeue” the first entered value out of the queue. When you dequeue an element, it is no longer part of that collection.

 Console.WriteLine($"You have invited {guests.Count} guests.");
 Console.WriteLine($"Your first invited guest is {guests.Dequeue()}.");
 Console.WriteLine($"You have invited {guests.Count} guests.");

When the second WriteLine is executed, “Bear” is removed from the collection. The count property will decrease by one.


If you want that value back in the collection, you will have to “queue” it back in.


Peek

To remedy the earlier situation where all we wanted to do is see the first element added but not remove it from the list, the Peek method can be used. Peek allows you to see the first element without actually removing it.

 Console.WriteLine($"You have invited {guests.Count} guests.");
 Console.WriteLine($"Your first invited guest is {guests.Peek()}.");
 Console.WriteLine($"You have invited {guests.Count} guests.");

This code will display the same information but will not change the number of guests on the list. The Peek method is convenient to see the first element, but there is no way to access any of the following elements without removing it from the collection.


Clear

The Clear method will remove all of the elements from the collection.

guests.Clear();

Looping Through a Queue


Foreach Loop

If you want to see what is in the queue but not do anything with the elements, you can use the foreach loop. Since a foreach restricts changing the collection while looping through it, it allows you to read each element. In a way, it’s letting you “peek” into the entire collection.

 foreach (var item in guests)
 {
 Console.WriteLine(item);
 }

For Loop

Since a for loop access each element individually, you can not use it read through the elements of the collection. The following code will not run. You will get a compile error stating, “Cannot apply indexing with [] to an expression of type ‘Queue<string>’”.

  for (int i = 0; i < guests.Count; i++)
 {
 Console.WriteLine(guests[i]);
 }

While Loop

The while is useful for looping through the collection to remove items. For example, let’s say we want to loop through our guests from our favorite guest to least favorite, asking each one, what they want for dinner

 while (guests.Count>0)
 {
 Console.WriteLine($"{guests.Dequeue()}, what would you like for dinner?");
 }

The Dequeue method allows us to read and remove the element from the collection in a single action.


Author’s Note: If it seems like I copy the text from the Stack section into the Queue session, it’s because I did. Like I stated earlier, the two collections are very familiar. The main difference is how the elements are removed from the collection.

25 views0 comments

Recent Posts

See All