Нахождение наименьшего числа с помощью турнирной сетки

Я пишу программу, которая должна найти наименьшее число в турнирной сетке. Например, есть массив

int[] a = new int[4] {4, 2, 1, 3}

и, сравнивая числа, стоящие рядом друг с другом, я должен выбрать наименьшее. (min(4, 2) -> 2, min(1, 3) -> 1, а затем я сравниваю 1 и 2, 1 наименьший, поэтому он и выигрывает, но сравнивать 2 и 1 невозможно. Просто [0] с 1, a[2] с a[3] и так далее. Обычно a[2*i] с [(2 *i)+1] for(int i=0; i<a.Length/2; i++) ‹- примерно так

Первый вопрос: если есть n чисел, все дерево состоит из 2n-1 скобок. Я должен создать массив из 4 или 7 элементов? 4 кажется лучшим вариантом.

Второй вопрос: если я сравниваю 4 и 2, а 2 меньше, я должен сделать [0] = 2, а затем при сравнении 1 и 3 1 = 1? Наконец, сравнивая [0] с 1 и помещая наименьшее число в [0 ]? Может потребоваться временный int.

Последний вопрос: что вы предлагаете сделать самым простым способом? Я почти не мог найти информацию об этом алгоритме. Я надеюсь, что вы направите мой разум в рабочий алгоритм.

введите здесь описание изображения

Не так много, но я отправляю свой код:

int[] a = new int[4] { 4, 2, 1, 3 };
int tmp = 0;
for (int i = 0; i < (a.Length)/2; i++)
{
    if (a[tmp] > a[tmp + 1])
    {
        a[i] = a[i + 1];
    }
    else if(a[tmp] < a[tmp +1])
    {
        a[i] = a[i + 1];
    }
    tmp = tmp + 2;
}

Можете ли вы указать, что я делаю хорошо, а что следует улучшить?


person mikro098    schedule 17.10.2015    source источник
comment
Можете ли вы сказать нам, что вам нужно сделать с номерами? Вы хотите сгенерировать новый список номеров из предыдущего раунда турнира? Откуда 2n-1 скобок, когда есть n чисел?   -  person Flying_Banana    schedule 18.10.2015
comment
Мне просто нужно найти самую маленькую. Я говорил о 2n-1 пробелах во всем дереве, как вы можете видеть здесь: f.cl.ly/items/463s1h060m3T3b3c2h3l/ Итак, в начале у нас есть 4 числа, но все дерево состоит из 2n-1.   -  person mikro098    schedule 18.10.2015
comment
Вы, кажется, в целом на твердом пути. Попробуйте что-нибудь, посмотрите, как это работает, опубликуйте свой код, и мы поможем вам двигаться вперед.   -  person Daniel Hoffmann-Mitscherling    schedule 18.10.2015
comment
Итак, скобка может рассматриваться как 2 числа, и вам не разрешено сравнивать числа, кроме числа рядом с ним (в своей собственной скобке)? Я немного смущен тем, какие точные ограничения у вас здесь... и если есть n чисел, все дерево состоит из 2n-1 скобок. Я должен создать массив из 4 или 7 элементов? действительно не имеет смысла - куда делся n?   -  person Flying_Banana    schedule 18.10.2015
comment
Таким образом, весь алгоритм может быть основан на массиве из 4 элементов, если есть 4 числа, как в этом примере?   -  person mikro098    schedule 18.10.2015


Ответы (2)


Если необходим турнирный стиль, рекурсивный подход кажется наиболее подходящим:

int Minimum  (int [] values, int start, int end)
{
   if (start == end)
      return values [start];
   if (end - start == 1)
      if ( values [start] < values [end])
         return values [start];
      else
         return values [end];
   else
   {
      int middle = start + (end - start) / 2;
      int min1 = Minimum  (values, start, middle);
      int min2 = Minimum  (values, middle + 1, end);
      if (min1 < min2)
         return min1;
      else
         return min2;
   }
}

РЕДАКТИРОВАТЬ: код не тестировался, и могли возникнуть ошибки, поскольку он был введен в приложении для Android.

РЕДАКТИРОВАТЬ: забыл сказать, как вы вызываете этот метод. Вот так:

int min = Minimum  (myArray, 0, myArray.Length -1);

РЕДАКТИРОВАТЬ: Или создать другую перегрузку:

int Minimum  (int [] values)
{
   return Minimum  (values, 0, values.Length -1);
}

И для вызова используйте только:

int min = Minimum  (myArray);

РЕДАКТИРОВАТЬ: И вот нерекурсивный метод (имейте в виду, что этот метод фактически изменяет массив):

int Minimum(int[] values)
{
    int step = 1;
    do
    {
        for (int i = 0; i < values.Length - step; i += step)        
            if(values[i] > values[i + step])
                values[i] = values[i + step];
        step *= 2;
    }
    while(step < values.Length);

    return values[0];
}
person Mihai Caracostea    schedule 18.10.2015
comment
Я не заметил вашего кода, но я добился очень близкого результата. Итак, теперь values[0] сохраняет наименьшее число, но что, например, с 2? - person mikro098; 18.10.2015

Существуют различные простые решения, в которых используются функции, созданные в C#:

int min = myArray.Min();
//Call your array something other than 'a' that's generally difficult to figure out later

В качестве альтернативы это будет выполнять цикл foreach по всем вашим значениям.

int minint = myArray[0];
foreach (int value in myArray) {
  if (value < minint) minint = value;
}

1 - О каком дереве ты говоришь? Ваш массив имеет n значений для начала, поэтому он будет иметь n значений max. Если вы имеете в виду, что количество значений во всех массивах, которые вы создадите, равно 2n-1, это все равно не означает, что вам нужно поместить все это в 1 массив, создать массив, использовать его, а затем создать другой массив. С# GC будет собирать объекты ссылочного типа, у которых нет указателей (которые не будут использоваться снова), так что будет хорошо с памятью, если это вас беспокоит?

2 - Опубликуйте свой код. Есть несколько ошибок, но, скорее всего, вы справитесь с изменением текущих значений массива или созданием нового массива. Temp int не понадобится.

3. Опубликованные выше алгоритмы являются «самыми простыми» с использованием встроенных функций, доступных для C#. Если это домашнее задание, пожалуйста, напишите код.

В качестве общего направления использование рекурсивной функции, вероятно, было бы наиболее элегантным (и некоторые общие сведения о сортировке слиянием окажутся полезными для вас в будущем).

person Daniel Hoffmann-Mitscherling    schedule 17.10.2015
comment
Я не мог понять, как сравнить a[0] с a[1], a[2] с a[3], а затем победителей, например, a[0] с a[2]. Я также прикрепил изображение того, о чем я говорю. Завтра выложу что есть. - person mikro098; 18.10.2015
comment
Я определенно могу вам помочь, однако я не буду делать вашу домашнюю работу (или что бы то ни было) за вас, так как вы, кажется, на правильном пути. Пожалуйста, не стесняйтесь публиковать свой код всякий раз, когда у вас есть время, я думаю, вы можете понять это с помощью пары небольших указателей (как только у нас будет код для просмотра)! - person Daniel Hoffmann-Mitscherling; 18.10.2015