Я пишу сортировку выбора, которая, учитывая массив неупорядоченных элементов, заполняет новый массив индексами отсортированных элементов. Например,

[3, 2, 1]

Вернется

[2, 1, 0] // original indexes of sorted array [1, 2, 3]

К сожалению, он неправильно заполняет массив, повторяя один и тот же индекс над.

Это мой код:

void sort(float data[], int indx[], int len) {
  int   min;
  float temp;
  float tempData[len];

  for (int x = 0; x < len; ++x){
    tempData[x] = data[x];
  }

  for (int i = 0; i < len; ++i) {
    min = i;

    for (int j = i + 1; j < len; ++j) {
      if (tempData[j] < tempData[min]) {
        min = j;
      }
    }

    temp = tempData[i];
    tempData[i] = tempData[min];
    tempData[min] = temp;

    indx[i] = min;
  }
}

И учитывая этот массив:

[8.5, 10.0, 9.25, 12.5, 12.75, 12.5, 16.0, 14.75, 17.0, 18.0, 21.0, 13.0, 7.25];

Он возвращает:

[12, 12, 2, 12, 5, 12, 12, 11, 11, 12, 11, 12, 12]

Кажется, я не могу понять, где возникает логическая ошибка. Может ли кто-нибудь помочь мне его найти?

5
user1883368 23 Фев 2016 в 07:42

5 ответов

Лучший ответ

Первоначально заполните indx числами от 0 до len -1 и используйте индексированный доступ для сканирования и управления массивом. Ваш текущий код может рассинхронизироваться с вводом. И вам не нужен tempData.

Так как то так:

void sort(float data[], int indx[], int len) {
    int   min;
    float temp;

    for(int x = 0; x < len; ++x){
        indx[x] = x;
    }   

    for (int i = 0; i < len; ++i) {
        min = i;

        for (int j = i + 1; j < len; ++j) 
        {
            if (data[indx[j]] < data[indx[min]])
            {
                min = j;
            }
        }

        temp = indx[i];
        indx[i] = indx[min];
        indx[min] = temp;
    }   
}
4
perreal 23 Фев 2016 в 05:58

Вот логическая ошибка. Каждый раз, когда элемент выбирается для обработки, и он требует перемещения из своей позиции, индекс элемента также изменяется, например, после обработки первого элемента (8.5) с индексом 0, он перемещается в индекс самого маленького элемента. при индексе 12 и так далее. решение, предполагающее использование «флагов», кажется подходящим

1
Spyke 23 Фев 2016 в 05:40

В массиве индексов хранится индекс последней позиции в процессе сортировки вместо исходного индекса.

Итак, инициализируйте индексный массив исходным индексом

indx[i] = i;

Также замените индекс в процессе сортировки

indx[i] = indx[min];
indx[min] = i;
1
ydoow 23 Фев 2016 в 05:05

Проблема с вашим алгоритмом. Скажем, минимальное значение находится на последней позиции. Вы сохраняете последнюю позицию на первом месте индекса вашего массива. Затем вы меняете значение там со значением в первой позиции. Итак, теперь ваша последняя позиция может содержать минимум оставшихся значений.

Вместо этого инициализируйте свой массив индексов с помощью {0,1,2,3,4,5,6 ...}, а затем отсортируйте этот массив на основе значений данных в этих индексах.

2
Hal 23 Фев 2016 в 05:01

Проблема в том, что вы не должны менять местами содержимое массива, чтобы получить правильный порядок, просто «отметьте» его (вы можете увидеть ответ Хэла по поводу объяснения ошибки). это должно дать правильный результат:

  for (int i = 0; i < len; ++i) {

    min = i;

    for (int j = 0; j < len; ++j) {
      if (tempData[j] < tempData[min]) {
        min = j;
      }
    }

    tempData[min]=100000000; //INF, equal to  "don't compare this"

    indx[i] = min;
  }
4
malioboro 23 Фев 2016 в 05:10