Сортировка и классификация
Сортировка таблицы помещает строки в порядок, который имеет смысл для ее средства просмотра. Например, один из зрителей может предпочесть просмотреть таблицу содержимого папки, отсортированную по теме сообщения, чтобы все потоки беседы были объединяемы, в то время как другим зрителям может потребоваться отсортировать сообщения по имени отправителя. Только что созданная таблица не обязательно отсортирована в определенном порядке.
Существует два типа сортировки:
- Стандартная сортировка
- Сортировка по категориям
При стандартной сортировке все строки отображаются в неструктурированном списке с использованием одного или нескольких столбцов в качестве ключа сортировки. При сортировке по категориям строки отображаются иерархически с одним или несколькими столбцами в качестве ключа сортировки. В каждой категории есть специальная строка заголовка, содержащая следующие столбцы.
- Столбец или столбцы, составляющие ключ сортировки
- PR_CONTENT_COUNT (PidTagContentCount)
- PR_CONTENT_UNREAD (PidTagContentUnreadCount)
- PR_INSTANCE_KEY (PidTagInstanceKey)
- PR_DEPTH (PidTagDepth)
- PR_ROW_TYPE (PidTagRowType)
Отступом под строкой заголовка являются все строки из таблицы, содержащие столбцы со значениями, соответствующими ключу сортировки. Эти строки называются конечными строками. Конечные строки содержат все столбцы в наборе столбцов за вычетом ключевых столбцов сортировки.
Таблицы содержимого папок часто поддерживают сортировку по категориям в дополнение к стандартной сортировке. Таблицы содержимого контейнеров адресной книги обычно поддерживают только стандартную сортировку.
Категория может иметь два состояния: свернутое и развернутое. Если категория находится в свернутом состоянии, из IMAPITable::QueryRows возвращается только строка заголовка. Если категория находится в развернутом состоянии, возвращаются все строки, связанные с категорией. Сюда входят строка заголовка и конечные строки.
Каждая категория в представлении таблицы может быть развернута или свернута независимо друг от друга. То есть не все категории должны находиться в одном состоянии одновременно; некоторые категории можно свернуть, а другие — развернуть.
Пользователь классифицированной таблицы решает, как она отображается. Один из распространенных вариантов — использовать элемент управления, предоставляемый в пакете SDK для Windows, который называется элементом управления treeview. Элементы управления treeview — это поля со списком, поддерживающие сведения в структуре, похожей на дерево. Строки заголовков для категорий в развернутом состоянии помечаются знаком «минус», а строки заголовка для категорий в свернутом состоянии помечаются знаком «плюс». Развернутые категории отображаются с отступами конечных строк под строками заголовков.
Чтобы свернуть и развернуть категорию, клиентское приложение или поставщик услуг использует следующие методы IMAPITable : IUnknown :
- IMAPITable::GetCollapseState
- IMAPITable::SetCollapseState
- IMAPITable::ExpandRow
- IMAPITable::CollapseRow
Дополнительные сведения о сортировке потоков беседы см. в следующих разделах:
- SSortOrder
- Каноническое свойство PidTagSubject
- Каноническое свойство PidTagSubjectPrefix
- Каноническое свойство PidTagNormalizedSubject
- Каноническое свойство PidTagConversationTopic
- Каноническое свойство PidTagConversationIndex
- ScCreateConversationIndex
- Сортировка таблиц после установки столбцов и ограничений
Дефолтная сортировка для списка записей в админке Yii2
Ваша функция search , как я предполагаю возвращает ActiveDataProvider . Если да, то вы можете указать дефолтную сортировку так:
$dataProvider = new ActiveDataProvider([ 'query' => $query, 'sort' => [ 'defaultOrder' => [ 'id' => SORT_DESC, ] ], ]);
Отслеживать
ответ дан 12 окт 2020 в 16:03
1,349 1 1 золотой знак 10 10 серебряных знаков 28 28 бронзовых знаков
- yii2
- yii
-
Важное на Мете
Похожие
Подписаться на ленту
Лента вопроса
Для подписки на ленту скопируйте и вставьте эту ссылку в вашу программу для чтения RSS.
Дизайн сайта / логотип © 2024 Stack Exchange Inc; пользовательские материалы лицензированы в соответствии с CC BY-SA . rev 2024.1.8.3130
Нажимая «Принять все файлы cookie» вы соглашаетесь, что Stack Exchange может хранить файлы cookie на вашем устройстве и раскрывать информацию в соответствии с нашей Политикой в отношении файлов cookie.
Виды алгоритмов сортировки в Python

В одной из прошлых статей я рассматривал списки в Python, а также затронул их сортировку. Теперь давайте разберем эту тему более подробно: изучим виды алгоритмов сортировки и сравним их скорость на примере сортировки чисел в порядке возрастания.
Встроенные методы сортировки в Python
Стандартный метод сортировки списка по возрастанию – sort(). Пример использования:
nums = [54, 43, 3, 11, 0] nums.sort() print(nums) # Выведет [0, 3, 11, 43, 54]
Метод sorted() создает новый отсортированный список, не изменяя исходный. Пример использования:
nums = [54, 43, 3, 11, 0] nums2 = sorted(nums) print(nums, nums2) # Выведет [54, 43, 3, 11, 0] [0, 3, 11, 43, 54]
Если нам нужна сортировка от большего числа к меньшему, то установим флаг reverse=True. Примеры:
nums = [54, 43, 3, 11, 0] nums.sort(reverse=True) print(nums) # Выведет [54, 43, 11, 3, 0] nums = [54, 43, 3, 11, 0] nums2 = sorted(nums, reverse=True) print(nums, nums2) # Выведет [54, 43, 3, 11, 0] [54, 43, 11, 3, 0]
Но будет полезно знать и другие виды сортировки, так как не всегда встроенные методы будут подходить под все ваши задачи.
Комьюнити теперь в Телеграм
Подпишитесь и будьте в курсе последних IT-новостей
Пузырьковая сортировка
Алгоритм попарно сравнивает элементы списка, меняя их местами, если это требуется. Он не так эффективен, если нам нужно сделать только один обмен в списке, так как данный алгоритм при достижении конца списка будет повторять процесс заново. Чтобы алгоритм не выполнялся бесконечно, мы вводим переменную, которая поменяет свое значение с True на False, если после запуска алгоритма список не изменился.
Сравниваются первые два элемента. Если первый элемент больше, то они меняются местами. Далее происходит все то же самое, но со следующими элементами до последней пары элементов в списке.
Пример пузырьковой сортировки:
def bubble(list_nums): swap_bool = True while swap_bool: swap_bool = False for i in range(len(list_nums) - 1): if list_nums[i] > list_nums[i + 1]: list_nums[i], list_nums[i + 1] = list_nums[i + 1], list_nums[i] swap_bool = True nums = [54, 43, 3, 11, 0] bubble(nums) print(nums) # Выведет [0, 3, 11, 43, 54]
Сортировка вставками
Алгоритм делит список на две части, вставляя элементы на их правильные места во вторую часть списка, убирая их из первой.
Если второй элемент больше первого, то оставляем его на своем месте. Если он меньше, то вставляем его на второе место, оставив первый элемент на первом месте. Далее перемещаем большие элементы во второй части списка вверх, пока не встретим элемент меньше первого или не дойдем до конца списка.
Пример сортировки вставками:
def insertion(list_nums): for i in range(1, len(list_nums)): item = list_nums[i] i2 = i - 1 while i2 >= 0 and list_nums[i2] > item: list_nums[i2 + 1] = list_nums[i2] i2 -= 1 list_nums[i2 + 1] = item nums = [54, 43, 3, 11, 0] insertion(nums) print(nums) # Выведет [0, 3, 11, 43, 54]
Сортировка выборкой
Как и сортировка вставками, этот алгоритм в Python делит список на две части: основную и отсортированную. Наименьший элемент удаляется из основной части и переходит в отсортированную.
Саму отсортированную часть можно и не создавать, обычно используют крайнюю часть списка. И когда находится наименьший элемент списка, то переносим его на первое место, вставляя первый элемент на прошлое порядковое место наименьшего. Далее делаем все то же самое, но со следующим элементом, пока не достигнем конца списка.
Пример сортировки выборкой:
def selection(sort_nums): for i in range(len(sort_nums)): index = i for j in range(i + 1, len(sort_nums)): if sort_nums[j] < sort_nums[index]: index = j sort_nums[i], sort_nums[index] = sort_nums[index], sort_nums[i] nums = [54, 43, 3, 11, 0] selection(nums) print(nums) # Выведет [0, 3, 11, 43, 54]
Пирамидальная сортировка
Этот алгоритм, как и сортировки вставками или выборкой, делит список на две части. Алгоритм преобразует вторую часть списка в бинарное дерево для эффективного определения самого большого элемента.
Преобразуем список в бинарное дерево, где самый большой элемент является вершиной дерева, и помещаем этот элемент в конец списка. После перестраиваем дерево и помещаем новый наибольший элемент перед последним элементом в списке. Повторяем этот алгоритм, пока все вершины дерева не будут удалены.
Хоть алгоритм и кажется сложным, он значительно быстрее остальных, что особенно заметно при обработке больших списков.
Пример пирамидальной сортировки:
def heapify(sort_nums, heap_size, root): l = root left = (2 * root) + 1 right = (2 * root) + 2 if left < heap_size and sort_nums[left] >sort_nums[l]: l = left if right < heap_size and sort_nums[right] >sort_nums[l]: l = right if l != root: sort_nums[root], sort_nums[l] = sort_nums[l], sort_nums[root] heapify(sort_nums, heap_size, l) def heap(sort_nums): size = len(sort_nums) for i in range(size, -1, -1): heapify(sort_nums, size, i) for i in range(size - 1, 0, -1): sort_nums[i], sort_nums[0] = sort_nums[0], sort_nums[i] heapify(sort_nums, i, 0) nums = [54, 43, 3, 11, 0] heap(nums) print(nums) # Выведет [0, 3, 11, 43, 54]
Сортировка слиянием
Алгоритм разделяет список на две части, каждую из них он разделяет еще на две и так далее, пока не останутся отдельные единичные элементы. Далее соседние элементы сортируются парами. Затем эти пары объединяются и сортируются с другими парами, пока не обработаются все элементы в списке.
Пример сортировки слиянием:
def mergeSort(sort_nums): if len(sort_nums)>1: mid = len(sort_nums)//2 lefthalf = sort_nums[:mid] righthalf = sort_nums[mid:] mergeSort(lefthalf) mergeSort(righthalf) i=0 j=0 k=0 while iБыстрая сортировка в Python
Один из самых популярных алгоритмов при сортировке списков. При правильном использовании он не требует много памяти и выполняется очень быстро.
Алгоритм разделяет список на две равные части, принимая псевдослучайный элемент и используя его в качестве опоры, то есть центра деления. Элементы, меньшие, чем опора, перемещаются влево от опоры, а элементы, размер которых больше опоры – вправо. Этот процесс повторяется для списка слева от опоры, а также для массива элементов справа от опоры, пока весь массив не будет отсортирован. Алгоритм быстрой сортировки будет работать медленно, если опорный элемент равен наименьшему или наибольшему элементу списка.
Пример быстрой сортировки:
def partition(sort_nums, begin, end): part = begin for i in range(begin+1, end+1): if sort_nums[i] = end: return part = partition(sort_nums, begin, end) quick(sort_nums, begin, part-1) quick(sort_nums, part+1, end) return quick(sort_nums, begin, end) nums = [54, 43, 3, 11, 0] quick_sort(nums) print(nums) # Выведет [0, 3, 11, 43, 54]Скорость работы алгоритмов
Сортировка слиянием почти в два раза медленнее, чем быстрая сортировка. Сортировка выборкой выполняет больше сравнений, чем сортировка вставками, но выполняется немного быстрее.
Пузырьковая сортировка не подойдет для практического применения, так как она является самой медленной из всех. Но знать данный алгоритм будет полезно тем, кто хочет полностью изучить тему алгоритмов сортировки списков в Python.
Итог
Мы изучили виды сортировки списков в Python и сравнили их эффективность, а также рассмотрели встроенные методы. Надеюсь, данная статья была полезна для вас!
Сортировки
Сортировкой (англ. sorting) называется процесс упорядочивания множества объектов по какому-либо признаку.
Так как данные могут хранится в разных структурах, то и алгоритмы для каждой структуры могут отличаться. Например, при хранении данных в списке сортировка кучей потребует $O(n^2 \log n)$ времени против $O(n \log n)$ с использованием массива; а вот сортировка пузырьком не изменится.
Также есть алгоритмы параллельной сортировки данных (т.н. Сортирующие сети), время работы которых в лучшем случае $O(\log n)$.
Классификация сортировок
Время работы
Эту классификацию обычно считают самой важной. Оценивают худшее время алгоритма, среднее и лучшее. Лучшее время — минимальное время работы алгоритма на каком-либо наборе, обычно этим набором является тривиальный $\big[ 1 \ldots n \big] $. Худшее время — наибольшее время. У большинства алгоритмов временные оценки бывают $O(n \log n)$ и $O(n^2)$.
Память
Параметр сортировки, показывающий, сколько дополнительной памяти требуется алгоритму. Сюда входят и дополнительный массив, и переменные, и затраты на стек вызовов. Обычно затраты бывают $O(1)$, $O(\log n)$, $O(n)$.
Устойчивость
Устойчивой сортировкой называется сортировка, не меняющая порядка объектов с одинаковыми ключами. Ключ — поле элемента, по которому мы производим сортировку.
Количество обменов
Количество обменов может быть важным параметром в случае, если объекты имеют большой размер. В таком случае при большом количестве обменов время алгоритма заметно увеличивается.
Детерминированность
Алгоритм сортировки называется детерминированным, если каждая операция присваивания, обмена и т.д. не зависит от предыдущих. Все сортирующие сети являются детерминированными.
Сравнение сортировок
Рассмотрим массив $\big[ 1 \ldots n \big]$. Для элементов должно выполняться отношение порядка.
| Название | Лучшее время | Среднее | Худшее | Память | Устойчивость | Обмены (в среднем) | Описание |
|---|---|---|---|---|---|---|---|
| Сортировка пузырьком (Bubble Sort) |
$O(n)$ | $O(n^2)$ | $O(n^2)$ | $O(1)$ | Да | $O(n^2)$ | Алгоритм состоит в повторяющихся проходах по сортируемому массиву. На каждой итерации последовательно сравниваются соседние элементы, и, если порядок в паре неверный, то элементы меняют местами. |
| Сортировка вставками (Insertion Sort) |
$O(n)$ | $O(n^2)$ | $O(n^2)$ | $O(1)$ | Да | $O(n^2)$ | На каждом шаге алгоритма мы выбираем один из элементов входных данных и вставляем его на нужную позицию в уже отсортированной части массива до тех пор, пока весь набор входных данных не будет отсортирован. |
| Сортировка Шелла (Shellsort) |
$O(n\log^2)$ | Зависит от выбора шага | $O(n^2)$ | $O(1)$ | Нет | $O(n^2)$ | Является модификацией сортировки вставками, сортируем между собой элементы, стоящие на кратных нашему шагу местах. |
| Сортировка выбором (Selection Sort) |
$O(n^2)$ | $O(n^2)$ | $O(n^2)$ | $O(1)$ | Нет | $O(n)$ | На $i$-ом шаге алгоритма находим минимальный среди последних $n - i + 1$, и меняем его местами с $i$-ым элементом в массиве. |
| Быстрая сортировка (Quick Sort) |
$O(n \log n)$ | $O(n \log n)$ | $O(n^2)$ (маловероятно) |
$O(\log n)$ (стек вызовов) |
Нет | $O(n \log n)$ | Один из самых известных и широко используемых алгоритмов сортировки. Алгоритм состоит в выборе опорного элемента, разделении массива на 2 части относительно опорного (одна — все элементы, меньшие опорного элемента, вторая — большие), и в сортировке полученных частей рекурсивным вызовом себя от них. |
| Сортировка слиянием (Merge Sort) |
$O(n \log n)$ | $O(n \log n)$ | $O(n \log n)$ | $O(n)$ (обычная реализация) $O(1)$ (модифицированная реализация) |
Да | $O(n \log n)$ | Алгоритм состоит в разделении массива пополам, сортировке половин и их слиянии. |
| Timsort | $O(n)$ | $O(n\log)$ | $O(n\log)$ | $O(n)$ | Да | $O(n\log)$ | Гибрид сортировки слиянием. Разбиваем массив на подмассивы фиксированной длины и сортируем каждый подмассив любой устойчивой сортировкой. После чего объединяем отсортированные подмассивы модифицированной сортировкой слиянием. |
| Сортировка кучей (Heap Sort) |
$O(n \log n)$ | $O(n \log n)$ | $O(n \log n)$ | $O(1)$ | Нет | $O(n \log n)$ | Строим из массива кучу, по очереди извлекаем минимум кучи. |
| Плавная сортировка (Smoothsort) |
$O(n)$ | $O(n\log)$ | $O(n\log)$ | $O(1)$ | Нет | $O(n\log)$ | Модификация сортировки кучей. Вместо двоичной кучи используем K-ую кучу Леонардо. |
| Терпеливая сортировка (Patience sorting) |
$O(n\log)$ | $O(n\log)$ | $O(n\log)$ | $O(n)$ | Нет | $O(n\log)$ | Раскидываем элементы массива по стопкам, после чего строим двоичную кучу из стопок. Позволяет также вычислить длину наибольшей возрастающей подпоследовательности данного массива. |
| Сортировка с помощью бинарного дерева (Tree Sort) |
$O(n)$ | $O(n \log n)$ | $O(n \log n)$ | $O(n)$ | Да | $O(n)$ | Добавляем по очереди вершины в сбалансированное дерево поиска, проходим по всем вершинам в порядке возрастания. |
| Карманная сортировка (Bucket Sort) |
$O(n + k)$ | $O(n \log_k n)$ | $O(n \cdot k)$ | $O(n)$ | Да | - | Распределяем элементы в $k$ карманов, сортируем элементы внутри карманов, из каждого кармана данные записываются в массив в порядке разбиения. |
| Цифровая сортировка (Radix Sort) |
$O(n \lg n)$ | $O(n \lg n)$ | $O(n \lg n)$ | $O(n)$ | Да | - | Сортировка объектов равной длины, имеющих "разряды". обычно это строки или целые числа. Алгоритм состоит в том, чтобы отсортировать объекты по разрядам, начиная от младших к старшим. |
| Сортировка подсчетом (Counting Sort) |
$O(n)$ | $O(n + k)$ | $O(k)$ | $O(k)$ | Да | $O(n + k)$ | Сортировка целых чисел, входящих в какой-то небольшой диапазон. Создаем массив длины диапазона $k$, каждый элемент которого будет показывать, сколько исходных элементов равны данному. Бежим по массиву и считаем количество вхождений каждого числа. |
| Сортировка Хэна (Han's Sort) |
$O(n \log \log n)$ | $O(n \log \log n)$ | $O(n \log \log n)$ | $O(n)$ | Да | $O(n \log \log n)$ | Очень сложная сортировка, основанная на принадлежности ключей к целым числам. Использует экспоненциальное поисковое дерево Андерсона. |
| Многопоточная сортировка слиянием (Multithreaded merge sort) |
$O(\frac>\log \frac>)$ | $O(\frac>\log \frac>)$ | $O(\frac>\log \frac>)$ | $O(n)$ | Да | $O(n \log n)$ | Отличается от сортировки слиянием только тем, что при рекурсивном вызове будет создавать новый поток. |
| PSRS-сортировка (PSRS-sorting) |
$O(\frac>\log \frac>)$ | $O(\frac>\log \frac>)$ | $O(\frac>\log \frac>)$ | $O(N_^2)$ | Нет | $O(n \log n)$ | Разделим массив на $N_$ подмассива и запустим в каждой быструю сортировку. После этого объединим все эти подмассивы. |
См. также
- Поисковые структуры данных
- Приоритетные очереди
- Поиск подстроки в строке
Источники информации
- Википедия — Алгоритмы сортировки
- Wikipedia —Sorting algorithm
- Хабрахабр — Бенчмарк алгоритмов сортировки
- Томас Х. Кормен, Чарльз И. Лейзерсон, Рональд Л. Ривест, Клиффорд Штайн Алгоритмы: построение и анализ — 3-е изд. — М.: «Вильямс», 2013. — с. 174. — ISBN 978-5-8459-1794-2