7. Бързо сортиране. Последователно и двоично търсене. Хеширане
Бързо сортиране.
А. Разделяне на дялове:
1. Избираме случаен елемент x от масива a
2. Преглеждаме масива отляво (от началото), докато достигнем
до елемент >x
3. Преглеждаме масива отдясно (от края), докато достигнем до
елемент <x
4. Разменяме местата на двата елемента
vector<int> a(n);
void partition(int x)
{
int i=1, j=n;
do
{
while (a[i] < x) i++;
while (a[j] > x) j--;
if (i<=j)
{ swap(a[i], a[j]); i++;
j--; }
}
while (i<=j);
}
Б. Сортиране - след като масивът се раздели, двата му дяла се
подлагат
на същата
обработка и това продължава, докато се получат дялове само с по един
елемент.
//
qsort.cpp
void quicksort(int left, int right)
{
int i=left, j=right;
int x=a[(i + j)/2];
do
{
while (a[i] < x) i++;
while (a[j] > x) j--;
if (i<=j)
{ swap(a[i], a[j]); i++; j--; }
}
while (i<=j);
if (left<j) quicksort(left, j);
if (i<right) quicksort(i, right);
}
qsort от STL ??????????
Сортиране чрез сливане
mergesort.cpp
Последователно
търсене [4, стр. 231]
** Човешката дейност търсене
** Опростен модел на търсене
** Фундаментални операции над елемнтите на множество (правилна оценка
на ефективността на алгоритмите за търсене)
-- инициализиране
-- търсене
-- вмъкване
-- изтриване
-- обединяване на множества
-- сортиране.
** Ключ, повтарящи се ключове
-- има ли елемент с даден ключ? [bool
exists(unsigned key)]
-- индекс на елемент (обект) с даден ключ? [unsigned find_one(unsigned key)]
-- брой елементи с даден ключ? [unsigned count(unsigned key)]
-- индекси на всички елементи (обекти) с даден ключ? [vector<unsigned>
find_all(unsigned key)]
** Последователно (линейно) търсене
Проверяваме последователно
елементите на множеството (което е линейно наредено), докато или
намерим търсения елемент или стигнем
до края на редицата.
Ефективност на алгоритъма за линейно
търсене:
Броят на обръщенията към елементите на масива зависи
от търсеното число, но в най-лошия случай, когато числото не се среща в
масива, е равен на дължината на масива. Следователно сложността на
алгоритъма
е O(n).
// lsearch.cpp
int linear_search(vector<int> v,
int
a)
{
int i;
for (i = 0; i < v.size();
i++)
if
(v[i] == a) return i;
return -1;
}
** Последователно търсене в сортиран списък с поддържане на
сортирания
списък при вмъкване на нов елемент.
** Последователно търсене с преподреждане
Двоично търсене (разделай и владей) [4.3, стр. 239]
// bsearch.cpp
int binary_search(vector<int> v,
int
from, int to, int a)
{
if (from > to)
return
-1;
int mid = (from + to) / 2;
int diff = v[mid] - a;
if (diff == 0) return
mid;
/* v[mid] == a */
else if (diff <
0)
/* v[mid] < a */
return
binary_search(v, mid + 1, to, a);
else
return
binary_search(v, from, mid - 1, a);
}
Търсене и
сортиране на реални данни
// esearch.cpp
int
binary_search(vector<Employee> v,
int from, int to, string n)
{
if (from > to) return -1;
int mid = (from + to) / 2;
if (v[mid].get_name() ==
n) return mid;
else if (v[mid].get_name()
< n)
return
binary_search(v, mid + 1, to, n);
else
return
binary_search(v, from, mid - 1, n);
}