найти медиану с минимальным временем в массиве

у меня есть массив скажем a = { 1,4,5,6,2,23,4,2}; теперь мне нужно найти медиану позиции массива от 2 до 6 (нечетные полные члены), поэтому то , что я сделал, я взял a[1] to a[5] на arr[0] to arr[4] тогда я отсортировал его и написал arr[2] как медиана .

но здесь каждый раз , когда я ввожу значения из одного массива в другой, так что значения моего исходного массива остаются неизменными . во-вторых, я отсортировал, поэтому эта процедура занимает довольно много **time** . Поэтому я хочу знать, есть любой способ, которым я могу сделать это по-другому less my computation time .

любые веб-сайты , материала, чтобы понять , что и как делать?

5 ответов


если вы выполняете несколько запросов в одном массиве, вы можете использовать дерево сегментов. Они обычно используются для запросов минимального/максимального диапазона и суммы диапазона, но вы можете изменить его на медиану диапазона.

дерево сегментов для набора с n интервалами использует хранилище O(N log n) и может быть построено за время O(n log n). Запрос диапазона может быть выполнен в O (log n).

пример медианы в дереве сегментов диапазона:

вы строите дерево сегментов снизу вверх (обновление сверху вниз):

                    [5]
        [3]                     [7]
 [1,2]        [4]         [6]         [8] 
1     2     3     4     5     6     7     8

индексы покрыты узла:

                    [4]
        [2]                     [6]
 [0,1]        [3]         [5]         [7] 
0     1     2     3     4     5     6     7

запрос медианы для индексов диапазона 4-6 будет идти по этому пути значений:

                    [4]
                          [5]
0     1     2     3     4     5     6     7

выполняя поиск медианы, вы знаете количество общих элементов в запросе (3), а медиана в этом диапазоне будет 2-м элементом (индекс 5). Таким образом, вы по существу выполняете поиск первого узла, который содержит тот индекс, который является узлом со значениями [1,2] (индексы 0,1).

выполнение поиска медианы диапазона 3-6 немного сложнее, потому что вам нужно искать два индекса (4,5), которые находятся в одном узле.

                    [4]
                                [6]
                          [5] 
0     1     2     3     4     5     6     7

дерево отрезков

минимальный запрос диапазона на дереве сегментов


использовать std::nth_element С <algorithm> который O (N):

nth_element(a, a + size / 2, a + size);
median = a[size/2];

можно найти медиану без сортировки в O(n) времени; алгоритмы, которые это делают, называются алгоритмы выбора.


чтобы найти медиану массива менее 9 элементов, я думаю, что наиболее эффективным является использование алгоритма сортировки, как сортировка вставками. Сложность плохая, но для такого небольшого массива из-за k в сложности лучших алгоритмов, таких как quicksort, сортировка вставки очень эффективна. Сделайте свой собственный тест, но я могу сказать, что у вас будут лучшие результаты с сортировкой вставки, чем с сортировкой оболочки или quicksort.


Я думаю, что лучший способ-использовать медиану медианы алгоритма подсчета k-го наибольшего элемента массива. Общую идею алгоритма вы можете найти здесь:медиана медиан в Java, в Википедии: http://en.wikipedia.org/wiki/Selection_algorithm#Linear_general_selection_algorithm_-_Median_of_Medians_algorithm или просто просмотрите интернет. Некоторые общие улучшения могут быть сделаны во время реализации (избегайте сортировки при выборе медианы конкретные массивы). Однако обратите внимание, что для массива менее 50 элементов более эффективно использовать сортировку вставки, чем медиана медианы алгоритма.