Šis vadovėlis paaiškins dvejetainę paiešką ir rekursinę dvejetainę paiešką Java kalba kartu su jos algoritmu, įgyvendinimu ir Java dvejetainės paieškos kodo pavyzdžiais:
Dvejetainė paieška "Java" - tai metodas, naudojamas tikslinei reikšmei arba raktui kolekcijoje ieškoti. Tai metodas, kai rakto paieškai naudojamas "skaldyk ir valdyk" metodas.
Kolekcija, kuriai bus taikoma dvejetainė paieška raktui ieškoti, turi būti surūšiuota didėjančia tvarka.
Paprastai dauguma programavimo kalbų palaiko linijinės paieškos, dvejetainės paieškos ir šifravimo metodus, kurie naudojami duomenims kolekcijoje ieškoti. Šifravimo mokysimės vėlesniuose vadovėliuose.
Dvejetainė paieška "Java
Tiesinė paieška yra pagrindinis metodas. Taikant šį metodą, masyvas apeinamas nuosekliai ir kiekvienas elementas lyginamas su raktu, kol randamas raktas arba pasiekiamas masyvo galas.
Tiesinė paieška praktikoje naudojama retai. Dažniausiai naudojamas dvejetainis paieškos metodas, nes jis yra daug greitesnis už tiesinę paiešką.
"Java" siūlo tris būdus, kaip atlikti dvejetainę paiešką:
- Iteracinio metodo taikymas
- Naudojant rekursinį metodą
- Naudojant metodą Arrays.binarySearch ().
Šioje pamokoje įgyvendinsime ir aptarsime visus šiuos 3 metodus.
Dvejetainės paieškos algoritmas "Java
Taikant dvejetainį paieškos metodą, rinkinys pakartotinai padalijamas į dvi dalis ir raktinio elemento ieškoma kairėje arba dešinėje rinkinio pusėje, atsižvelgiant į tai, ar raktinis elementas yra mažesnis, ar didesnis už vidurinį rinkinio elementą.
Paprastas dvejetainės paieškos algoritmas yra toks:
- Apskaičiuokite vidurinį kolekcijos elementą.
- Palyginkite pagrindinius elementus su viduriniu elementu.
- Jei raktas = vidurinysis elementas, grąžinama rasto rakto vidurinioji indekso pozicija.
- Kitaip Jei raktas> vidurinis elementas, tuomet raktas yra dešinėje kolekcijos pusėje. Taigi pakartokite 1-3 veiksmus apatinėje (dešinėje) kolekcijos pusėje.
- Else key <vidurio elementas, tuomet raktas yra viršutinėje kolekcijos pusėje. Vadinasi, reikia pakartoti dvejetainę paiešką viršutinėje kolekcijos pusėje.
Kaip matote iš pirmiau pateiktų veiksmų, atliekant dvejetainę paiešką, pusė kolekcijos elementų ignoruojami iškart po pirmojo palyginimo.
Atkreipkite dėmesį, kad ta pati veiksmų seka galioja ir iteracinei, ir rekursyvinei dvejetainei paieškai.
Iliustruokime dvejetainį paieškos algoritmą pavyzdžiu.
Pavyzdžiui, paimkime tokį surūšiuotą masyvą iš 10 elementų.
Apskaičiuokime vidurinę masyvo vietą.
Vidurio = 0+9/2 = 4
#1) Raktas = 21
Pirmiausia palyginsime rakto reikšmę su elementu [mid] ir nustatysime, kad elemento reikšmė ties viduriu = 21.
Taigi randame, kad raktas = [mid]. Vadinasi, raktas randamas masyvo 4 pozicijoje.
#2) Raktas = 25
Pirmiausia palyginsime rakto reikšmę su viduriu. Kadangi (21 <25), rakto tiesiogiai ieškosime viršutinėje masyvo pusėje.
Dabar vėl rasime viršutinės masyvo pusės vidurį.
Vidurio = 4+9/2 = 6
Vertė vietoje [mid] = 25
Dabar palyginsime rakto elementą su vidurio elementu. Taigi (25 == 25), taigi raktas rastas vietoje [mid] = 6.
Taigi pakartotinai dalijame masyvą ir lygindami raktinį elementą su viduriu nusprendžiame, kurioje pusėje ieškoti rakto. Dvejetainė paieška yra efektyvesnė laiko ir korektiškumo požiūriu, be to, ji daug greitesnė.
Dvejetainės paieškos įgyvendinimas Java
Naudodamiesi pirmiau pateiktu algoritmu, įgyvendinkime dvejetainės paieškos programą "Java", taikydami iteracinį metodą. Šioje programoje paimsime pavyzdinį masyvą ir atliksime dvejetainę paiešką šiame masyve.
import java.util.*; class Main{ public static void main(String args[]){ int numArray[] = {5,10,15,20,25,30,35}; System.out.println("Įvesties masyvas: " + Arrays.toString(numArray)); //ieškomas raktas int key = 20; System.out.println("\nKey to be searched=" + key); /nustatyti pirmą indeksą int first = 0; /nustatyti paskutinį elementą int last=numArray.length-1; //apskaičiuoti masyvo vidurįmasyvas int mid = (first + last)/2; //apie tai, kad first ir last nesutampa while( first <= last ){ //jei mid <raktas, tai ieškomas raktas yra pirmoje masyvo pusėje if ( numArray[mid] last ){ System.out.println("Elementas nerastas!"); } } } } }
Išvestis:
Įvesties masyvas: [5, 10, 15, 20, 25, 30, 35]
Ieškomas raktas=20
Elementas rastas ties indeksu: 3
Pirmiau pateiktoje programoje parodytas iteracinis dvejetainės paieškos metodas. Iš pradžių deklaruojamas masyvas, tada apibrėžiamas ieškomas raktas.
Apskaičiavus masyvo vidurį, raktas lyginamas su vidurio elementu. Tada, priklausomai nuo to, ar raktas yra mažesnis, ar didesnis už raktą, rakto ieškoma atitinkamai apatinėje arba viršutinėje masyvo pusėje.
Rekursinė dvejetainė paieška "Java
Dvejetainę paiešką taip pat galite atlikti naudodami rekursijos metodą. Šiuo atveju dvejetainis paieškos metodas kviečiamas rekursiškai, kol randamas raktas arba išnaudojamas visas sąrašas.
Toliau pateikiama programa, kuria įgyvendinama rekursinė dvejetainė paieška:
import java.util.*; class Main{ //rekursyvus dvejetainės paieškos metodas public static int binary_Search(int int intArray[], int low, int high, int key){ //jei masyvas yra tvarkingas, tada atlikite dvejetainę paiešką masyve if (high>=low){ //apskaičiuokite vidurį int mid = low + (high - low)/2; //if key =intArray[mid] return mid if (intArray[mid] == key){ return mid; } //jei intArray[mid]> key, tada key yra kairėje pusėjemasyvo pusė if (intArray[mid]> key){ return binary_Search(intArray, low, mid-1, key);//rekursyviai ieško rakto }else //raktas yra dešinėje masyvo pusėje { return binary_Search(intArray, mid+1, high, key);//rekursyviai ieško rakto } } } return -1; } public static void main(String args[]){ //definuokite masyvą ir raktą int int intArray[] = {1,11,21,21,31,41,41,51,61,71,81,91}; System.out.println("InputSąrašas: " + Arrays.toString(intArray)); int key = 31; System.out.println("Ieškomas raktas:" + key); int high=intArray.length-1; //kviečiame dvejetainės paieškos metodą int result = binary_Search(intArray,0,high,key); //spausdinti rezultatą if (result == -1) System.out.println("\nKey nerastas pateiktame sąraše!"); else System.out.println("\nKey rastas vietoje: "+rezultatas + " sąraše"); } } }
Išvestis:
Įvesties sąrašas: [1, 11, 21, 31, 41, 51, 61, 71, 81, 91
Ieškomas raktas:
Raktas randamas sąrašo vietoje: 3
Naudojant metodą Arrays.binarySearch ().
"Java" klasėje "Arrays" pateikiamas metodas "binarySearch ()", kuris atlieka dvejetainę paiešką duotame masyve. Šis metodas kaip argumentus priima masyvą ir ieškomą raktą ir grąžina rakto poziciją masyve. Jei raktas nerandamas, metodas grąžina -1.
Toliau pateiktame pavyzdyje įgyvendinamas metodas Arrays.binarySearch ().
import java.util.Arrays; class Main{ public static void main(String args[]){ //apibrėžti masyvą int intArray[] = {10,20,30,40,50,60,70,80,90}; System.out.println("Įvesties masyvas : " + Arrays.toString(intArray)); //apibrėžti ieškomą raktą int key = 50; System.out.println("Ieškomas raktas:" + key); //iššaukti binarySearch metodą duotame masyve su ieškomu raktu int result =Arrays.binarySearch(intArray,key); //spausdinti grąžinamą rezultatą if (result <0) System.out.println("\nKey nerastas masyve!"); else System.out.println("\nKey rastas masyve indeksu: "+rezultatas + "); } } }
Išvestis:
Įvesties masyvas: [10, 20, 30, 40, 50, 60, 70, 80, 90]
Ieškomas raktas:50
Raktas randamas masyve, kurio indeksas yra 4.
Dažnai užduodami klausimai
Q #1) Kaip parašyti dvejetainę paiešką?
Atsakymas: Dvejetainė paieška paprastai atliekama dalijant masyvą į dalis. Jei ieškomas raktas yra didesnis už vidurinį elementą, tada ieškoma viršutinėje masyvo dalyje, toliau dalijant ir ieškant dalinio masyvo, kol randamas raktas.
Panašiai, jei raktas yra mažesnis už vidurinį elementą, rakto ieškoma apatinėje masyvo dalyje.
Q #2) Kur naudojama dvejetainė paieška?
Atsakymas: Dvejetainė paieška dažniausiai naudojama rūšiuotiems duomenims ieškoti programinėse programose, ypač kai atminties erdvė yra kompaktiška ir ribota.
Q #3) Kas yra didžioji dvejetainės paieškos O?
Atsakymas: Dvejetainės paieškos laiko sudėtingumas yra O (logn), kur n yra masyvo elementų skaičius. Dvejetainės paieškos erdvės sudėtingumas yra O (1).
Q #4) Ar dvejetainė paieška yra rekursyvi?
Atsakymas: Taip. Kadangi dvejetainė paieška yra strategijos "skaldyk ir valdyk" pavyzdys ir ją galima įgyvendinti naudojant rekursiją. Galime padalyti masyvą į dalis ir vėl ir vėl skambinti tam pačiam metodui, kad atliktume dvejetainę paiešką.
Q #5) Kodėl ji vadinama dvejetaine paieška?
Atsakymas: Dvejetainis paieškos algoritmas naudoja "skaldyk ir valdyk" strategiją, pagal kurią masyvas pakartotinai padalijamas į pusę arba dvi dalis. Todėl jis vadinamas dvejetainiu paieškos būdu.
Išvada
Dvejetainė paieška yra dažnai naudojamas paieškos metodas Java. Norint atlikti dvejetainę paiešką, reikia, kad duomenys būtų surūšiuoti didėjančia tvarka.
Dvejetainė paieška gali būti įgyvendinama taikant iteracinį arba rekursinį metodą. "Java" klasėje "Arrays" taip pat pateikiamas metodas "binarySearch", kuris atlieka dvejetainę paiešką masyve.
Vėlesnėse pamokose nagrinėsime įvairius rūšiavimo būdus "Java".