You are on page 1of 32

АЛГОРИТМИ И

СТРУКТУРЕ ПОДАТАКА

1. Увод
АЛГОРИТМИ

 Алгоритам је врло стар појам и не подлеже строгом дефинисању.

 Не постоји строга дефиниција алгоритма, већ се он интуитивно


дефинише.

 Реч АЛГОРИТАМ потиче од имена арапског математичара из IX века, а


његово име је Muhammad ibn Musa al-Kwarizm.

 Емпиријска дефиниција алгоритма: Алгоритам је правило формулисано


на неком језику које једнозначно дефинише редослед операција
неопходан за трансформацију дозвољених улазних података у тражени
резултат.
АЛГОРИТМИ

 Алгоритам је опис поступка који након коначног броја радњи даје


резултат.

 Алогоритам је и део посла у процесу који од уоченог проблема доводи


до резултата (најчешће помоћу рачунарског програма).

Редослед послова:
СТРУКТУРЕ ПОДАТАКА

 Подаци одговарају дискретним, записаним чињеницама о феноменима


из којих се извлаче информације.

 Да би могли манипулисати подацима, они морају бити уређени.

 Уређен скуп података се зове структура.

 Без структуре података нема програма.

 Wirth је изједначио по значају алгоритамски и декларативни део (у којем


су дате структуре података). Он је показао да је структура података
потпуно равноправна у односу на алгоритам и да је то стабилнији део
програма.
ОДНОС АЛГОРИТМА И СТРУКТУРЕ ПОДАТАКА

 Ако посматрамо шему где су приказани алгоритми А1, А2, ..., Аn који сви
приступају некој структури података S, јасно је да измена неког од
aлгоритама Аi вероватно неће имати утицај на других n-1 алгоритама.

 Али свака измена структуре S ће готово сигурно изазвати измене у


скоро свим алгоритмима.
ГРАФОВИ

 За графичко приказивање структура података се користе графови.

 Састоји се од чворова (елементи скупа S).

 Релације међу тим чворовима се приказују тако што их


повезујемо гранама које не морају бити орјентисане.

 Орјентисан граф се зове диграф (directed graph).

 У математици, чворове графа означавамо кружићима,


док је код структура података уобичајено да се за ознаке
користе правоугаоници.

 За сваки чвор на диграфу се дефинише улазни степен чвора, а то је број


грана које улазе у чвор, и излазни степен чвора, тј. број грана које излазе
из њега.

 Граф низа:
ГРАФОВИ
КЛАСИФИКАЦИЈА СТРУКТУРЕ ПОДАТАКА

НИЗ

 Низови спадају у најзначајније и најстарије структуре података. Зову се


и вишедимензионалне структуре.

 Код Pascala, низови се односе на векторе, на матрице и на


вишедимензионалне низове.

СTEK (stack)

 Још се назива и LIFO листа (Last In First Out).

 Када треба сместити нови елемент у стек, он се ставља на његов крај


(PUSH операција), при чему се и при узимању елемената са стека они
такође узимају са краја (POP операција).
КЛАСИФИКАЦИЈА СТРУКТУРЕ ПОДАТАКА

РЕД (queue)

 Ред је FIFO (First In First Out) листа.


 У ову листу се елементи стављају на крај, али узимају са почетка.

ДЕК (двоструки ред)

 Убацивање и избацивање се врши са обе стране, тј. са оба краја.


КЛАСИФИКАЦИЈА СТРУКТУРЕ ПОДАТАКА

ЛИСТА (општа листа)

 Убацивање и избацивање елемената се може вршити са било које


позиције (на почетку, на крају, или на било којој позицији унутар листе).
КЛАСИФИКАЦИЈА СТРУКТУРЕ ПОДАТАКА

ПОВЕЗАНА ЛИСТА (linked list)

 Повезана листа je низ елемената, од којих сваки има два поља.

 У једном је вредност елемента (оно што би било на том месту у обичном


низу), а у другом показивач на следећи елемент низа.

 Задњи елемент показује на NULL.

 Предности овакве структуре података су убацивање и избацивање


елемената из листе у временској сложености О(1).
КЛАСИФИКАЦИЈА СТРУКТУРЕ ПОДАТАКА

ХЕШ ТАБЛИЦЕ (hash tables)

 Хеш таблице настају хеширањем елемената.

 Сваки елемент који желимо сместити у ову структуру података


хеширамо, тј. срачунамо вредност коју нека хеш функција даје за њега, и
сместимо на то место у табелу.

 Пример: Треба запамтити имена ученика неког разреда и још неки


податак о сваком, рецимо број телефона. Пример хеш функције је рецимо
збир ASCII вредности свих слова у имену по модулу величине таблице
(што је најпожељније неки прост број). Ако је то место већ заузето,
додајемо још један унос у исто поље (можемо хеш таблицу дакле памтити
као матрицу, или као низ повезаних листи, што је боља имплементација).
Сада кад требамо наћи Марков број телефона, сабраћемо ASCII
вредности слова у речи "Марко", узети ту вредност по модулу величине
таблице, и тражити на том месту у хеш таблици.

 Предност ове структуре података је време приступа елементу О(1).


КЛАСИФИКАЦИЈА СТРУКТУРЕ ПОДАТАКА

СТАБЛО (дрво, tree)

 За неки почетни чвор кажемо да је "корен"


(root) стабла.

 За сваки чвор који су "надоле" од њега и


директно повезани са њим кажемо да су
његова "деца" (children).

 Заједно са онима надоле са којима је повезан


преко више од једне ивице кажемо да су његови "потомци" (descendants).

 Сваки чвор који је "нагоре" од неког и повезан са њим је његов "предак"


(ancestor).

 Неки чвор заједно са свим његовим потомцима чини подстабло


(subtree) чији је он корен.

 Најчешће се користи бинарно стабло, у коме сваки чвор има највише


двоје деце.

 Такође, овде сваки чвор има своје лево и десно подстабло.


КЛАСИФИКАЦИЈА СТРУКТУРЕ ПОДАТАКА

БИНАРНО СТАБЛО ПРЕТРАГЕ (Binary Search Tree)

 То је такво стабло у коме је за неки чвор његово лево дете увек мање
од њега, а десно увек веће.

 У оваквом дрвету је за тражење, убацивање или избациване неког


елемента потребно време О(log n).

 Међутим, ако су елементи лоше распоређени, свака од ових операција


може однети чак О(n) времена!
КЛАСИФИКАЦИЈА СТРУКТУРЕ ПОДАТАКА

AVL (Adelson-Velsky and Landis) СТАБЛО

 AVL стабло је "избалансирано" бинарно стабло претраге.

 У њему је разлика висина левог и десног подстабла за сваки чвор


највише 1.

 При сваком додавању или избацивању елемената, обраћа се пажња да


стабло остане избалансирано, при чему се за тај корак не сме потрошити
више од О(log n) времена.
КЛАСИФИКАЦИЈА СТРУКТУРЕ ПОДАТАКА

HEAP

 Heap је још једна врста бинарног стабла, код кога је задовољен услов
да су деца сваког чвора увек већа или једнака од самог тог чвора (може се
правити и обрнуто, да су деца увек мања од оца).

 Ова структура података има изузетно широк спектар употребе.

 Наиме, често је потребно у сваком тренутку знати који је најмањи


елемент неког низа.

 Користећи heap, ову информацију имамо у О(1) (то је уствари први


елемент у heap-у).

 Избацивање или убацивање елемента ради се у О(log n).


ОПЕРАЦИЈЕ НАД СТРУКТУРАМА ПОДАТАКА

 Постоје три групе операција:

1. примитивне операције;
2. основне операције;
3. сложене операције;

 Примитивне операције су сасвим просте операције и углавном се


појављују у саставу других операција, тј. ретко се појављују као
изоловане.

 Треба споменути операцију Empty, која је логичка операција и враћа


вредност true ако је структура података празна, тј. нема елемената.

 Друга битна је операција Full, такође логичка која показује да ли је


меморијски простор намењен чувању неке структуре података попуњен.
ОПЕРАЦИЈЕ НАД СТРУКТУРАМА ПОДАТАКА

Сложене операције су:

а) претраживање – разлика између ове и операције тражења је у томе


што резултат ове операције може бити више од једног елемента;

б) сортирање – то је уређивање (по правилу) линијске структуре


података по неком критеријуму

в) копирање;

г) спајање две или више структура у једну;

д) разлагање једне структуре података на две или више.


ОПЕРАЦИЈЕ НАД СТРУКТУРАМА ПОДАТАКА

 Основне операције су најбитније и служе за међусобно разликовање


структура података које имају исти диграф.

 Постоје три групе ових операција:

а) приступ – то су семантички једноставне операције. Своде се на


уочавање (издвајање) неког елемента из структуре података ради читања
или измене податка (информационог дела, тј. садржаја елемента).
ОПЕРАЦИЈЕ НАД СТРУКТУРАМА ПОДАТАКА

Постоје три начина приступа у оквиру структуре података од којих су сви


равноправни, али неједнако заступљени:

1. према позицији: критеријум је место елемента, може се дати и


имплицитно, користи се код низова;

2. према информационом садржају (тражење): као аргумент тражења


се даје део информационог садржаја елемента и то такав део да потпуно
дефинише дати елемент. Део информативног садржаја који једнозначно
дефинише сваки елемент се назива кључ;

3. навигација – овај начин претраживања изграђен је око појма текућег


елемента. Текући елемент увек постоји и њему се имплицитно приступа;
ОПЕРАЦИЈЕ НАД СТРУКТУРАМА ПОДАТАКА

б) уклањање се врши на следећи начин: извуче се тражени елемент из


структуре и потом се ажурирају везе, како би се уклониле све према сада
непостојећем елементу;

в) додавање се изводи слично као уклањање, једина разлика је што се


нови елемент умеће у структуру, а везе се ажурирају како би се и нови
елемент нашао распоређен на право место.
СЛОЖЕНОСТ АЛГОРИТАМА

 Одређивање перформанси алгоритма се своди на израчунавање


временске сложености самог алгоритма у зависности од величине или
димензије проблема.

 Као природна димензија проблема узима се параметар који највише


утиче на време, а то је најчешће број улазних података. Он се у анализи
обележава са n, па се сложеност алгоритма изражава као функција од
n-f(n).

 Уобичајен начин за изражавање сложености алгоритма је O-нотација. За


функцију f(n) се каже да је O(g(n)) ако постоје позитивне константе c и n0
тако да је f(n)≤cg(n) за свако n≥n0. Тада је lim (f(n)/g(n)) = c kada n→∞.
Овако се налази горња граница сложености, јер је f(n) асимптотски
ограничено са g(n).

 Ако два програмска сегмента P1 и P2 имају сложености f1(n) и f2(n),


онда је укупна сложеност секвенце коју чине ова два сегмента
O(max(f1(n),f2(n))).
СЛОЖЕНОСТ АЛГОРИТАМА

 Уколико се, на пример, сегмент P2 комбинује са сегментом P1 тако да


чини секвенцу са делом сегмента P1 који доминантно одређује његову
сложеност, онда је укупна сложеност комбинације реда O(f1(n)f2(n)). За О-
нотацију важи особина транзитивности: Ако је f(n) реда O(g(n)), а g(n) реда
O(h(n)) онда је и f(n), такође, реда O(h(n)).

 Доња граница сложености алгоритма се одређује коришћењем Ω-


нотације. За функцију f(n) се каже да је Ω(g(n)) ако постоје позитивне
константе c и n0 тако да је f(n)≥cg(n) за свако n≥n0.

 Уколико нека функција f(n) задовољава истовремено релације


f(n)=O(g(n)) и f(n)=Ω(g(n) онда се каже да је f(n)=θ(g(n)), што представља
асимптотску границу перформанси и са горње и са доње стране. То значи
да постоје константе с1, c2 и n0 такве да је 0 ≤ c1g(n) ≤ f(n) ≤ c2g(n) за све
вредности n≥n0.
КЛАСЕ АЛГОРИТАМА ПО РАСТУЋОЈ СЛОЖЕНОСТИ

 O(1) – Константни алгоритми чија сложеност не зависи од улазних


података представљају најпожељнију врсту алгоритма, али су зато и
најређи. Пример: уметање елемента на почетак уланчане листе.

 O(log n) – Логаритамски алгоритми су такође веома пожељни због врло


спорог пораста логаритамске функције. Основа алгоритма мења
сложеност само за константан фактор. Сваки пут када се основа
експлицитно не наведе, подразумева се логаритам за основу 2 (log2 n).
Општи принцип логаритамских алгоритама се своди на редукцију
проблема сукцесивним половљењем док се не дође до терминалног
решења – проблема јединичне величине. Пример: бинарно претраживање
уређеног низа.

 O(n) – Линеарни алгоритми имају општу форму циклуса који се


извршава n пута и карактеристични су за проблеме који обрађују улазне
податке. Пример: секвенцијално претраживање неуређеног низа.

 O(n log n) – Линеарно логаритамски алгоритми су засновани на


бинарном одлучивању, половљењу проблема. Најбољи алгоритми
сортирања поређењем кључева имају ову сложеност.
КЛАСЕ АЛГОРИТАМА ПО РАСТУЋОЈ СЛОЖЕНОСТИ

 O(n2) – Квадратни алгоритми обично имају форму угнеждене петље


димензије n. Пример: директни методи сортирања.

 O(nk) – Степени алгоритми имају општу форму облика k угнеждених


петљи димензије n и одликује их значајан пораст сложености за велико n.
За све алгоритме овог и претходних типова се каже да су полиномијални,
јер се њихова сложеност може представити полиномом променљиве која
представља димензију проблема, нарочито за умерене вредности степена
k.

 O(kn) где је k>1 – Експоненцијални алгоритми су непогодни за


рачунарско решавање за проблеме већих димензија због изузетно брзог
пораста експоненцијалне функције.
АЛГОРИТМИ ЗА ПРЕТРАЖИВАЊЕ

ПРЕТРАЖИВАЊЕ У ХЕШ ТАБЛИЦАМА

 Ако користимо хеш таблице, тражење елемента је врло једноставно.

 Потребно је елемент "унети" у хеш функцију и тиме га нађемо у О(1).

ТРАЖЕЊЕ У БИНАРНОМ СТАБЛУ ПРЕТРАГЕ И AVL СТАБЛУ

 Код обa је процес исти: пођемо од корена целог стабла.

 Уколико је он елемент који тражимо, крај.

 Ако не, видимо да ли је елемент који тражимо мањи или већи од њега.
Ако је мањи, исти поступак (рекурзивно) понављамо за лево подстабло,
ако је већи за десно.

 Сложеност је О(log n), са тим да у небалансираном стаблу може да буде


и знатно гора (али и боља!).
АЛГОРИТМИ ЗА ПРЕТРАЖИВАЊЕ

ЛИНЕАРНА ПРЕТРАГА

 Претпоставимо да имамо обичан низ од n елемената.

 Линеарна претрага се састоји у томе да прођемо све елементе низа


тражећи онај који нам треба.

 Сложеност: О(n).
АЛГОРИТМИ ЗА ПРЕТРАЖИВАЊЕ

БИНАРНА ПРЕТРАГА

 Имамо сортиран (растући) низ од n елемената у коме треба наћи неки


елемент.

 Нека је на почетку LEFT=1 и RIGHT=1.

 У свакој итерацији, нађемо елемент MIDDLE као средњи између LEFT и


RIGHT.

 Уколико је тражени елемент једнак том MIDDLE, крај.

 Ако је MIDDLE већи од њега, кажемо RIGHT=MIDDLE, у супротном


LEFT=MIDDLE, и понављамо исти поступак.

 Врло једноставан, али врло често употребљаван концепт.

 Сложеност је О(log n).


АЛГОРИТМИ ЗА СОРТИРАЊЕ

SELECTION, INSERTION, BUBBLE SORT

 Ово су три врло једноставна алгоритма за сортирање елемената.

 Сложеност: О(n²).

QUICK SORT

 Најбољи алгоритам за сортирање.

 Ради по следећем принципу: одредимо неки, било који, елемент. Сада


испремештамо све елементе низа тако да су прво сви они мањи, па онда
сви они већи од одабраног. Сада, за сваки од ова два дела рекурзивно
позовемо QUICKSORT.

 Сложености је О(n log n), мада она није увек иста.

 У пракси, QUICKSORT обично даје боље резултате од свих осталих


алгоритама за сортирање.
АЛГОРИТМИ ЗА СОРТИРАЊЕ

MERGE SORT

 Ради на принципу “подели па владај”.

 Он наиме подели низ на два дела, рекурзивно се позива за оба, а када


се врати, та два дела спаја (merge) у један сортирани.

 Сложеност је увек О(n log n).

 Може се и користити за рачунање броја инверзија пермутације.

HEAP SORT

 Низ сортира тако што га смести у heap.

 Операције уметања и скидања са heap-а имају сложеност О(log n), па ће


овај алгоритам ће имати укупну сложеност О(n log n), јер сваки елемент
треба прво да убацимо у heap, па кад смо формирали цео, избацујемо
увек први елемент докле год не испразнимо heap.
АЛГОРИТМИ ЗА СОРТИРАЊЕ

BUCKET SORT

 Претпоставимо да имамо низ од n елемената, али у коме је сваки цео


број између 1 и m.

 Направимо m bucket-а, тако да сваком броју одговара по један.

 Прво сваки елемент ставимо у њему одговарајући bucket.

 Сада прођемо кроз све bucket-е још једном да би направили сортирани


низ.

 Сложеност је O(m+n).

 Уколико је m мали број (O(n)), сложеност је линеарна. Ако је пак m


велико, и сложеност је велика, а и проблем је направити m bucketa (због
количине потребног простора).
АЛГОРИТМИ ЗА СОРТИРАЊЕ

RADIX SORT

 RADIX SORT има сличну идеју као bucket.

 Oн прво направи само 10 bucket-а (ако радимо у бројном систему са


основом 10), и смести сваки елемент у одговарајући bucket.

 Сада у сваком bucket-у имамо велики број елемената, и они нису


сортирани међусобно, али сви имају исту прву цифру.

 Сада можемо применити исти поступак на елемент сваког bucket-а, с


тим што уместо прве разматрамо другу цифру. Онда то исто за трећу, итд.

 Сложеност је O(n*k), где је k број цифара колико имају елементи тог


низа.

You might also like