0% found this document useful (0 votes)
62 views4 pages

Linear Data Structures Stacks and Queues Exercises

Download as docx, pdf, or txt
Download as docx, pdf, or txt
Download as docx, pdf, or txt
You are on page 1/ 4

Exercises: Linear Data Structures – Stacks and Queues

This document defines the exercise assignments for the "Data Structures" course @ Software University. You can
submit your code in the SoftUni Judge System - https://judge.softuni.bg/Contests/567/Linear-Data-Structures-
Stacks-and-Queues-CSharp-Exercise.

Problem 1. Reverse Numbers with a Stack


Write a program that reads N integers from the console and reverses them using a stack. Use the Stack<int>
class from .NET Framework. Just put the input numbers in the stack and pop them. Examples:

Input Output
1 2 3 4 5 5 4 3 2 1
1 1
(empty) (empty)
1 -2 -2 1

Problem 2. Calculate Sequence with a Queue


We are given the following sequence of numbers:

 S1 = N
 S2 = S1 + 1
 S3 = 2*S1 + 1
 S4 = S1 + 2
 S5 = S2 + 1
 S6 = 2*S2 + 1
 S7 = S2 + 2
 …

Using the Queue<T> class, write a program to print its first 50 members for given N. Examples:

Input Output
2 2, 3, 5, 4, 4, 7, 5, 6, 11, 7, 5, 9, 6, …
-1 -1, 0, -1, 1, 1, 1, 2, …
1000 1000, 1001, 2001, 1002, 1002, 2003, 1003, …

Problem 3. Implement an Array-Based Stack


Implement the "stack" data structure Stack<T> that holds its elements in an array:

public class ArrayStack<T>


{
private T[] elements;
public int Count { get; private set; }
private const int InitialCapacity = 16;
public ArrayStack(int capacity = InitialCapacity) { … }

© Software University Foundation (softuni.org). This work is licensed under the CC-BY-NC-SA license.
Follow us: Page 1 of 4
public void Push(T element) { … }
public T Pop() { … }
public T[] ToArray() { … }
private void Grow() { … }
}

Follow the concepts from the CircularQueue<T> class from the exercises in class. The stack is simpler than the
circular queue, so you will need to follow the same logic, but more simplified. Some hints:
 The stack capacity is this.elements.Length
 Keep the stack size (number of elements) in this.Count
 Push(element) just saves the element in elements[this.Count] and increases this.Count
 Push(element) should invoke Grow() in case of this.Count == this.elements.Length
 Pop() decreases this.Count and returns this.elements[this.Count]
 Grow() allocates a new array newElements of size 2 * this.elements.Length and copies the first
this.Count elements from this.elements to newElements. Finally, assign this.elements =
newElements
 ToArray() just creates and returns a sub-array of this.elements[0…this.Count-1]
 Pop() should throw InvalidOperationException (or IllegalArgumentException) if the stack is
empty

Problem 4. Linked Stack


Implement a stack by a "linked list" as underlying data structure:

Use the following code as start:

public class LinkedStack<T>


{
private Node<T> firstNode;
public int Count { get; private set; }
public void Push(T element) { … }
public T Pop() { … }
public T[] ToArray() { … }
private class Node<T>

{
private T value;
public Node<T> NextNode { get; set; }
public Node(T value, Node<T> nextNode = null) { … }
}
}

The Push(element) operation should create a new Node<T> and put it as firstNode, followed by the old value
of the firstNode, e.g. this.firstNode = new Node<T>(element, this.firstNode).

The Pop() operation should return the firstNode and replace it with firstNode.NextNode. If the stack is
empty, it should throw InvalidOperationException.

© Software University Foundation (softuni.org). This work is licensed under the CC-BY-NC-SA license.
Follow us: Page 2 of 4
Problem 5. Linked Queue
Implement a queue by a "doubly-linked list" as underlying data structure:

Use the following code as start:

public class LinkedQueue<T>


{
public int Count { get; private set; }
public void Enqueue(T element) { … }
public T Dequeue() { … }
public T[] ToArray() { … }

private class QueueNode<T>


{
public T Value { get; private set; }
public QueueNode<T> NextNode { get; set; }
public QueueNode<T> PrevNode { get; set; }
}
}

You may modify and adjust the code from the DoublyLinkedList<T> class from the last lesson. If the queue is
empty, the Dequeue() should throw InvalidOperationException.

Problem 6. * Sequence N  M
We are given numbers n and m, and the following operations:

a) n  n + 1
b) n  n + 2
c) n  n * 2

Write a program that finds the shortest sequence of operations from the list above that starts from n and finishes
in m. If several shortest sequences exist, find the first one of them. Examples:

Input Output
3 10 3 -> 5 -> 10
5 -5 (no solution)
10 30 10 -> 11 -> 13 -> 15 -> 30

Hint: use a queue and the following algorithm:

© Software University Foundation (softuni.org). This work is licensed under the CC-BY-NC-SA license.
Follow us: Page 3 of 4
1. create a queue of numbers
2. queue  n
3. while (queue not empty)
1. queue  e
2. if (e < m)
i. queue  e + 1
ii. queue  e + 2
iii. queue  e * 2
3. if (e == m) Print-Solution; exit

The above algorithm either will find a solution, or will find that it does not exist. It cannot print the numbers
comprising the sequence n  m.

To print the sequence of steps to reach m, starting from n, you will need to keep the previous item as well. Instead
using a queue of numbers, use a queue of items. Each item will keep a number and a pointer to the previous item.
The algorithms changes like this:

Algorithm Find-Sequence (n, m):

1. create a queue of items { value, previous item }


2. queue  { n, null }
3. while (queue not empty)
1. queue  item
2. if (item.value < m)
i. queue  { item.value + 1, item }
ii. queue  { item.value + 2, item }
iii. queue  { item.value * 2, item }
3. if (item.value == m) Print-Solution; exit

Algorithm Print-Solution (item):

1. while (item not null)


1. print item.value
2. item = item.previous

© Software University Foundation (softuni.org). This work is licensed under the CC-BY-NC-SA license.
Follow us: Page 4 of 4

You might also like