Все лекции программирование
.pdfВычислительная сложность
В отличие от пузырьковой сортировки и сортировки посредством выбора, количество сравнений в сортировке вставками зависит от изначальной упорядоченности списка. Если список уже отсортирован, количество сравнений равно n - 1; в противном случае его производительность является величиной порядка n2.
Сравнение простых методов
Пузырьковая |
Сортировка |
Сортировка |
сортировка |
посредством |
вставками |
|
выбора |
|
|
|
|
Input string: dcab |
Input string: dcab |
Input string: dcab |
ex->adcb |
ex->acdb |
ex->cdab |
ex->abdc |
ex->abdc |
ex->acdb |
ex->abcd |
ex->abcd |
ex->abcd |
Sorted string: abcd. |
Sorted string: abcd. |
Sorted string: abcd. |
|
|
|
Быстрая сортировка
Быстрая сортировка, придуманная Ч. А. Р. Хоаром (Charles Antony Richard Hoare) и названная его именем, обычно считается лучшим из существующих в настоящее время алгоритмом сортировки общего назначения. В ее основе лежит сортировка обменами.
Быстрая сортировка построена на идее деления. Общая процедура заключается в том, чтобы выбрать некоторое значение, называемое компарандом (comparand), а затем разбить массив на две части. Все элементы, большие или равные компаранду, перемещаются на одну сторону, а меньшие – на другую. Потом этот процесс повторяется для каждой части до
тех пор, пока массив не будет отсортирован.
Для оптимальной сортировки необходимо выбирать значение компаранда, которое расположено точно в середине диапазона всех значений. Однако для большинства наборов данных это сделать непросто. В худшем случае выбранное значение оказывается одним из крайних. Тем не менее, даже в
этом случае быстрая сортировка работает правильно.
Пример
void quick(char *items, int count)
{
qs(items, 0, count-1);
}
void qs(char *items, int left, int right)
{
register int i, j; char x, y;
i = left; j = right;
x = items[(left+right)/2]; printf("ex->%s\n",items);
printf("comparand->%c, left = %d, right=%d\n",x,left,right); do {
while((items[i] < x) && (i < right)) i++; while((x < items[j]) && (j > left)) j--; if(i <= j) {
y = items[i]; items[i] = items[j]; items[j] = y;
i++; j--;
}
} while(i <= j);
if(left < j) qs(items, left, j); if(i < right) qs(items, i, right);
}
Input string: defacb ex->defacb
comparand->f, left = 0, right=5 ex->debacf
comparand->b, left = 0, right=4 ex->abedcf
comparand->a, left = 0, right=1 ex->abedcf
comparand->d, left = 2, right=4 Sorted string: abcdef.
Пример
void quick_string(char items[][10], int count)
{
qs_string(items, 0, count-1);
}
void qs_string(char items[][10], int left, int right)
{
register int i, j; char *x;
char temp[10];
i = left; j = right;
x = items[(left+right)/2];
do {
while((strcmp(items[i],x) < 0) && (i < right)) i++; while((strcmp(items[j],x) > 0) && (j > left)) j--; if(i <= j) {
strcpy(temp, items[i]); strcpy(items[i], items[j]); strcpy(items[j], temp); i++; j--;
}
} while(i <= j);
if(left < j) qs_string(items, left, j); if(i < right) qs_string(items, i, right);
}
void quick_struct(struct address items[], int count)
{
qs_struct(items,0,count-1);
}
void qs_struct(struct address items[], int left, int right)
{
register int i, j; char *x;
struct address temp;
i = left; j = right;
x = items[(left+right)/2].zip;
do {
while((strcmp(items[i].zip,x) < 0) && (i < right)) i++; while((strcmp(items[j].zip,x) > 0) && (j > left)) j--; if(i <= j) {
temp = items[i]; items[i] = items[j]; items[j] = temp; i++; j--;
}
} while(i <= j);
if(left < j) qs_struct(items, left, j); if(i < right) qs_struct(items, i, right);
}
Поиск
Базы данных существуют для того, чтобы время от времени пользователи
могли найти нужную запись, введя ее ключ. Существует один метод поиска информации в неупорядоченном массиве, и другой для поиска в упорядоченном массиве.
Последовательный поиск
int sequential_search(char *items, int count, char key)
{
register int t;
for(t=0; t < count; ++t) if(key == items[t]) return t;
return -1;
}
Двоичный поиск
Если данные, в которых производится поиск, отсортированы, для нахождения элемента можно применять метод, намного превосходящий предыдущий – двоичный поиск. В нем применяется метод половинного деления. Сначала проверим средний элемент. Если он больше, чем искомый ключ, проверим средний элемент первой половины, в противном случае – средний элемент второй половины. Будем повторять эту процедуру до тех пор, пока искомый элемент не будет найден либо пока не останется очередного элемента.
int binary_search(char *items, int count, char key)
{
int low, high, mid;
low = 0; high = count-1; while(low <= high) {
mid = (low+high)/2;
if(key < items[mid]) high = mid-1; else if(key > items[mid]) low = mid+1; else return mid; return -1;
}