将查找最小元素的功能添加到“队列”结构中

问题描述

欢迎大家
我了解队列的原理,我自己已经实现了。
我需要用一个函数来补充代码,以在当前存在的元素中找到最小的元素。该代码中的某些要点不是我一个人完成的,原则上,我只是开始进行面向对象的编程。
给我一个关于如何引用元素以及用于查找最小元素的循环的想法。
谢谢

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",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
        }
    }

解决方法

假设我们将这些值放入队列:

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

第3项入队后Minimum的正确值是多少?这得看情况。它可以是3(如果尚未将项目1出队),也可以是4。但无论是哪个值已经出队,它都永远不会是58,因为4 < 54 < 8

因此,在每次入队后,我们可以使用Minimum的潜在答案来构建数据结构:

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]

请确保minimum列表总是已排序。如果遇到的新值大于列表中的最大项目,则将其附加。如果较小,则将所有较大的值替换为新的值。


现在,出队会发生什么?让我们以索引8之后的minimum列表为例(因为它恰好是最长/最有趣的),并查看出队情况:

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

请注意,我们在出列相同值时只是从列表中删除了最小值。


现在,我们需要的是一个数据结构,该数据结构使我们可以检查第一个元素(在O(1)内),删除第一个元素(在O(1)内)并向其中添加新值结束(这也需要从末尾删除摊销的O(n)元素)。

由于这是一次大学练习,因此我将实际的实现留给您,但这有望将您推向正确的方向。