Binäärihaku
Kokeneet kirjoittajat eivät ole vielä tarkistaneet sivun nykyistä versiota, ja se voi poiketa merkittävästi 20. maaliskuuta 2021 tarkistetusta
versiosta . tarkastukset vaativat
29 muokkausta .
Binäärihaku ( tunnetaan myös bisektiomenetelmänä tai dikotomiana ) on klassinen algoritmi elementin löytämiseksi lajitetusta taulukosta (vektorista), joka käyttää taulukon jakamista puoliksi. Käytetään tietojenkäsittelytieteessä , laskennallisessa matematiikassa ja matemaattisessa ohjelmointissa .
Binäärihaun erikoistapaus on puolittamismenetelmä , jota käytetään tietyn jatkuvan funktion juurien etsimiseen tietyltä aikaväliltä.
Elementin etsiminen järjestetystä taulukosta
- Tietorakenteen keskellä olevan elementin arvon määrittäminen. Saatua arvoa verrataan avaimeen.
- Jos avain on pienempi kuin keskiarvo, haku suoritetaan elementtien ensimmäisellä puoliskolla, muuten - toisessa.
- Haku rajoittuu siihen, että valitun puolikkaan keskielementin arvo määritetään uudelleen ja sitä verrataan avaimeen.
- Prosessi jatkuu, kunnes joko avainarvon sisältävä elementti löytyy tai hakuväli on tyhjä.
Vaikka koodi on melko yksinkertainen, siinä on muutamia sudenkuoppia.
- Koodi (first + last) / 2on virheellinen, jos firstja lastsopii yksilöllisesti niiden tyyppiin, mutta first+last ei [1] . Jos näin suuret taulukot ovat teoriassa mahdollisia, on turvauduttava temppuihin:
- Käytä koodia first + (last - first) / 2, joka ei varmasti johda ylivuotoon, kun käsittelet ei-negatiivisia kokonaislukuja ja ensimmäinen<viimeinen.
- Jos firstja last ovat osoittimia tai iteraattoreita , tällainen koodi on ainoa oikea, koska se ei riko abstraktiota ("osoitin + osoitin" -toiminto on jo virheellinen). Toki algoritmin monimutkaisuuden säilyttämiseksi tarvitsemme nopeita operaatioita “osoitin+numero → osoitin”, “osoitin−osoitin → numero”.
- Jos firstja last ovat allekirjoitettuja tyyppejä, suorita laskenta allekirjoittamattomassa tyypissä: ((unsigned)first + (unsigned)last) / 2. Javalla toimii seuraava koodi: ( allekirjoitettu (first + last) >>> 1binäärilisäys on sama kuin allekirjoittamaton, Java takaa tämän toiminnan myös ylivuodossa ja koko kaava toimii allekirjoitetuilla numeroilla etumerkittöminä).
- Kirjoita laskelma assemblerissä siirtolipun avulla . Jotain sellaista add eax, b; rcr eax, 1. Mutta ei ole suositeltavaa käyttää pitkiä tyyppejäfirst + (last - first) / 2 , se on nopeampi.
- Yksittäiset virheet ovat yleisiä binäärihauissa , ja jokainen tällainen virhe muuttuu silmukaksi , ohitukseksi tai rajojen ulkopuolelta. Siksi on tärkeää testata tällaisia tapauksia: tyhjä taulukko ( n=0), yksi elementti ( n=1), puuttuvan arvon etsiminen (liian suuri, liian pieni ja jossain keskellä), ensimmäisen ja viimeisen elementin etsiminen.
- Joskus vaaditaan, että jos xketjussa on useita esiintymiä, ei löydy yhtäkään, vaan välttämättä ensimmäinen (vaihtoehtona: viimeinen; tai ei ollenkaan x, vaan sitä seuraava elementti). [2] Esimerkiksi C++- funktio etsii ensimmäisen yhtäläisestä ja löytää x:ää seuraavan alkion. Jos ei löydy, molemmat palauta paikka, johon ne lisätään.std::lower_boundstd::upper_bound
Tiedemies Jon Bentley väittää, että 90 % opiskelijoista unohtaa ottaa huomioon kaikki näistä vaatimuksista kehittäessään binaarihakua. Ja jopa Jonin itsensä kirjoittamassa ja kirjasta kirjaan siirtymässä koodissa sisään hiipi virhe: koodi ei kestä ylivuotoa [1] .
Java-toteutusesimerkki
int binarySearch ( int [ ] arr , int avain ) {
int alhainen = 0 ;
int korkea = arr . pituus - 1 ;
while ( matala <= korkea ) {
int mid = ( matala + korkea ) >>> 1 ;
int midVal = arr [ mid ] ;
jos ( midVal < avain )
matala = keski + 1 ;
muu jos ( midVal > avain )
korkea = keski - 1 ;
muu
paluu puolivälissä ; // avain löytyi
}
paluu - ( alhainen + 1 ); // avainta ei löydy.
}
Sovellukset
Binäärihakumenetelmän käytännön sovellukset ovat erilaisia:
Katso myös
Muistiinpanot
- ↑ 1 2 Extra, Extra - Lue kaikki siitä: Lähes kaikki binaarihaut ja yhdistämismuodot ovat rikki . Arkistoitu 2. joulukuuta 2013 Wayback Machinessa // Joshua Bloch, Google Research; käännös — Lähes kaikissa binäärihaun ja yhdistämislajittelun toteutuksissa on virhe . Arkistoitu 24. marraskuuta 2013 Wayback Machineen
- ↑ C++ : ssa etsii ensimmäisen esiintymän ja löytää seuraavan elementin . std::lower_boundxstd::upper_boundx
Kirjallisuus
- Levitin A. V. Luku 4. Hajotusmenetelmä: Binäärihaku // Algoritmit. Johdatus kehitykseen ja analyysiin - M .: Williams , 2006. - S. 180-183. — 576 s. — ISBN 978-5-8459-0987-9
- Amosov A. A., Dubinsky Yu. A., Kopchenova N. P. Laskennalliset menetelmät insinööreille. - M .: Mir, 1998.
- Bakhvalov N. S., Zhidkov N. P. , Kobelkov G. G. Numeeriset menetelmät. - 8. painos - M . : Perustiedon laboratorio, 2000.
- Wirth N. Algoritmit + tietorakenteet = Ohjelmat . - M . : " Mir ", 1985. - S. 28 .
- Volkov E. A. Numeeriset menetelmät. - M .: Fizmatlit, 2003.
- Gill F., Murray W., Wright M. Käytännön optimointi. Per. englannista. - M .: Mir, 1985.
- Kormen, T. , Leizerson, C. , Rivest, R. , Stein, K. Algoritmit: rakentaminen ja analyysi = Introduction to Algorithms / Ed. I. V. Krasikova. - 2. painos - M .: Williams, 2005. - 1296 s. — ISBN 5-8459-0857-4 .
- Korn G., Korn T. Matematiikan käsikirja tutkijoille ja insinööreille. - M .: Nauka, 1970. - S. 575-576.
- Korshunov Yu. M., Korshunov Yu. M. Kybernetiikan matemaattiset perusteet. - Energoatomizdat, 1972.
- Maksimov Yu. A., Filippovskaya EA Algoritmit epälineaaristen ohjelmointiongelmien ratkaisemiseen. - M .: MEPhI, 1982.
- Robert Sedgwick. C:n perusalgoritmit. Perusteet/Tietorakenteet/Lajittelu/Haku. - Pietari. : DiaSoftYUP, 2003. - S. 672. - ISBN 5-93772-081-4 .
Linkit