简体   繁体   中英

Add the function of finding the minimum element to the "Queue" structure

Welcome all .
I understand the principle of the queue, having implemented it myself.
I need to supplement the code with a function to find the minimum element among the currently existing ones. Some points in this code were not done by myself, and in principle, I just started working with object-oriented programming.
Give me an idea of how to refer to elements and which loop to use to find the minimum element.
Thanks .

class Program
    {
        public static void Main()
        {
            var watch = new Stopwatch();
            watch.Start(); // начало замера времени
            long before = GC.GetTotalMemory(false);
            int min = int.MaxValue;
            Queue queue = new Queue(); // Структура очередь
            File.WriteAllText(@"output.txt", string.Empty);
            using (StreamReader sr = new StreamReader(@"input.txt", System.Text.Encoding.Default)) // Считывание файла input.txt
            {
                string line;
                while ((line = sr.ReadLine()) != null) // пока строки в файле не null
                {
                    if (line[0] == '+') // если "+", добавить элемент со значением, стоящим после "+"
                    {
                        var pattern = new Regex(@"\d+");
                        var numberStr = pattern.Match(line).Groups[0].Value;
                        queue.Enqueue(int.Parse(numberStr));
                    }
                    if (line[0] == '-') // если "-", выпустить элемент из очереди (first in - first out)
                    {
                        using (StreamWriter sw = new StreamWriter(@"output.txt", true, System.Text.Encoding.Default))
                        {
                            sw.WriteLine(queue.Dequeue());
                        }
                    }
                    if (line[0] == '?') // если "?", вывести наименьший элемент в очереди
                    {
                        using (StreamWriter sw = new StreamWriter(@"output.txt", true, System.Text.Encoding.Default))
                        {
                            sw.WriteLine(queue.Minimum());
                        }
                    }
                }
            }
            long after = GC.GetTotalMemory(false);
            long consumedInMegabytes = (after - before) / (1024); // замер памяти в КБ
            Console.WriteLine($"Затраты памяти (КБ): {consumedInMegabytes}");
            watch.Stop(); // конец замера времени
            Console.WriteLine($"Время выполнения (миллисекунд): {watch.ElapsedMilliseconds}");


        }
    }

    public class QueueItem
    {
        public int Value { get; set; }
        public QueueItem Next { get; set; }
    }

    public class Queue
    {
        QueueItem head;
        QueueItem tail;

        public void Enqueue(int value) // функция добавления элемента в очередь
        {
            if (head == null)
                tail = head = new QueueItem { Value = value, Next = null };
            else
            {
                var item = new QueueItem { Value = value, Next = null };
                tail.Next = item;
                tail = item;
            }
        }

        public int Dequeue() // функция удаления элемента из очереди
        {
            if (head == null) throw new InvalidOperationException();
            var result = head.Value;
            head = head.Next;
            if (head == null)
                tail = null;
            return result;
        }
        public int Minimum()
        {
            // WHAT I NEED DO
        }
    }

Let's say we enqueue these value:

index: 0 1 2 3 4 5 6 7 8 9
value: 5 3 8 4 2 1 6 3 7 2

What is the correct value of Minimum after item 3 is enqueued? Well, it depends. It can be 3 (if item 1 hasn't been dequeued yet) or it can be 4 . But it can never be 5 or 8 , because 4 < 5 and 4 < 8 , no matter which values have been dequeued.

So we can build a data structure with the potential answers of Minimum , after each enqueue:

index:     0   1      2      3   4   5      6      7         8      9
value:     5   3      8      4   2   1      6      3         7      2
minimum:  [5] [3] [3, 8] [3, 4] [2] [1] [1, 6] [1, 3] [1, 3, 7] [1, 2]

See that the minimum list is always sorted. If we encounter a new value that is larger than the largest item in the list, we append it. If it is smaller, we replace all larger values by the new one.


Now, what happens on dequeue? Let's take the minimum list after index 8 (because it happened to be the longest / most interesting) and see what happens on dequeue:

index:          0         1         2         3         4      5      6   7   8
dequeue:        5         3         8         4         2      1      6   3   7
minimum: [1, 3, 7] [1, 3, 7] [1, 3, 7] [1, 3, 7] [1, 3, 7] [3, 7] [3, 7] [7] []

See that we just remove the minimum value from the list when we dequeue that same value.


Now all we need is a data structure that allows us to inspect the first element (in O(1) time), remove the first element (in O(1) time), and add a new value to the end (which requires removing amortized O(n) elements from the end as well).

Since this is a university exercise, I'll leave the actual implementation to you, but this should hopefully push you in the right direction.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM