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);
}

Хеширане