(Bubble Sort) |
(BiDirectional Bubble Sort) |
(Shells Sort) |
(Quick Sort) |
Самый известный и самый медленный вид сортировки. Его популярность это следствие запоминающегося названия и простота. Пузырьковая сортировка основана на методе перестановок. Алгоритм - это постоянное сравнение элемента с соседними элементами и перестановка их при необходимости. Элементы массива при этом уподобляются всплывающим пузырькам в сосуде с водой (что и можно заметить на аплете) Алгоритм состоит из двух циклов. Внешний задает область поиска а внутренний в этой области выполняет перестановки между соседними элементами. После одного прохода внешнего цикла вначале массива оказывается один элемент (самый маленький в нашем случае), после чего эта (верхная) часть массива уже не учавствует в сортировке. Потом внутренний цикл выдает нам еще один элемент из нижней части массива (после первого прохода это весь массив, кроме одного отсортированного элемента в верхней части) и ставит его на второе место, когда верхний цикл идет по третьему кругу внутренний сравнивает и выбирает самый мелкий элемент уже из всех кроме первых двух верхних и т.д. После count-1 проходов (count размер массива) внизу остается только один (самый большой ) элемент и массив отсортирован. Анализируя алгоритмы сортировки надо принимать во внимание количество произведенных сравнений и перестановок. Для пузырьковой сортировки это: 1/2*n*(n-1) - число сравнений. 3/4*n*(n-1) - среднее число перестановок. 3/2*n*(n-1) - максимальное возможное число перестановок. Пузырьковая сортировка является квадратичным алгоритмом по числу сравнений и перестановок относительно числа сортируемых элементов. И, крайне неэффективной. Ниже приведен пример алгоритма на языке С++, если вас смущает шаблонная форма сего то просто пропустите "template < class Stype >" и в функции вместо Stype вставьте свой тип данных, к примеру float.
// BubbleSort template < class Stype > void bubble( Stype *item, int count) { register int i, j; Stype t; for( i=1; i=i ; j--){ if (item[j-1]>item[j]){ t = item[j-1]; item[j-1] = item[j]; item[j] = t; } }//for j }//for i }
Cие произведение искусства принципиально ни чем не отличается от простой Пузырьковой сортировки, только сравнение идет в обе стороны (как и видно на примере) Никакого существенного выигрыша в этом алгоритме нет, но можно поморочить голову тем кто верит наслово. Единственный плюс - это более быстрое понимание того что массив уже отсортирован и ничего больше сравнивать не надо, то есть выход из сортировки в случае если перестановок за проход не произошло. Сам я это "произведение искусства" нашел в примерах поставляемых с JDK, и сюда поместил просто чтобы лишний раз показать что Пузырек плох в любой вариации.
//BiDirBubbleSort template < class Stype > void bubble( Stype *item, int count) { int j, flipped; int limit= count ; int st = -1; Stype temp; while (st < limit){ flipped = 0; st++; limit--; for (j = st; j < limit; j++){ if (item[j] > item[j + 1]) { temp = item[j]; item[j]=item[j+1] item[j+1]=temp; flipped = 1; } } if (!flipped) { return; } for (j = limit; --j >= st;) { if (item[j] > item[j + 1]) { temp = item[j]; item[j]=item[j+1] item[j+1]=temp; flipped = 1; } } if (!flipped) return; } }
template < class Stype > void shell( Stype *item, int count) { register int i, j, gap, k; Stype t; char a[] = {9, 5, 3, 2, 1}; for (k = 0; k < 5; k++){ gap = a[k]; for (i = gap - 1; i < count; i++) t = item[i]; for(j=i-gap;j > =0 && item[j] > x;j-=gap) item[j+gap] = item[j]; item[j+gap] = t; } }
template < class Stype > void quicksort(Stype *item,int count) { int i, j; Stype center; Stype x; i = left; j = right; center = item[ (left+right)/2 ]; while (i < = j ) { while ( (item[i] < center)&&(i < right) ) i++; while ( (item[j] > center)&&(j > left ) ) j--; if ( i<=j ){ x = item[i]; item[i] = item[j]; item[j] = x; i++; j--; } } if (left < j) quicksort(left , j); if (right > i) quicksort(i, right); }