R ūšiavimo algoritmai

Preview:

DESCRIPTION

R ūšiavimo algoritmai. MRU prof. Dalė Dzemydienė Panaudota literatūra: http://www.techmat.vgtu.lt/konspektai/Algoritmai/Paskaita61.pdf. Algoritmų u niversalumas. - PowerPoint PPT Presentation

Citation preview

Rūšiavimo algoritmai

MRU prof. Dalė Dzemydienė

Panaudota literatūra:http://www.techmat.vgtu.lt/konspektai/Algoritmai/Paskaita61.pdf

Algoritmų universalumas

Jeigu atidžiai įsigilintume į šaknies traukimo algoritmą, tai galėtume pasakyti, kad jis tinka šakniai traukti iš bet kurio neneigiamo skaičiaus. Taigi algoritmą galime kartoti su vis kitais pradiniais duomenimis. 

Algoritmo tinkamumas įvairioms pradinių duomenų reikšmėms vadinamas universalumu (masiškumu).

Tai viena svarbiausių algoritmo savybių, ir nuo jos priklauso algoritmų praktinė vertė. Pavyzdžiui, sudaryti atskirą šaknies traukimo algoritmą kiekvienam skaičiui nebūtų prasmės. Tačiau yra ir tokių algoritmų, kurie skirti vienam duomeniui, pavyzdžiui, taksofonai, kurie priima tik vienos rūšies monetas. Argi šie algoritmai neturės universalumo savybės? Pamastykime. Jeigu tartume, kad neturės, tuomet iškiltų klausimas - kaipgi bus su algoritmais, kurie skirti tik dviems konkretiems duomenims ir pan. Patektume į aklavietę. Todėl universalumo sąvoką reikia patikslinti. Reikia laikyti, kad kiekvienas algoritmas yra skirtas kuriai nors pradinių duomenų klasei. Pavyzdžiui, šaknies traukimo algoritmui tokią klasę sudaro visi neneigiami skaičiai, taksofonui - nurodytos rūšies monetos. Algoritmo universalumas - tai algoritmo tinkamumas nurodytai pradinių duomenų klasei.

Rezultatyvumas Paminėsime dar vieną gana akivaizdžią algoritmų savybę, kuri

reiškia, kad atlikę kurį nors algoritmą, turime gauti kokį nors rezultatą.  

Algoritmo rezultatyvumas: algoritmas turi duoti kokį nors konkretų rezultatą.

Rezultatas suprantamas plačiąja prasme. Tai gali būti, pavyzdžiui, ne tik duotos lygties sprendiniai, bet ir pranešimas, kad duotoji lygtis sprendinių neturi arba kad blogai parinkti pradiniai duomenys (pavyzdžiui, šaknies traukimo algoritmo atveju - neigiamas skaičius), todėl šio  uždavinio sprendimas netenka prasmės.

Rikiavimo algoritmas – algoritmas, dėstantis duomenis tam tikra tvarka.

Algoritmo darbas priklauso nuo duomenų tvarkos apibrėžimo, duomenų struktūros, rikiuojamų, atminties panaudojimo rikiavimui, duomenų pateikimo vienalaikiškumo, eiliškumo, kitų veiksnių ...

Surūšiuoti duomenys taikomi

pateikiama informacija ir daugelyje kasdien naudojamų informacijos šaltinių: kataloguose, žinynuose, enciklopedijose, telefonų knygose

Rūšiavimo algoritmų taikymas

Beveik visose žmogaus veiklos srityse tenka saugoti informaciją ir ją panaudoti reikiamu momentu.

Informacijos tvarkymo, paieškos uždavinys darosi vis aktualesniu, kai kompiuterizuojami abu proceso etapai: informacijos gamybos (pvz., skaitmeninis garso,

vaizdo, rašytinių šaltinių saugojimas ir atgaminimas)

bei jos panaudojimo (duomenų bazės, globalus Internetas).

paieška efektyviausia, kai saugome surūšiuotus duomenis.

Rikiavimo algoritmai gali būti skirstomi keliais būdais:

Pagal naudojamą atmintį. Priklausomai nuo to, ar naudoja tik vidinę kompiuterio atmintį, ar jiems reikia ir išorinės, rikiavimo algoritmai skirstomi į vidinio rikiavimo ir išorinio rikiavimo.

Taip pat algoritmus galima skirstyti ir pagal reikiamos atminties kiekį (nereikia visai; reikia tik rodyklėms; papildomai reikia tiek, kiek yra duomenų).

Pagal stabilumą. Stabilūs algoritmai nekeičia lygių elementų tvarkos, o nestabilūs algoritmai to negarantuoja.

Pagal sudėtingumą.

Algoritmų analizėje

duomenų rikiavimo problema laikoma pačia svarbiausia, nes tai viena dažniausiai pasitaikančių operacijų programavime. Efektyvus rikiavimo algoritmo pasirinkimas gali turėti netgi lemiamą įtaką programos vykdymo spartai didėjant duomenų kiekiui.

Rūšiavimo (rikiavimo) strategija

Kelias ar būdas, pasirinktas norint surūšiuoti (rikiuoti) duomenis tam tikra tvarka – bus įvardijamas kaip rūšiavimo strategija.

Pavyzdys - žaidimas su pagaliukais

Žaidėjai paeiliui ima iš krūvelės pagaliukus. Vienu ėjimu galima paimti vieną arba du pagaliukus. Pralaimi tas, kuris paima paskutinį pagaliuką. Prieš sudarydami algoritmą aptarsime pagrįsime ir jo sprendimą. Šio algoritmo pradinis duomuo - pagaliukų skaičius krūvelėje, rezultatas - pranešimas, kuris iš žaidėjų laimi.

Algoritmų sudėtingumų lentelė Algoritmas Blogiausias Tikėtinas Geriausias Pastabos (stabilumas, atmintis,

išorinis/vidinis)

Skaitmeninisradixsort

O(2d N) O(2d N) O(2d N)

Tik skaitmeninėms teigiamoms duomenų reikšmėms, kur d yra skaitmenų sk. Reikalauja papildomos atminties

Greitojo rikiavimo (quicksort)

O(N2) O(N log N) O(N log N)Beveik nenaudoja papildomos atminties

Kombinuotas O(N log N) O(N (log N)²)    

Krūvos (heapsort)

O(N log N) O(N log N) O (N log N)Nestabilus, nenaudoja papildomos atminties

Šelo (Shell sort) O(N2) O(N1,2) O(N)  

Sąlajos(mergesort)

O(N log N) O(N log N) O(N log N)

Stabilus, naudoja papildomą atmintį. Tinka, kai iš karto galime nuskaityti nevisus duomenis į operatyvią atmintį

Burbulo (bubble)

O(N2) O(N2) O(N) Nenaudoja papildomos atminties

Įterpimo (insertion)

O(N2) O (N2) O(N) Stabilus

Išrinkimo (selection)

O(N2) O(N2) O(N2)  

Uždavinio formulavimas

Rūšiavimo uždavinio sudėtingumas

Nagrinėsime tokį rūšiavimo algoritmą, kuris naudoja 2 operacijas: dviejų aibės A elementų raktų palyginimą, dviejų elementų sukeitimą vietomis.

Rūšiavimo uždavinio sudėtingumas Įmkime pavyzdį, kai turime 3 elementų aibę

A=(a,b,c)

Rūšiavimo uždavinio sudėtingumas

Rūšiavimo uždavinio sudėtingumas

Algoritmavimo ir programavimo kalbos

- tai žymenų ir taisyklių sistemos, pritaikytos veiksmams ir jų atlikimo tvarkai aprašyti taip, kad algoritmą galėtų atlikti kompiuteris ar koks kitas automatas.

Prieš keletą dešimtmečių skirtumas tarp algoritmavimo ir programavimo kalbų buvo kur kas ryškesnis nei dabar. Mat tada kompiuterių galimybės buvo mažesnės, ir užrašant programas (programomis vadinami algoritmai, kuriuos gali įvykdyti kompiuteris) tekdavo taikytis prie skurdžios simbolikos, elementarių komandų. Tokie žymenys buvo nepatogūs, todėl žmogus pirmiausia rašydavo algoritmą  jam patogiu pavidalu, o vėliau jį pakeisdavo kompiuteriui priimtinu - programa. Šiuolaikiniai kompiuteriai supranta kur kas “žmoniškesnius” žymenis, todėl dažniausiai tos pačios kalbos vartojamos ir algoritmams, ir programoms užrašyti.

Paskalio programavimo kalba

Programavimo kalba, kaip ir bet kuri kita, turi savo abėcėlę. Paskalio kalbos abėcėlę sudaro:

1. raidės: a, b, c,   …

2. skaitmenys: 0, 1, 2, 3,   …

3. skyrybos ženklai:    : ,  ;  .   ?   …

4. operacijų (veiksmų) ženklai: +, -, >,    …

5. keletas dešimčių sutartinių žodžių, program, begin, end.

N.Virtas - programuotojas, sukūręs Paskalio kalbą.

Programos struktūra

Paskalio kalbos programą sudaro šios dalys:

1) antraštė;

2) aprašai;

3) veiksmai;

4) programos pabaigos požymis - taškas.

Dviejų skaičių sumavimas

Dabar šį algoritmą užrašysime Paskalio kalba:

program sumavimas; var a, b, suma: integer;

begin read (a, b); suma := a + b; writeln (suma)

end.

var (variable - “kintamasis”)

writeln (wrlte line - “rašyti eilutėmis”), kuris vadinamas spausdinimo arba rašymo sakiniu.

                                                                   

                                                               Dviejų skaičių sumavimo algoritmo

struktūrograma.

Programos vykdymas Lietuvoje paplitęs Turbo Paskalio kompiliatorius, dažnai

vadinamas Turbo Paskalio sistema ar net paprasčiausiai Turbo Paskaliu. N.Virto sukurta kalba vadinama standartiniu Paskaliu. Standartinis Paskalis buvo sukurtas taip, kad jis kuo geriau tiktų bendro pobūdžio uždaviniams užrašyti ir kuo mažiau priklausyti nuo kompiuterio tipo. Ypač jis tinka pradedantiesiems, kai mokomasi algoritmavimo konstrukcijų. Turbo Paskalis apima standartinį Paskalį, tačiau teikia dar daug galimybių valdyti patį kompiuterį. Kadangi mes domėsimės pačių algoritmų rašymu, tai mums visiškai pakaks standartinio Paskalio konstrukcijų.

Kiekvienam kintamajam kompiuteris skiria vietą savo atmintinėje. Ten saugoma to kintamojo reikšmė - konkretus duomuo.

Kintamųjų aprašų pavyzdys:

var  a, b : integer; x, y, z : real;

Reiškinys

- tai konstantos ir kintamieji, sujungti operacijų (veiksmų) ženklais bei lenktiniais skliaustais.

Reiškinių Paskalio kalba pavyzdžiai:

pl + p2 + p3) / 3

skl + sk2 - sk3 div 10

(a + b) * (a - b)

Priskyrimo sakinys

- tai kintamasis ir reiškinys, atskirti priskyrimo simboliu (:=). Atlikus programą gauta reiškinio reikšmė priskiriama kairėje esančiam kintamajam.

Priskyrimo sakinių pavyzdžiai:

sk := 5;

suma := x + y;

Algoritmas kvadratinio trinario ax2 +bx +c reikšmei rasti Paskalio kalba:

program trinaris;    var a, b, c, x, r : real; begin    read (a, b, c, x);    r := a * x * x + b * x + c;    writeln (r) end.

Parašykime algoritmą nurodytam parų skaičiui p išreikšti valandomis ir minutėmis

Iš struktūrogramos lengvai užrašysime programą:

program laikas; var p, val, min : integer;

begin read (p); val := p * 24; min := val * 60; writeln (val, min : 7)

end.

Parašykime sakinių seką kintamųjų a ir b reikšmėms sukeisti vietomis:

tarp := a; a := b; b := tarp;

Kintamojo tr reikšmė - triženklis skaičius. Parašykime algoritmą šio skaičiaus skaitmenų sumai rasti.

Paskalio kalba neturi operacijos, kuri išskirtų skaičiaus skaitmenis - tai reikia išreikšti aritmetinėmis operacijomis. Pirmąjį triženklio skaičiaus skaitmenį gauname dalydami šį skaičių iš 100:   s1 := tr div 100. Antrąjį skaitmenį gauti sudėtingiau. Iš pradžių reikia atmesti pirmąjį skaičiaus skaitmenį, po to - likusį dviženklį skaičių dalyti iš 10:   s2 := tr mod 100 div 10. Galima ir kitaip - pirma atmesti trečiąjį skaitmenį, po to - pirmąjį:   s2 := tr div 10 mod 10. Trečiasis skaitmuo lygus liekanai, gautai padalijus skaičių iš 10:   s3 := tr mod 10. Taigi triženklio skaičiaus skaitmenų sumą galima apskaičiuoti šitokiu algoritmu:

program triženklis; var tr, {triženklis skaičius} s1, s2, s3, {jo skaitmenys} suma : integer; {skaitmenų suma}

begin read (tr); s1 := tr div 100; {pirmasis skaitmuo} s2 := tr mod 100 div 10; {antrasis skaitmuo} s3 := tr mod 10; {trečiasis skaitmuo} suma := s1 + s2 + s3;

writeln (suma) end.

Loginis duomuo turi tik dvi reikšmes: “teisinga” ir “neteisinga”

Paskalio kalboje jos žymimos vardais: true - teisinga false - neteisinga. Loginius duomenis, kaip ir skaičius, galima vartoti

rašymo sakiniuose, su jais galima atlikti logines operacijas, jų reikšmes galima priskirti loginiams kintamiesiems. Kintamieji, galintys įgyti logines reikšmes, aprašuose žymimi žodžiu boolean. Pavyzdžiui, aprašu:

 var x, log : boolean;

Inversijos operacija labai paprasta: ją atlikus, esama loginė reikšmė pakeičiama priešinga. Ji žymima sutartiniu žodžiu not (“ne”) ir paprastai vadinama lietuviškai - neigimu.

Konjunkcija

x y x  and   y

false false false

false true false

true false false

true true true

Disjunkcija

x y x  or  y

false false false

false true true

true false true

true true true

Lyginimo operacijos

Operacijų prioritetai

Sudarysime loginį reiškinį, kurio reikšmė būtų true, jeigu x patenka į intervalą [a; b], arba false, jeigu nepatenka:

  log := (a <= x) and (x <= b) Matematikoje tokia sąlyga užrašoma paprasčiau: a <= x <= b. Programavime bet kurios lyginimo operacijos  a <= x  rezultatas būtų loginė reikšmė (true arba false)

ir tada jos nebegalima lyginti su skaičiumi b. Todėl tenka šią sąlygą išskaidyti į dvi paprastesnes ir jas sujungti konjunkcijos operacija.

Galimi keturi trumpiausi keliavimo būdai:

1)  a  and  e  and  g  3)   f  and  e  and  b

2)  c  and  e  and  g 4)   f  and  e  and  d

Juos galime užrašyri vienu ilgu loginiu reiškiniu:

a and e and g or c and e and g or f and e and b or f and e and d

(Skliaustai nebūtini, nes konjunkcija atliekama pirmiau už disjunkciją. )

Šakojimosi sakiniai

if   x <= 0      then  y := 0      else  y := x

Šitaip nurodoma atlikti vieną veiksmą iš dviejų: y := 0 arba y := x priklausomai nuo sąlygos - kintamojo x reikšmės.

Šakojimasis kai yra daugiau nei dvi galimybės

Grįžkime prie rūšiavimo algoritmų

Kai 3 skaičius reikia išrikiuoti (surūšiuoti) jų didėjimo tvarka

Primityviausias ir paprasčiausias rūšiavimo algoritmas (rūšiuojantis 3 elementus)

http://upload.wikimedia.org/wikipedia/commons/3/37/Bubble_sort_animation.gif

Recommended