[Powered by Google Translate] [7 skirsnis: patogesnė]
[Rob Bowden] [Harvardo universiteto]
[Tai CS50] [CS50.TV]
Gerai. Taigi, kaip sakiau mano elektroninio pašto adresą,
tai bus dvejetainis medis intensyviai dalis.
Bet ten nėra, kad daug klausimų.
Taigi, mes ketiname išbandyti ir atkreipti dėmesį į kiekvieną klausimą
ir eiti į skausminga išsamiai visų geriausių būdų, kaip daryti dalykus.
Taigi pačioje pradžioje, mes einame, per imčių brėžinius dvejetainiai medžiai ir kita.
Taigi čia, "Atminkite, kad dvejetainis medis mazgus, panašias į susietą sąrašą,
išskyrus vietoj vieno rodyklė yra du: vienas kairėje "vaiko"
ir vienas dešinėje "vaiko". "
Taigi dvejetainis medis yra kaip susietą sąrašą,
išskyrus struct turi dvi rodykles.
Yra Trójkowy medžiai, kurie ketina turėti tris patarimų,
yra N-Arnhem medžiai, kuri tiesiog bendrinis žymeklį
kad tada jūs turite malloc būti pakankamai didelis, kad
pakankamai pabrėžiamas visų galimų vaikų.
Taigi, dvejetainis medis, tiesiog taip atsitinka, turėti pastovų skaičių dviejų.
Jei norite, galite duoti kaip Smūginės medžio susietą sąrašą,
bet aš nemanau, kad kas vadina tai, kad.
"Nupiešk dėžės ir rodykles dvejetainis medis mazgas schema
su Nate mėgstamą skaičių, 7, kur kiekvienas vaikas žymeklis yra niekinis. "
Taigi, iPad režimas.
>> Tai bus gana paprasta.
Mes tiesiog teks mazgas, aš padaryti tai kaip kvadratas.
Ir aš padaryti vertybes čia.
Taigi ši vertė bus eiti čia,
ir tada žemyn čia mes į kairę rodyklę kairėje ir teisę rodyklę dešinėje.
Ir tai yra labai daug, todėl konvencija skambinti į kairę ir į dešinę, žymeklis pavadinimai.
Abi šios priemonės yra bus niekinis.
, Kad bus tiesiog nulis, ir kad bus tiesiog yra niekinis.
Gerai. Taigi atgal čia.
"Su susietą sąrašą, mes tik turėjo laikyti žymeklį
į pirmąjį sąrašą, kad būtų prisiminti visą susietą sąrašą, arba visą sąrašą mazgas.
Be to, su medžiais, mes tik laikyti žymeklį
į vieną mazgą, siekiant prisiminti visą medį.
Šis mazgas yra Calle "root" iš medžio.
Remtis diagramos prieš arba parengti naują
toks, kad turite dėžės ir rodykles vaizdavimas dvejetainis medis
vertė 7, tada kairėje 3
9 Tada dešinėje, o tada 6 nuo 3 teise. "
Leiskite pamatyti, jei aš galiu prisiminti visa tai, mano galva.
Taigi, tai bus mūsų šaknis čia.
Mes turime šiek tiek žymeklį kažkur, kažkas, kad mes vadiname šaknį,
ir ji nukreipta šis vaikinas.
Dabar, kad naują mazgas,
Ką turime 3 kairėje?
Taigi, naujas mazgas su 3, ir ji iš pradžių nurodo null.
Aš tiesiog įdėti N.
Dabar mes norime padaryti, kad eiti į kairę nuo 7.
Taigi, mes pakeisti šį žymiklį į dabar šis vaikinas.
Ir mes darome tą patį. Mes norime, kad 9 Over Here
, kuri iš pradžių tiesiog sako null.
Mes ketiname pakeisti šią rodyklę, nurodykite 9,
ir dabar mes norime įdėti 6 į dešinę iš 3.
Taigi jis ketina padaryti 6.
Ir kad vaikinas bus nurodyti kryptį.
Gerai. Taip, kad visa tai prašo mūsų padaryti.
>> Dabar eikime per kai terminologija.
Mes jau kalbėjome apie tai, kaip iš medžio šaknys yra iš viršaus labiausiai medžio mazgas.
Vienas yra 7. "Iš medžio apačioje centrai yra vadinami lapai.
Kiekvienas mazgas, kuris tiesiog yra niekinis, kaip savo vaikų lapų.
Taigi tai yra įmanoma, jei mūsų dvejetainis medis yra tik vienas mazgas,
kad medis yra lapas, ir viskas.
"Iš medžio" aukštis "yra apynių, jūs turite padaryti
gauti iš viršaus į lapo pusėje. "
Mes susisieksime per sekundę, skirtumą
tarp subalansuotas ir nesubalansuoto dvejetainiai medžiai,
bet dabar, bendras aukštis šio medžio
Sakyčiau, yra 3, nors jei skaičiuoti apynių
jūs turite padaryti, siekiant gauti iki 9, tada tai tikrai tik aukštis 2.
Dabar tai yra nesubalansuotas dvejetainis medis,
bet mes kalbėjome apie subalansuota, kai ji gali būti aktuali.
Taigi dabar mes galime kalbėti apie medžio mazgų požiūriu
, palyginti su kitų mazgų medyje.
Taigi dabar mes turime tėvai, vaikai, broliai, seserys, protėviai, ir palikuonių.
Jie yra gana sveiku protu, ką jie reiškia.
Jei mes klausiame - tai tėvus.
Taigi, kas yra 3 tėvų?
[Studentai] 7. >> Taip. Patronuojanti įmonė yra tiesiog bus, kas rodo jums.
Tai kas yra 7 vaikai?
[Studentai] 3 ir 9. >> Taip.
Atkreipkite dėmesį, kad "vaikai" tiesiog reiškia, kad vaikai,
taip 6 negalėjo būti taikoma, nes jis kaip anūkas.
Bet tada, jei mes einame palikuonis, todėl tai, ką yra 7 palikuonys?
[Studentai] 3, 6 ir 9. >> Taip.
Šakninis mazgas palikuonys bus viskas į medį,
išskyrus gal pati šakninis mazgas, jei nenorite manyti, kad palikuonis.
Ir, pagaliau, protėviai, todėl priešinga kryptimi.
Taigi, kas yra 6 protėviai?
[Studentai] 3 ir 7. >> Taip. 9 neįskaičiuoti.
Tai tiesiog tiesioginė sąsaja atgal į šaknis
bus jūsų protėviai.
>> "Mes sakome, kad dvejetainis medis" užsakė ", jei už kiekvieno medžio mazgas,
visų savo palikuonių kairėje turi mažiau vertybes
ir teise, turi didesnės reikšmės.
Pavyzdžiui, aukščiau medis užsisakyti bet tai nėra vienintelis galimas tvarkingas.
Prieš mes į, kad,
užsisakyti dvejetainis medis, taip pat žinomas kaip dvejetainis paieškos medis.
Čia mes atsitiktų būti vadiname tai tvarkingas dvejetainis medis,
bet aš niekada girdėjote jis vadinamas užsisakyti dvejetainis medis, prieš,
ir viktorinos yra daug labiau tikėtina, įdėti dvejetainis paieškos medis.
Jie vienas ir tas pats,
ir labai svarbu, jums atpažinti skirtumą tarp dvejetainis medis ir dvejetainis paieškos medis.
Dvejetainis medis yra tik medis, kad atkreipia dėmesį į du dalykus.
Kiekvienas mazgas atkreipia dėmesį į du dalykus.
Yra ne apie vertybes, ji pažymi, kad motyvai.
Taigi, kaip čia, nes tai dvejetainis paieškos medis,
mes žinome, kad, jei mes einame į kairę nuo 7,
tada visi vertybių, kurį galime pasiekti
eidami liko iš 7 turi būti mažiau nei 7.
Atkreipkite dėmesį, kad visos vertybės yra mažiau kaip 7 3 ir 6.
Visi tie, kurie į kairę nuo 7.
Jei mes einame į dešinę nuo 7, viskas turi būti didesnis kaip 7,
taip 9 yra į dešinę nuo 7, todėl mes geri.
Tai ne dvejetainis medis,
reguliariai dvejetainis medis, mes galime tik 3 viršuje, 7 į kairę,
Nuo 9 iki 7 kairėje; nėra užsisakyti vertybių bebūtų.
Dabar, mes ne iš tikrųjų, nes tai varginantis ir nereikalingas,
bet "stengiasi padaryti su daug užsakytas medžių, kaip jūs galite galvoti
skaičius 7, 3, 9 ir 6.
Kiek skirtingų tvarka yra? Kas yra kiekvienam iš jų aukštis? "
>> Mes padarysime pora, bet pagrindinė idėja yra,
tai jokiu būdu unikalus atstovavimas dvejetainis medis, kurio sudėtyje yra šių vertybių.
Visi mes turime, yra kai dvejetainis medis, kuris yra 7, 3, 6, ir 9.
Kitas galimas galioja vienerius būtų šaknis yra 3,
eiti į kairę ir tai 6, eikite į kairę ir tai 7,
eiti į kairę ir tai 9.
, Kuri yra puikiai tinka dvejetainis paieškos medis.
Tai nėra labai naudingi, nes tai tiesiog kaip susietą sąrašą
ir visi šių rodykles yra tiesiog niekinis.
Bet tai galioja medis. Taip?
[Studentų] Ar vertybės turi būti didesnis dešinėje?
Ar tai? >> Tai reiškė eiti į kitą pusę.
Yra taip pat - Taip, galime pereiti, kad.
9, 7, 6, 3. Geras laimikis.
Jis vis dar turi klausyti, ką dvejetainis medis paiešką turėtų daryti.
Taigi viskas į kairę turi būti mažesnis, nei bet kuriuo mazgo.
Mes galime tiesiog perkelti, tarkim, šį 6 ir įdėti jį čia.
Ne, mes negalime. Kodėl aš nuolat tai daro?
Darom - čia yra 6, čia yra 7, 6 taškai 3.
Tai vis dar galioja dvejetainis paieškos medis.
Kas yra negerai, jei aš - galime pamatyti, jei aš gali sugalvoti susitarimą.
Taip, gerai. Taigi, kas yra negerai su šio medžio?
Manau, aš jau davė jums užuominą, kad yra kažkas negerai su juo.
Kodėl aš nuolat tai daro?
Gerai. Tai atrodo pagrįstas.
Jei pažvelgsime kiekvieną mazgą, kaip 7, tada 7 kairėje yra 3.
Taigi, mes turime 3, dalykas, į dešinę nuo 3 6.
Ir jei jums atrodo 6-ąją, dalykas, į dešinę nuo 6 yra 9.
Tad kodėl tai nėra galioja dvejetainis paieškos medis?
[Studentai] 9 vis dar yra į kairę nuo 7. >> Taip.
Ji turi būti teisinga, kad visos reikšmės jums galbūt gali pasiekti, eikite į kairę nuo 7 yra mažiau nei 7.
Jei mes einame į kairę iš 7, mes turime 3, ir mes vis dar galite gauti iki 6,
mes vis dar galite gauti iki 9, bet powędrowały mažiau nei 7,
mes neturėtų būti suteikta galimybė gauti skaičius, kad didesnis nei 7.
Taigi, tai nėra galiojantis dvejetainis paieškos medis.
>> Mano brolis iš tikrųjų turėjo interviu klausimą
, kad iš esmės tai buvo, tiesiog kodas kažką, kad būtų patvirtinta
ar medis yra dvejetainis paieškos medis,
, todėl pirmas dalykas, kurį jis darė, buvo tik patikrinti,
jeigu iš kairės ir dešinės yra teisingos, ir tada pakartoti ten.
, Bet jūs galite ne tik padaryti, kad, todėl jūs turite sekti
į tai, kad dabar, kai aš atvyko liko iš 7,
viskas šiame šaka turi būti mažiau nei 7.
Teisingas algoritmas turi sekti
lemia, kad vertybės galbūt gali sumažėti.
Mes negalime eiti per visus juos.
Yra gražus pasikartojimo santykis,
nors mes ne Dotarłeś tiems, arba mes ne gauti tiems,
nustatyti, kiek ten iš tikrųjų yra.
Taigi yra 14 iš jų.
Idėja, kaip jūs daryti matematiškai yra panašus,
galite pasirinkti bet kurią vieną šakninis mazgas,
ir tada, jei aš pasiimti 7 šakninis mazgas,
tada yra, tarkim, kai kuriuos skaičius, kad galite eiti mano kairę mazgas,
ir yra keletas numeriai, kurie gali būti mano dešinėje mazgas,
bet jei aš n skaičiai, tada suma, kad gali eiti į kairę
plius sumą, kad gali eiti į dešinę, yra n - 1.
Taigi likusių numerių, jie turi, kad būtų galima eiti arba į kairę, arba teise.
Atrodo, kad sunku, kad, jei aš per pirmuosius 3, tada viskas turi eiti į kairę,
bet jei aš įdėti 7, tada kai kurie dalykai gali eiti į kairę ir kai kurių dalykų gali eiti į dešinę.
Ir "3 pirmasis", aš reiškė, viskas gali eiti į dešinę.
Tai tikrai, jūs tiesiog turite galvoti apie tai, kaip,
kiek daug dalykų gali eiti į kitą lygį medžio.
Ir jis išeina būti 14 arba jūs galite padaryti juos visus,
ir tada jūs gausite 14.
>> Grįžtant čia,
"Užsakytas dvejetainiai medžiai yra kietas, nes mes galime ieškoti per juos
labai panašiai kaip ieškoti per rūšiuotų masyvo.
Norėdami tai padaryti, mes pradedame ties pagrindu ir dirbti savo kelią žemyn medžio
prieš lapų, nuo vertybių, mes ieško patikrinti kiekvienas mazgas vertybes.
Jei dabartinės mazgo vertė yra mažesnė už vertę, mes ieškome,
jūs einate šalia mazgas teisių kūdikiui.
Priešingu atveju, jūs einate mazgas kairėje vaiko.
Tam tikru momentu, jums rasti vertę, jūs ieškote, arba jums paleisti į nulį,
vertę ne į medį ".
Turiu perbraižyti medį, mes turėjome anksčiau, kad paims antrą.
Bet mes norime ieškoti, ar 6, 10 ir 1 į medį.
Taigi, kas tai buvo, 7, 9, 3, 6. Gerai.
Numerius, kuriuos norite ieškoti, mes norime ieškoti 6.
Kaip veikia šis algoritmas darbą?
Na, mes taip pat turi keletą šaknų žymiklį prie mūsų medžio.
Ir mes norėtume eiti į šaknis ir pasakyti, tai yra vertė lygi vertės Mes ieškote?
Taigi, mes ieškome už 6, todėl tai nėra lygus.
Todėl mes nuolat vyksta, ir dabar mes galime pasakyti, gerai, kad 6 yra mažiau nei 7.
Ar tai reiškia, mes norime eiti į kairę, ar mes norime eiti į dešinę?
[Studentų] kairės. >> Taip.
Tai žymiai lengviau, visi jūs turite padaryti, tai atkreipti vieną galimą mazgas medžio
ir tada jums NeraŠykiTe - vietoj bando galvoti savo galva,
gerai, jei tai mažiau, man eiti į kairę arba eiti teisę,
tiesiog žiūri šioje nuotraukoje, tai labai aišku, kad aš turiu eiti į kairę
jei šis mazgas yra didesnė už vertę, kad Aš ieškau.
Taigi jūs einate į kairę, dabar aš ne 3.
Noriu - 3 yra mažiau Aš ieškau už vertę, kuri yra 6.
Taigi, mes einame į dešinę, ir dabar aš galų gale 6,
o tai yra vertė, aš ieškau, todėl aš return true.
Kitą vertė aš ruošiuosi ieškoti 10.
Gerai. Taigi, 10, dabar vyksta - nupjautų, kad ketina laikytis pagrindines.
Dabar 10 yra bus didesnė už 7, todėl aš noriu žiūrėti į dešinę.
Aš ruošiuosi atvažiuoti čia, 10 bus didesnė už 9,
todėl aš ruošiuosi norėsite pažvelgti į dešinę.
Aš atėjau čia, bet kaip čia dabar aš ne null.
Ką daryti, jei aš paspauskite null?
[Studentų] Grįžti klaidingas? >> Taip. Neradau 10.
1 bus beveik identiškas atvejis,
, išskyrus atvejus, ji tiesiog bus apversta, užuot ieškojus
žemyn dešinėje pusėje, aš ruošiuosi žiūrėti žemyn į kairę pusę.
>> Dabar manau, kad mes iš tikrųjų gauti kodą.
Štai kur - atverti CS50 prietaisą ir naršyti savo kelią ten,
bet taip pat galite tiesiog padaryti jį erdvėje.
Tai tikriausiai idealus daryti erdvėje,
nes mes galime dirbti erdvėje.
"Pirmiausia mums reikės dvejetainis medis mazgas, kuriame yra int vertybes naujo tipo apibrėžimą.
Naudojant Šablonas Typedef žemiau,
dvejetainis medis mazgas sukurti naujo tipo apibrėžimą.
, Jei turite problemų. . . "Blah, blah, blah. Gerai.
Taigi tegul Standartiniai čia,
Typedef struct mazgas, ir mazgas. Taip, gerai.
Taigi, ką mes ketiname nori mūsų mazgo laukai?
[Studentų] Žiniasklaida ir tada du patarimų?
>> Žiniasklaida vertė, dvi rodykles? Kaip aš rašau patarimų?
[Studentų] struct. >> Turėčiau padidinti. Taip, kad Struct mazgas * paliko,
ir Struct mazgas * teisus.
Ir atminkite diskusiją nuo paskutinio karto,
, kad tai neturi jokios prasmės, tai neturi jokios prasmės,
tai neturi prasmės.
Jums reikia viską, ką siekiant apibrėžti šį rekursinis struct.
Gerai, kad ką mūsų medis atrodys.
Jei mes padarėme Trójkowy medį, tada mazgas gali atrodyti B1, B2, struct mazgas * B3,
kur b yra filialas - Tiesą sakant, aš daugiau girdėjau, tai Kairėn, Vidurys, teisę, bet whatever.
Mes rūpi tik dvejetainis, todėl kairę, į dešinę.
"Dabar paskelbti pasaulinį mazgas * kintamąjį iš medžio šaknų".
Taigi mes neketiname to daryti.
Tam, kad, kad viskas šiek tiek sunkesnis ir apibendrintas,
mes ne pasaulio mazgas kintamąjį.
Vietoj to, pagrindinis bus paskelbti visus mūsų mazgas dalykų,
, o tai reiškia, kad žemiau, kai mes pradedame veikia
mūsų Contains funkcija ir mūsų įterpti funkciją,
vietoj mūsų sudėtį įeina veikia tik naudojant šį pasaulinį mazgas kintamasis,
mes ketiname kaip argumentas medį, kad mes norime jį apdoroti.
Atsižvelgdama pasaulinį kintamąjį buvo manoma, kad būtų lengviau.
Mes ketiname padaryti ką sunkiau.
Dabar užtrukti minutę ar dvi, tiesiog daryti tai dalykas rūšiuoti,
kai viduje pagrindinis norite sukurti šį medį, ir kad visi jūs norite daryti.
Išbandykite šį medį ir pastatyti savo pagrindinės funkcijos.
>> Gerai. Taigi jums nereikia net buvo pastatyta The Tree visą kelią dar.
Tačiau bet kas, ką aš galėtų atsigriebti
parodyti, kaip galima būtų pradėti statyti tokį medį?
[Studentų] Kažkieno trankosi, bando išeiti.
[Bowden] Kiekvienas patogiai su savo medžio statybos?
[Studentų] Žinoma. Tai nebuvo padaryta. >> Tai gerai. Mes galime tiesiog pabaigti
oh, galite jį išsaugoti? Valio.
Taigi čia mes turime - O, aš šiek tiek nukirto.
Aš Mastelis?
Padidinti vaizdą, spauskite slinkties klavišą. >> Turiu klausimą. >> Taip?
[Studentų] Kai apibrėžti struct, yra dalykų, pavyzdžiui, inicijuoti, kad nieko?
[Bowden] L. >> Gerai. Todėl jūs turite inicijuoti
[Bowden] L. Kai jūs nustatote, arba kai paskelbti struct
ji nėra inicializuoti pagal nutylėjimą, tai tiesiog patinka, jei pareiškiate, int.
Tai lygiai tas pats. Tai kaip kiekvieną iš savo atskirų laukų
gali turėti šiukšlių vertę. >> Ir tai galima nustatyti ar paskelbti struct
tokiu būdu, kad ji nenori inicijuoti juos?
[Bowden] Taip. Taigi, nuoroda iniciacijos sintaksė
atrodys -
Yra du būdai, kaip mes galime tai padaryti. Manau, kad turėtume sudaryti
įsitikinti, kad Apsukite metalinis garsas, taip pat tai daro.
Argumentų tam, kad ateina į struct,
jūs įtraukėte kaip argumentų viduje šių klamrami tvarka.
Taigi, jei norite inicijuoti iki 9, o į kairę, yra niekinis ir tada dešiniuoju yra niekinis,
jis turėtų būti 9, null, null.
Alternatyva yra, ir redaktorius nemėgsta šią sintaksę,
ir jis mano, kad aš noriu naują bloką,
tačiau alternatyva yra kažkas panašaus -
čia, aš įdėti jį į naują eilutę.
Galite tiksliai pasakyti, nepamenu tikslaus sintaksę.
Todėl jūs galite aiškiai nurodo jų pavadinimą, ir pasakyti,
C arba. Vertė = 9, kairėje = ​​NULL.
Spėju, kad šie veiksmai turi būti kableliais.
Dešinę = NULL, todėl tokiu būdu jūs neturite
tikrųjų reikia žinoti struct tvarka,
ir kai jūs skaitote šį, tai daug aiškus
apie tai, kas vertė yra inicializuoti.
>> Tai atsitinka, kad vienas iš dalykų, kad -
taip, kad didžioji dalis, C + + yra C supersets
Galite imtis C kodą, perkelti jį į C + +, ir tai turėtų sudaryti.
Tai yra vienas iš dalykų, kad C + + nepalaiko, todėl žmonės linkę to nedaryti.
Aš nežinau, jei tai yra vienintelė priežastis, kodėl žmonės linkę to nedaryti,
tačiau tuo atveju, kai man reikia jį naudoti, reikia dirbti su C + + ir todėl aš negalėjo naudoti šią.
Kitas kažką, kad pavyzdys neveikia su C + +
malloc grįžta "void *," techniškai
, bet jūs galite tiesiog pasakyti, char * x = malloc whatever,
ir jis bus automatiškai būti įmestam į char *.
Kad automatinis dauguma neatsitinka C + +.
Kad nebūtų sudaryti, ir jūs aiškiai reikia pasakyti,
char *, malloc, nesvarbu, mesti jį į char *.
Nėra daug dalykų, kad C ir C + + gali nesutarti dėl
tačiau jie yra du.
Taigi mes eiti su šia sintakse.
Bet net jei mes ne eiti su ta sintaksė
tai, kas gali būti negerai?
[Studentų] Man nereikia dereference jį? >> Taip.
Atminkite, kad rodyklė turi implicitini dereference,
ir todėl, kai mes tik susijusius su struct
mes norite naudoti. gauti lauko vidaus struct.
Ir tik laiko mes naudojame rodyklę yra, kai mes norime daryti -
gerai, rodyklė yra lygiavertis
tai, ką ji reikštų, jei aš rodyklę.
Visi rodyklė reiškia, dereference tai dabar aš esu ne struct, ir aš galiu gauti lauką.
Arba gauti lauką tiesiogiai ar dereference ir gauti lauką -
Manau, tai turėtų būti vertė.
Bet čia aš susiduriame tik su, o ne rodyklių į struct struct,
ir todėl aš negaliu naudoti rodyklę.
Bet šis dalykas rūšiuoti, mes galime padaryti visų mazgų.
O, Dieve.
Tai 6, 7 ir 3.
Tada mes galime sukurti mūsų medžio šakas, mes galime turėti 7 -
mes galime, ar tai kairysis turėtų atkreipti dėmesį į 3.
Taigi, kaip tai padaryti?
[Studentai, nesuprantamas] >> Yeah. Adresą iš node3,
ir jei jūs neturite adreso, tada jis tiesiog nebūtų surinkti.
Bet atsiminkite, kad tai yra rodykles į kitą mazgų.
Teisė turėtų atkreipti iki 9,
ir 3 turėtų atkreipti dešinėje iki 6.
Manau, kad tai yra visas rinkinys. Visos pastabos ar klausimai?
[Studentas, nesuprantamas] šaknis bus 7.
Mes galime tik pasakyti mazgas * ptr =
arba šaknis, = & node7.
>> Mūsų tikslais, mes ketiname būti susijusios su įdėklu,
todėl mes ketiname norite parašyti funkciją įterpti į šį dvejetainis medis
ir įterpti neišvengiamai ketinate skambinti malloc sukurti naują šio medžio mazgą.
Taigi viskas vyksta gauti purvinas su tuo, kad kai kurie mazgai
Šiuo metu kamino
ir kiti mazgai yra ketina baigti krūvos, kai mes įdėkite juos.
Tai yra visiškai teisingas, bet tik todėl,
mes galime tai padaryti kamino
yra todėl, kad tai nenatūralu pavyzdys, kad mes žinome,
medis turėtų būti sukonstruoti taip, 7, 3, 6, 9.
Jei mes neturėjome, tada mes būtume neturi malloc į pirmąją vietą.
Kaip matysime šiek tiek vėliau, mes turėtume malloc'ing.
Dabar tai visiškai pagrįsta įdėti į steką,
bet galime tai pakeisti į malloc įgyvendinimo.
Taigi, kiekvienas iš jų yra dabar ketina būti kažkas panašaus
mazgas * node9 = malloc (sizeof (mazgas)).
Ir dabar mes ketiname turi padaryti mūsų atvykimo.
jei (== NULL node9) - Aš nenorėjau, kad
Atgal 1, tada mes galime padaryti node9-> nes dabar rodyklė,
vertė = 6, node9> left = NULL,
node9-> right = NULL,
ir mes ketiname daryti, kad kiekvieno iš šių mazgų.
Taigi vietoj to, tegul jį viduje atskirame funkcijos.
Tegul jį vadiname mazgas * build_node
ir tai yra šiek tiek panašus į API, mes pateikiame Hafmano kodavimas.
Mes suteikiame Jums inicijavimo priemonės funkcijas medžio
deconstructor "funkcijos" tų medžių ir miškų.
>> Taigi čia mes ketiname turėti inicijavimo priemonės funkciją
tiesiog statyti už mus mazgas.
Ir tai vyksta atrodo beveik lygiai taip pat kaip tai.
Ir aš net būti tingus, o ne pakeisti kintamojo pavadinimą,
nors node9 jokios prasmės nebėra.
O, aš manau, node9 vertė neturėjo būti 6.
Dabar galime grįžti node9.
Ir čia mes grąžina NULL.
Kiekvienas susitarti dėl to Build-A-mazgo funkciją?
Taigi dabar mes galime tiesiog paskambinkite, kad sukurti bet su tam tikros ribos, null Pointeriai mazgas.
Dabar mes galime skambinti, kad mes galime padaryti mazgas * node9 = build_node (9).
Ir darykime. . .
6, 3, 7, 6, 3, 7.
Ir dabar mes norime sukurti tuos pačius nurodymus,
išskyrus dabar viskas jau patarimų
todėl nebereikia adresą.
Gerai. Taigi, kas yra paskutinis dalykas, kurį noriu padaryti,?
Yra klaidų nebus, kad aš ne daryti.
Ką statyti mazgas grįžti?
[Studentas, nesuprantamas] >> Taip. Jei malloc nepavyko, jis bus grąžina NULL.
Taigi, aš ruošiuosi tingiai tai nuleisk ją čia, o ne padaryti už kiekvieną sąlygą.
Jei (node9 == NULL, arba - dar paprasčiau,
tai atitinka tik jei ne node9.
Taigi jei ne node9, ar ne node6, ar ne node3, ar ne node7, grįžkite 1.
Gal reikėtų spausdinti malloc nepavyko, ar kažkas.
[Studentų] Ar klaidinga lygus nulis taip pat?
[Bowden] Bet nulinė vertė yra klaidinga.
Taigi null yra nulinė vertė.
Nulis yra nulinė vertė. False yra nulinė vertė.
Bet koks - gana daug tik 2 nulines vertes yra niekinis ir lygus nuliui,
klaidinga yra tik maišos apibrėžiamas kaip lygus nuliui.
Tai taip pat taikoma, jei mes paskelbti pasaulinį kintamąjį.
Jei mes turėjo mazgas * šaknis čia,
tada - malonus dalykas, apie globalių kintamųjų, kad jie visada turi pradinę vertę.
Tai nėra tiesa funkcijų, kaip viduje iš čia,
jei mes turime, pavyzdžiui, mazgas * arba mazgas x.
Mes neturime jokio supratimo ką x.value, x.whatever
ar mes galime juos atsispausdinti ir jie gali būti savavališkai.
Tai nėra tiesa globalių kintamųjų.
Taigi mazgas šaknų mazgas x.
Pagal nutylėjimą, viskas, kas pasaulio, jei ne aiškiai inicijuoti tam tikrą vertę,
turi nulinę vertę kaip jo vertės.
Taigi čia, mazgas * šaknis, mes ne tiesiogiai inicijuoti jį nieko,
todėl jos numatytoji reikšmė bus niekinis, kuri yra nulinė vertė patarimų.
Numatytoji vertė x reiškia, kad x.value yra lygi nuliui,
, x.left yra niekinis, ir yra niekinis x.right.
Taigi, kadangi tai yra struct, visi struct srityse bus nulines vertes.
Mums nereikia naudoti, kad čia, nors.
[Studentų] structs yra kitoks nei kitų kintamųjų, ir kiti kintamieji
šiukšlių vertės; tai yra nuliai?
[Bowden] ir kitas vertes, taip pat. Taigi, X, X bus lygi nuliui.
Jei ji yra pasaulinio pobūdžio, ji pradinę vertę. >> Gerai.
[Bowden] Bet pradinė vertė jums davė, arba nulis.
Manau, kad rūpinasi visa tai.
>> Gerai. Taigi kai kitą klausimo dalis iš esmės klausia,
"Dabar mes norime parašyti funkciją, vadinamą yra
su bool prototipas yra int vertę. "
Mes neketiname daryti, bool yra int vertę.
Mūsų prototipas atrodys
bool yra (int vertę.
Ir tada mes taip pat ketiname perduoti jį į medį
kad ji turėtų būti patikrinti, pamatyti, jei ji turi tą vertę.
Taigi mazgas * medis). Gerai.
Ir tada mes galime skambinti kažką panašaus,
ir galbūt mes norite printf ar kažką.
Sudėtyje yra 6, mūsų šaknų.
Tai turėtų grąžinti vieną ar tikrosios,
o yra 5 šaknis turėtų grįžti klaidinga.
Taigi imtis antra tai įgyvendinti.
Jūs galite tai padaryti arba keletą kartų arba rekursyviai.
Gražus dalykas, apie tai, kaip mes Nustatykite, yra tai, kad
jis skolina pati į mūsų rekursinis tirpalu daug lengviau
kaip pasaulio kintamųjų būdas.
Nes jei mes tiesiog yra int vertę, tada mes turime jokių recursing žemyn subtrees būdu.
Mes turėtume turėti atskirą pagalbininkas funkciją, kad recurses mus subtrees.
Bet kadangi mes pakeitėme ji galėtų imtis medį kaip argumentą,
kurią jis turėtų visada buvo pirmoje vietoje,
dabar mes galime šabl lengviau.
Taigi pasikartojantis arba rekursinis mes pereiti tiek,
bet mes pamatysime, kad rekursinių galų gale buvo gana lengva.
Gerai. Ar kas nors turi ką mes galime dirbti su?
>> [Studentų] Turiu kartotinis sprendimas. >> Viskas gerai, kartojamas.
Gerai, tai gerai atrodo.
Taigi, nori vaikščioti mus per tai?
[Studentų] Žinoma. Taigi, aš temp kintamąjį gauti pirmąjį mazgą medžio.
Ir tada aš tiesiog Kilpinės per, o temperatūra nėra lygi null
taip, o dar į medį, I guess.
Ir jei reikšmė yra lygi vertės, kad temperatūra yra nukreipta į
tada ji grąžina šią vertę.
Priešingu atveju, jis pasitikrina, jei tai dešinėje arba kairėje pusėje.
Jei jūs kada nors gauti situaciją, kai ne daugiau medžių,
tada ji grąžina - išeinant kilpą ir False.
[Bowden] Gerai. Taip, kad atrodo gerai.
Kiekvienas turi jokių pastabų dėl nieko?
Aš neturiu korektiškumo komentarus.
Vienas dalykas, mes galime padaryti, tai vaikinas.
O, jis ketina eiti šiek tiek ilgais,.
Aš nustatyti, kad iki. Gerai.
>> Kiekvienas turi prisiminti, kaip trijų komponentų veikia.
Ten tikrai buvo viktorinos praeityje
, kad suteikti Jums su trijų komponentų pluoštų operatoriaus funkciją,
ir pasakyti, išversti, kažką daryti, kad nenaudoja trinariu.
Taigi tai yra labai dažnas atvejis, kai aš norėčiau galvoti naudoti trijų komponentų,
kur, jei kai sąlyga nustatyti kintamąjį į kažką
dar tą patį kintamąjį į ką nors kita.
, Kad kažkas, kad labai dažnai šis dalykas rūšiuoti gali būti transformuota į
kur nustatyti, kad kintamąjį - arba gerai, ar tai tiesa? Tada tai kitas.
[Studentų] Pirmasis yra, jei tiesa, tiesa?
[Bowden] Taip. Būdas, aš visada skaityti, temperatūra lygi reikšmę didesnę nei temp vertės,
tada tai kitas. Užduoti klausimą.
Ar jis didesnis? Tada atlikite pirmas dalykas. Kita padaryti Antras dalykas.
Aš beveik visada - dvitaškis, aš tiesiog, mano galva, aš perskaičiau, kaip kitur.
>> Ar kas nors turite rekursinį sprendimą?
Gerai. Tai vienas, mes ketiname - tai jau gali būti didelis,
bet mes ketiname padaryti dar geriau.
Tai yra gana daug pats tiksliai idėja.
Tai tiesiog, gerai, jūs norite paaiškinti?
[Studentų] Žinoma. Taigi mes įsitikinkite, kad medis IS NOT NULL 1.
nes jei medis yra niekinis, jis ketina grįžti klaidinga, nes mums nepavyko rasti jį.
Ir jei dar yra medis, mes einame į - mes pirmą kartą patikrinti, ar vertė yra dabartinė mazgas.
Grąžina true jei jis yra, ir jei ne mes šabl kairę arba į dešinę.
Ar tai garso tinkamas? >> Mm-hmm. (Susitarimas)
Taigi, pastebėsite, kad tai beveik struktūriškai labai panaši į Pakartotinai tirpalu.
Tai tiesiog, kad vietoj recursing, mes turėjome while cikle.
Ir bazė atveju, kai medis nėra lygi null
buvo sąlyga, pagal kurią mes įsiplieskė while cikle.
Jie labai panašūs. Bet mes ketiname imtis dar vieną žingsnį.
Dabar, mes čia tą patį.
Pranešimas mes grįžti tą patį šių eilučių,
išskyrus vienas argumentas yra skirtingos.
Taigi, mes ketiname padaryti, kad į trinariu.
Aš paspauskite parinktį kažką, ir ji padarė simbolį. Gerai.
Taigi mes ketiname grįžti yra ta.
Tai vis į kelias eilutes, gerai, Mastelis tai.
Paprastai, kaip stiliaus dalykas, aš ne manau, daug žmonių
įdėti po rodyklės erdvę, bet aš manau, jei esate nuosekli, tai gerai.
Jei vertė yra mažesnė nei medžio vertę, mes norime šabl ant medžio kairėje,
dar norime recurse nuo medžio teise.
Kad buvo padaryti tai atrodo mažesnis vienas žingsnis.
Antras žingsnis tai atrodo mažesnis -
mes galime atskirti keletą eilučių.
Gerai. Todėl atrodo mažesni dviejų etapų yra čia,
grąžinimo vertė yra lygi medžio vertę, ar yra whatever.
>> Tai yra svarbus dalykas.
Aš nesu įsitikinęs, jei jis sakė, kad tai aiškiai klasėje,
bet tai vadinama trumpojo jungimo vertinimas.
Čia yra idėja vertė == medis vertė.
Jei tai tiesa, tada tai yra tiesa, ir mes norime, kad "arba" kad visa, kas čia.
Taigi, net galvoti apie ką čia,
kas yra visa išraiška nesiruošia grįžti?
[Studentų] Tikroji? >> Taip, nes tiesa nieko,
su niekuo or'd - ar tiesa or'd yra nebūtinai tiesa.
Taigi, kuo greičiau, kaip matome sugrįžimo vertę = medis vertės,
mes tiesiog ketina grįžti tiesa.
Net ketina recurse toliau yra žemyn linija.
Mes galime imtis vieną žingsnį toliau.
Grįžti medis nėra lygi null Ir visa tai.
Jis padarė tai vienos eilutės funkcija.
Tai yra trumpojo jungimo vertinimo pavyzdys.
Bet dabar tai pati idėja -
vietoj - taigi, jei medis, nėra lygi null - arba gerai,
jei medis nėra vienodas null, kuris atvejis yra blogas,
jei medis yra lygus nuliui, tada pirmoji sąlyga bus klaidingas.
Taigi klaidinga anded, su nieko bus, ką?
[Studentų] klaidinga. >> Taip. Tai kita pusė trumpojo jungimo vertinimo,
kur jei medis nėra lygus NULL, tada mes nesiruošia net eiti
arba jei medis nėra vienodas null, tada mes ne ketinate daryti vertę == medis vertės.
Mes tik ketina nedelsiant gražins false.
, Kuris yra svarbus, nes jei jis to nepadarė trumpojo jungimo ir įvertinimas,
tada, jei medis ar vienodą null ši antroji sąlyga ketina seg kaltės,
nes medis-> vertė dereferencing null.
Taigi tai, kad. Tai gali padaryti - pereiti vieną kartą per.
Tai yra labai dažnas dalykas, taip pat, ne šį vieną eilutę su šiuo,
bet tai sąlygomis dažnas dalykas, o gal ir ne čia,
bet jei (medis! = NULL, ir medis-> value == vertė), daryti ką.
Tai labai dažna būklė, kai užuot
padalyti į dvi IF, kur, pavyzdžiui, yra medis null?
Gerai, tai nėra lygus nuliui, taigi dabar yra medis vertė yra lygi vertės? Tai padaryti.
Vietoj to, ši sąlyga, tai niekada seg kaltės
, nes tai bus pertrauka, jei tai atsitiks, yra niekinis.
Na, manau, jei jūsų medis yra visiškai neteisingas rodyklė, ji gali dar seg kaltės,
tačiau jis negali seg kaltės, jei medis yra niekinis.
Jei ji buvo nulis, tai būtų galima nutraukti, prieš jūs kada nors dereferenced žymiklį į pirmąją vietą.
[Studentų] Ar Tai vadinama tingus vertinimas?
>> [Bowden] Lazy vertinimas yra atskiras dalykas.
Tingus vertinimas yra daugiau, kaip jūs paklausti, kurių vertė,
Jūs klausiate, apskaičiuoti vertę, rūšis, tačiau jums nereikia iš karto.
Taigi, kol jūs iš tikrųjų reikia, tai nėra vertinamas.
Tai ne visai tas pats, bet Hafmano pset
ji sako, kad mes "tingiai" rašyti.
Priežastis mes tai padarysime, nes mes iš tikrųjų buferinė Rašyti
mes nenorime rašyti atskirus bitai vienu metu,
arba atskirų baitų vienu metu, mes, o ne norite gauti baitų riekė.
Tada, kai mes turime baitų riekė, tada mes rašyti jį.
Nors jūs paprašykite rašyti ir fwrite ir fread padaryti tos pačios rūšies dalykas.
Jie buferio jūsų skaito ir rašo.
Net jei jūs paprašykite jį rašyti iš karto, tai tikriausiai nebus.
Ir jūs negalite būti tikri, kad viskas bus parašyta
kol skambinate hfclose ar kokia ji yra,
tada sako, gerai, aš uždaryti savo failą,
tai reiškia, kad aš geriau rašyti viską, ką esu dar nėra parašyta.
Ji nereikia rašyti viską iš
tol, kol yra uždaryti failą, ir tada jis turi.
Taigi, tai tik ką tingus - jis laukia, kol jis turi įvykti.
Tai - imtis 51 ir jums eiti į jį išsamiau,
nes OCaml ir viskas 51, viskas yra rekursija.
Yra ne kartotinis sprendimus, iš esmės.
Viskas yra rekursija ir tingus vertinimas
bus svarbu daug aplinkybių
kur, jei tu ne tingiai įvertinti, tai reikštų -
Pavyzdys yra srautai, kurie yra be galo ilgas.
Teoriškai jūs galite galvoti kaip 1-2-3-4-5-6-7 srauto iš natūralių skaičių
Taip tingiai įvertino viskas yra gerai.
Jei aš sakau, kad aš noriu dešimties skaičių, tada aš gali įvertinti iki dešimtosios skaičiaus.
Jei aš noriu šimtąjį skaičių, tada aš gali įvertinti šimtąjį skaičių.
Be tingus vertinimo, tada jis vyksta pabandyti įvertinti visus numerius iš karto.
Jūs vertinti be galo daug skaičių, ir tai yra tiesiog neįmanoma.
Taigi yra daug aplinkybių, kai tingus vertinimas
yra tiesiog būtina gauti dalykų dirbti.
>> Dabar mes norime parašyti informacinį lapelį, kur įterpti bus
taip pat keičiasi jos apibrėžime.
Taigi dabar tai bool įterpti (int vertė).
Mes ketiname pakeisti, kad bool įdėklu (int vertė, mazgas * medis).
Mes iš tikrųjų ketiname pakeisti, kad dar kartą šiek tiek, mes suprasti, kodėl.
Ir tegul perkelti build_node, tik jo gi,
, įdėkite, kad mes neturime rašyti funkcijos prototipas.
Kuris yra užuomina, kad jūs ketinate naudoti build_node įdėkle.
Gerai. Imtis, kad minutę.
Manau, kad išgelbėjo peržiūrėti, jei norite ištraukti,
ar bent jau, aš dabar.
Norėjau šiek tiek pertraukos galvoti apie įdėklu logika,
jei tu negali galvoti apie tai.
Iš esmės, jūs tik kada nors bus įstatykite lapų.
, Pavyzdžiui, jei aš įterpti 1, tada aš neišvengiamai bus įterpiant 1 -
Aš pakeisti juoda - I'll įterpiant 1 čia.
Arba, jeigu aš įterpti 4, aš noriu būti čia įterpiant 4.
Todėl nesvarbu, ką jūs darote, jūs ketinate būti lapo įterpti.
Viskas, ką jums reikia padaryti, yra pakartoti medį, kol gausite į mazgą
kad turėtų būti tėvų mazgas, naujas mazgas tėvų,
ir tada pakeisti savo kairę arba į dešinę žymeklį, priklausomai nuo to, ar
tai didesnis arba mažesnis nei dabartinis mazgas.
Pakeisti, kad žymiklį, kad atkreipti dėmesį į savo naujas mazgas.
Taigi pakartoti medį, kad lapų tašką į naują mazgas.
Taip pat pagalvokite apie tai, kodėl draudžia situacijos tipą prieš,
kur aš pastatė dvejetainis medis, kur ji buvo teisinga,
jei jūs tik pažvelgė į vieno mazgo,
bet 9 buvo jei pakartota visą kelią į kairę nuo 7.
Taip, kad neįmanoma šiame scenarijuje, nes -
galvoti apie įstatykite 9 arba kažką labai iš pirmo mazgo,
Aš ruošiuosi žr. 7 ir aš dabar einu į dešinę.
Todėl nesvarbu, ką man daryti, jei aš ketina lapo įterpti,
ir lapų, naudojant atitinkamą algoritmą,
tai bus neįmanoma, man 9 įterpti į kairę nuo 7
nes kuo greičiau aš paspauskite 7 Aš ruošiuosi eiti į dešinę.
Ar kas nors turi kažką pradėti?
[Studentų] darau. >> Žinoma.
[Studentų, nesuprantamas]
[Other studentas, neįskaitomai]
[Bowden] Tai vertinama. Gerai. Noriu paaiškinti?
>> [Student] Kadangi mes žinome, kad buvo įterpiant
naujus mazgus iš medžio,
Aš Kilpinės keletą kartų per medžio
kol aš mazgas, kad atkreipė dėmesį į nulis.
Ir tada aš nusprendžiau įdėti jį arba dešinėje arba kairėje pusėje
naudojasi šia teise, kintamuosius; jis man pasakė, kur įdėti.
Ir tada, iš esmės, aš tiesiog padarė, kad paskutinis -
kad temp mazgas naujas mazgas, kad ji buvo sukurti,
kairėje pusėje ar dešinėje pusėje, priklausomai nuo to, kas vertė teisė.
Galiausiai, aš nustačiau naują mazgas vertę savo bandymų vertės.
[Bowden] Gerai, kad aš matau čia vieną problemą.
Tai, pavyzdžiui, 95%, kaip ten.
Vienas klausimas, kad aš matau, gerai, ar kas nors kitas pamatyti problemą?
Kas yra aplinkybė, pagal kurią jie išeiti iš kilpos?
[Studentų] Jei temperatūra yra niekinis? >> Taip. Taigi, kaip jums išeiti iš kilpos, jei temperatūra yra niekinis.
Bet ką aš čia?
Aš dereference temperatūra, kuri yra neišvengiamai null.
Taigi, kitas dalykas, ką jums reikia padaryti yra ne tik stebėti, kol temperatūra yra niekinis,
norite sekti iš tėvų visą laiką.
Mes taip pat norime mazgas * tėvų, aš manau, mes galime laikyti, kad netekusiais iš pradžių.
Teks keistą elgesį iš medžio šaknų,
bet mes gauti, kad.
Jei vertė yra didesnė nei whatever, tada temp = temp teisus.
Tačiau prieš tai, kad, tėvų = temp.
Ar tėvai visada vyksta į vienodą temp? Yra tai, kad šiuo atveju?
Jei temperatūra nėra lygus nuliui, tada aš ruošiuosi judėti žemyn, nesvarbu, ką,
mazgas, kurių temperatūra yra patronuojanti.
Taigi patronuojančios įmonės bus temp, ir tada aš perkelti temp žemyn.
Dabar temperatūra yra nulis, bet iš tėvų yra niekinis dalykas, kad tėvų.
Taip žemai čia, aš nenoriu nustatyti lygi 1.
Taigi, aš persikėlė į dešinę, todėl, jei dešinę = 1,
ir aš manau, jūs taip pat norite padaryti, -
jei jums judėti į kairę, norite nustatyti lygi 0.
Ar kitur, jei jūs kada nors perkelti į dešinę.
Kad teisė = 0. Jei dešinėje = ​​1,
dabar mes norime, kad patronuojančiai tinkamą rodyklė newnode
dar norime, kad patronuojančiai kairę rodyklę newnode.
Turite klausimų apie tai?
Gerai. Taigi tai yra būdas, kuriuo mes - gerai, iš tikrųjų, o ne tai padaryti,
mes 1/2, tikimasi jums naudoti build_node.
Ir tada, jei newnode lygus nuliui, gražins false.
Tai, kad. Dabar, tai yra tai, ką mes tikėjomės jums reikia padaryti.
>> Tai yra, ką darbuotojai sprendimai padaryti.
Nesutinku su "teisingu" būdu vyksta apie tai
bet tai yra visiškai gerai, ir ji veiks.
Vienas dalykas, kad šiek tiek keista dabar
jei medis prasideda netekusiais, mes pereiname neapibrėžta medžio.
Manau, tai priklauso nuo to, kaip jūs nustatote perduoti neapibrėžta medžio elgesį.
Manyčiau, kad jei pereisite neapibrėžta medžio,
įterpiant vertę į neapibrėžta medis
tiesiog reikia grįžti į medį, kur tik vertė yra tai, kad vienas mazgas.
Žmonės sutinka su tuo? Tu gali, jei norite,
, jei pereisite neapibrėžta medžio
ir norite įterpti reikšmės į, gražins false.
Tai iki jums nustatyti, kad.
Norėdami tai padaryti pirmas dalykas, kurį pasakiau ir tada -
Na, jūs ketinate turėti sunku daryti, kad, nes
būtų lengviau, jei mes turėjome pasaulio žymeklį į dalykas,
bet mes neturime, todėl jei medis yra niekinis, ten nieko mes galime padaryti apie tai.
Mes galime tik grįžti klaidinga.
Taigi, aš ruošiuosi pakeisti įdėklą.
Techniškai galima tiesiog pakeisti šią teisę,
kaip tai iteravimu užkliuvę,
bet aš ruošiuosi pakeisti įdėklą mazgas ** medį.
Dvigulės patarimų.
Ką tai reiškia?
Užuot užsiėmusi nuorodomis mazgams,
ką aš ruošiuosi būti manipuliuoti tai rodyklė.
Aš ruošiuosi manipuliuoti šį žymeklį.
Aš ruošiuosi būti tiesiogiai manipuliuoti patarimų.
Tai logiška, nes, pagalvokite, žemyn -
Na, dabar tai rodo null.
Ką aš noriu padaryti, tai manipuliuoti šį žymiklį į tašką NOT NULL.
Aš noriu, kad mano naujas mazgas.
Jei aš tiesiog sekti mano rodykles patarimų,
tada man nereikia sekti patronuojančios rodyklė.
Aš galiu tik stebėti, norėdami pamatyti, jei yra rodyklė, nukreipta į null,
ir jei rodyklė yra nukreipta į nulis,
jį pakeisti, kad rodytų į mazgą, aš noriu.
Ir aš galiu jį pakeisti,, nes turiu žymeklį į žymeklis.
Pažiūrėkime, tai dabar.
Jūs iš tikrųjų galite tai padaryti rekursyviai gana lengvai.
Ar mes norime tai padaryti?
Taip, mes darome.
>> Pažiūrėkime, jį rekursyviai.
Pirma, kas yra mūsų bazė atveju bus?
Beveik visada mūsų bazinį scenarijų, bet iš tikrųjų, tai yra rūšies sudėtinga.
Pirmasis ko pirma, jei (medis == NULL)
Manau, mes tiesiog ketina grįžti klaidinga.
Tai skiriasi nuo savo medį null.
Tai yra rodyklė į savo šaknų rodyklė null
, o tai reiškia, kad jūsų šakninis rodyklė neegzistuoja.
Tiek žemyn čia, jei aš
mazgas * - tegul tiesiog pakartotinai tai.
Mazgas * root = NULL,
ir tada aš ruošiuosi skambinti intarpą, daro kažką panašaus,
įterpti į & Root 4.
Taigi, ir šaknis, jei šaknis yra mazgas *
& Root bus mazgas **.
Tai galioja. Šiuo atveju, medis, čia,
medis nėra lygus nuliui, arba įrašyti.
Čia. Medis yra ne null; * medis yra niekinis, kuris yra gerai
nes jei * medis yra niekinis, tada galiu manipuliuoti
atkreipti dėmesį į ką aš noriu atkreipti.
Bet jei medis yra nulis, tai reiškia, kad aš tiesiog atėjo čia ir sakė null.
Tai neturi prasmės. Aš negaliu nieko daryti su tuo.
Jei medis yra niekinis, gražins false.
Taigi, aš iš esmės jau pasakė tai, ką mūsų nekilnojamojo bazinį scenarijų.
Ir kas yra tai, kad bus?
[Studentų, nesuprantamas]
[Bowden] Taip. Taigi, jei (* medis == NULL).
Tai susiję su tuo atveju, čia
kur, jei mano raudona rodyklė rodyklė aš sutelktas į
taip, kaip aš sutelktas į šio rodyklė, dabar aš orientuota į šio rodyklė.
Dabar aš orientuota į šio rodyklė.
Taigi, jei mano raudona rodyklė, kuri yra mano mazgas **
kada nors - jei *, mano raudona rodyklė, kada null,
tai reiškia, kad aš esu tuo atveju, jei aš dėmesio žymeklis, kuris nurodo
tai rodyklę, kad priklauso lapo.
Noriu pakeisti šį žymiklį į mano naujas mazgas.
Grįžti čia.
Mano newnode bus tik mazgas * n = build_node (vertė)
tada n jei n = NULL, gražins false.
Kita mes norime pakeisti tai, kas yra rodyklė, nukreipta į
dabar atkreipti dėmesį į mūsų naujai pastatytas mazgas.
Mes iš tikrųjų galite tai padaryti čia.
Užuot pasakęs n, mes sakome, * = jei * medžio medis.
Visi supranta, kad? , Kad sprendžiant rodykles į rodykles,
mes galime pakeisti tuščių patarimų, atkreipti ką norime nukreipkite jas į.
Štai mūsų bazinį scenarijų.
>> Dabar mūsų pasikartojimo, arba mūsų rekursija,
bus labai panašus į visų kitų recursions, mes buvo padaryti.
Mes ketiname norite įterpti vertę,
ir dabar aš ruošiuosi naudoti trinariu vėl, bet kas yra mūsų sąlyga bus?
Kas tai mes ieškome nuspręsti, ar mes norime eiti į kairę arba į dešinę?
Darykime jį į atskirus žingsnius.
If (vertė <), ką?
[Studentų] The Tree vertė?
[Bowden] Taigi, nepamirškite, kad aš šiuo metu -
[Studentai, nesuprantami]
[Bowden] Taip, kad čia, tarkim, kad tai žalia rodyklė
tai kokiu medžiu šiuo metu yra pavyzdys, yra rodyklė į šio rodyklė.
Taigi, tai reiškia, kad aš esu rodyklė rodyklė į 3.
Dereference du kartus skambėjo gerai.
Tai, ką aš - kaip aš galiu padaryti, kad?
[Studentų] Dereference vieną kartą, ir tada atlikite arrow, kad taip?
[Bowden] (* medis) yra dereference vieną kartą, -> vertė
ketina duoti man mazgo, kad aš netiesiogiai nukreipta į vertę.
, Kad aš taip pat galite rašyti ** tree.value, jei norite, kad.
Bet veikia.
Jei taip yra šiuo atveju, tada aš noriu skambinti įdėkite vertę.
Ir kas mano atnaujinama mazgas ** bus?
Aš noriu eiti į kairę, todėl ** tree.left bus mano kairę.
Ir aš noriu žymiklį į tą daiktą
taip, kad jei kairę baigiasi NULL pointeris,
Galiu keisti, kad rodytų į mano naujas mazgas.
>> Ir kitu atveju gali būti labai panašūs.
Tegul realiai padaryti, kad mano trinariu dabar.
Įterpti vertę jei vertė <(** medis). Vertė.
Tai mes norime atnaujinti savo ** į kairę,
dar norime atnaujinti savo ** į dešinę.
[Studentų] Ar tai gauti žymiklį į žymeklis?
[Bowden] Atminkite, kad - ** tree.right mazgas žvaigždė.
[Studentas, nesuprantamas] >> Taip.
** Tree.right kaip šio rodyklė ar kažką.
Taigi, atsižvelgiant rodyklę į, kuris suteikia man, ką aš noriu
žymeklis, kad vaikinas.
[Studentų] Nepavyko mes einame vėl, kodėl mes naudojame dvi rodykles?
[Bowden] Taip. Taigi - ne, jūs galite, ir kad sprendimas prieš
buvo būdas tai daryti be padaryti du nurodymus.
Jums reikia, kad būtų galima suprasti naudojant dvi rodykles,
ir tai yra švaresnis sprendimas.
Taip pat pastebėsite, kad kas atsitiks, jei mano medis -
kas atsitiks, jei mano šaknys buvo niekinis? Kas atsitiks, jei aš šiuo atveju čia?
Taigi mazgas * šaknis = NULL, įdėkite į & Root 4.
Kas yra Root bus po to?
[Studentas, nesuprantamas] >> Taip.
Šaknis vertė bus 4.
Šaknis į kairę bus niekinis, šaknis teisė bus niekinis.
Tais atvejais, kai mes ne išlaikyti šaknis adresą,
mes negalime pakeisti šaknis.
Tais atvejais, kai medis - šaknys buvo niekinis,
mes tiesiog turėjo grįžti klaidinga. Nėra nieko mes galime padaryti.
Mes negalime įterpti į tuščią medžio mazgas.
Bet dabar mes galime, mes tiesiog padaryti tuščią medį į vieną mazgas medžio.
Kuris paprastai yra numatomas būdas, kad jis turėjo dirbti.
>> Be to, tai yra žymiai trumpesnis nei
taip pat sekti iš tėvų, ir todėl jūs pakartoti visą kelią.
Dabar aš turiu savo tėvų, ir aš tiesiog savo patronuojančiai tinkamą žymeklį į whatever.
Vietoj to, jei mes padarėme tai keletą kartų, tai būčiau tą pačią idėją su while cikle.
Bet vietoj to, kad spręsti su mano tėvų rodyklė,
o mano dabartinis rodyklė būtų dalykas
kad aš tiesiogiai modifikavimo, kad rodytų į mano naujas mazgas.
Aš neturiu spręsti, nesvarbu ar tai būtų nukreipta į kairę.
Aš neturiu spręsti, nesvarbu ar tai būtų nukreipta į dešinę.
Tai tiesiog viskas, ką šis žymeklis, aš ruošiuosi nustatyti, kad jis mano naujas mazgas.
Visi supranta, kaip tai veikia?
Jei ne, kodėl mes norime tai padaryti tokiu būdu,
bet bent jau, kad tai, kaip išspręsti veikia?
[Studentų] Kur mes grįžti tiesa?
[Bowden] Tai turbūt čia.
Jei mes teisingai įdėkite jį, grąžinti tiesa.
Kitur, žemyn čia mes einame, kad nori grįžti, nepriklausomai nuo įterpti grąžą.
>> Ir kas ypatingo apie šį rekursinis funkcija?
Uodega rekursinis, taip ilgai, kaip mes sudaryti su kai kuriais optimizavimo,
bus pripažinti, kad ir jūs niekada gauti nepakeliama,
net jei mūsų medis aukštis 10.000 arba 10 mln.
[Studentų, nesuprantamas]
[Bowden] Manau, kad ji tai daro ne Dash - arba optimizavimas lygis
reikalingas uodegos rekursijos būti pripažintos.
Manau, kad ji pripažįsta - Persijos įlankos bendradarbiavimo tarybos ir Apsukite metalinis garsas
taip pat turi skirtingas reikšmes už jų optimizavimo lygį.
Noriu pasakyti, tai DashO 2, įsitikinkite, kad jis bus pripažinti uodegos rekursija.
Bet mes - galite statyti kaip Fibonocci pavyzdžiui, ar kažką.
Tai nėra lengva išbandyti su tai, nes sunku statyti
dvejetainis medis, tai toks didelis.
Bet taip, manau, kad tai DashO 2, kad
jei sudaryti DashO 2, tai atrodys uodegos rekursijos
ir optimizuoti, kad iš
Grįžkime - įdėkite pažodžiui paskutinis dalykas, kurį jis turi.
Grįžkime įdėklu per čia
kur mes ketiname padaryti tą pačią idėją.
Jis vis dar turite negalės visiškai rankena trūkumus
kai šaknys yra niekinis, ar praeities įrašas yra niekinis,
bet vietoj susijusius su patronuojančios žymeklį,
leisti taikyti tą pačią logiką palaikymo rodykles rodykles.
Jei čia mes išlaikyti mūsų mazgas ** dab,
ir mums nereikia sekti šiuo nebėra
bet mazgas ** dab = & medžiu.
Ir dabar mūsų while cikle bus o * dab nėra lygi null.
Nereikia sekti tėvų nebėra.
Nereikia sekti į kairę ir į dešinę.
Ir aš jums jį vadiname temp, nes mes jau naudojate temp.
Gerai. Taigi, jei (vertė> * temp),
tada & (* temp) -> į dešinę
dar temp = & (* temp) -> paliko.
Ir dabar, šiuo metu, po šio while cikle,
Aš tik tai padaryti, nes gal tai lengviau galvoti apie keletą kartų nei rekursyviai,
bet po šio while cikle,
* Temp tai rodyklė, mes norime pakeisti.
>> Kol mes turėjo tėvų, ir mes norėjome pakeisti į kairę iš tėvų arba vieno iš tėvų teisę,
tačiau, jei norime pakeisti patronuojančiai teisę,
* temperatūra yra tėvų teisė, ir mes galime jį pakeisti tiesiogiai.
Tiek žemyn čia, mes galime padaryti * temp = newnode, ir viskas.
Taigi pranešimo, mes padarėme tai buvo imti eilutes kodo.
Tam, kad sekti visose tėvų, kad yra papildomų pastangų.
Čia, jei mes tiesiog sekti, kad rodyklė prie rodyklė
ir net jei mes norėjome atsikratyti visų šių klamrami dabar,
kad ji atrodo trumpesnis.
Tai dabar yra lygiai toks pats sprendimas,
bet mažiau eilučių kodo.
Kai pradėsite Pripažindama, kad tai tinkamas sprendimas,
jis taip pat lengviau samprotauti apie nei kaip, gerai,
kodėl aš turiu šią vėliavą int teise?
Ką tai reiškia? Oh, tai, reiškiantis, kad
kiekvieną kartą, kai aš einu į dešinę, reikia nustatyti,
dar, jei aš einu į kairę, aš jį nustatyti į nulinę padėtį.
Čia, aš ne apie tai, kad priežastis, tai tiesiog lengviau galvoti apie.
Turite klausimų?
[Studentas, nesuprantamas] >> Taip.
Gerai, kad per pastaruosius tiek
Manau, greitai ir lengvai funkcija, mes galime padaryti,
let's - kartu, manau, išbandyti ir rašyti yra funkcija
nerūpi, ar tai yra dvejetainis paieškos medis.
Tai yra funkcija turėtų grįžti tiesa
jei bet kurios šios bendrosios dvejetainis medis yra vertė, mes ieškome.
Taigi, tegul pirmas tai padaryti rekursyviai ir tada mes tai padaryti keletą kartų.
Mes iš tikrųjų galite tiesiog padaryti jį kartu, nes tai bus tikrai trumpas.
>> Kas yra "Mano bazinį scenarijų bus?
[Studentų, nesuprantamas]
[] Taigi, jei (Bowden medis == NULL), kas tada?
[Studentų] Grįžti klaidinga.
[Bowden] kita, gerai, aš ne reikia kitame.
Jei buvo mano kiti bazinį scenarijų.
[Studentų] Tree vertė? >> Taip.
Taigi, jei (medis-> value == vertė.
Atkreipkite dėmesį, mes grįžome į mazgas *, o ne mazgas ** s?
Yra niekada nereikės naudoti mazgas **
nes mes nesame iš dalies keičiantis patarimų.
Mes tiesiog einant.
Jei tai atsitiks, tada mes norime return true.
Kita, ką norite feed vaikus.
Taigi, mes galime samprotauti apie tai, ar viskas į kairę yra mažiau
ir viskas į dešinę yra didesnis.
Taigi, kas yra mūsų sąlyga bus čia - arba, ką mes ketiname daryti?
[Studentas, nesuprantamas] >> Taip.
Grąža yra (vertė, medis-> kairėje)
arba jame yra (vertė, medis-> dešinėje). Ir viskas.
Ir pastebėsite, kad yra kai trumpojo jungimo vertinimą,
kur, jei atsitiktų rasti kairiajame medžio vertę,
mes niekada nereikės pažvelgti į dešinėje medžio.
Štai visos funkcijos.
Dabar padarykime tai keletą kartų,
bus mažiau gražus.
Mes priimsime įprastą pradžią mazgas * dab = medžio.
Nors (dab! = NULL).
Greitai ketiname pamatyti problemą.
Jei dab - čia, jei mes kada nors išeiti iš šio,
tada mes paleisti iš ką pažvelgti, todėl grįžti klaidinga.
If (dab-> == vertė) return true.
Taigi dabar, mes esame toje pačioje vietoje -
mes nežinome, ar mes norime eiti į kairę arba į dešinę.
Taip savavališkai, galime tiesiog eiti į kairę.
Aš akivaizdžiai paleisti į problemą, kai aš visiškai apleistame viską, -
Aš tik kada nors patikrinti medį kairėje pusėje.
Aš niekada patikrinti nieko, kad yra teisė, vaikas nieko.
Kaip man išspręsti šią problemą?
[Studentų] Jūs turite sekti kairę ir į dešinę kamino.
[Bowden] Taip. Taigi padarykime
struct sąrašas, mazgas * n, tada mazgas ** toliau?
Manau, kad puikiai veikia.
Mes norime eiti per kairėje arba let's - čia.
Struct sąrašas yra =, jis bus pradėti
iš šiuo struct sąrašą.
* Sąrašas = NULL. Taip, kad bus mūsų susieta sąrašas
subtrees, kad mes praleista daugiau.
Mes ketiname feed paliko dabar,
bet kadangi mes neišvengiamai reikia grįžti į dešinę,
Mes ketiname išlaikyti tinkamą pusę, viduje mūsų struct sąrašą.
Tada mes turime new_list arba struct
struct sąrašas * new_list = malloc (sizeof (sąrašas)).
Aš ruošiuosi ignoruoti klaida tikrinant, ar, bet turėtumėte patikrinti, pamatyti, jei ji null.
New_list mazgas, jis ketina atkreipti dėmesį į
oh, tai kodėl aš norėjau jį čia. Jis ketina atkreipti dėmesį į antrą struct sąrašą.
Štai tik tai, kaip jis susijęs sąrašai veiktų.
Tai yra tas pats kaip int susiję sąrašas
, išskyrus tuos atvejus, mes tiesiog pakeisti int mazgas *.
Tai lygiai tas pats.
Taigi new_list, vertė mūsų new_list mazgo,
bus dab-> į dešinę.
Mūsų new_list vertė-> Kitas bus mūsų pradinis sąrašas
ir tada mes ketiname atnaujinti savo sąrašą, kad rodytų į new_list.
>> Dabar mes turime kažkokią būdu pašalintas dalykus,
, kaip mes kertamos visą kairę šaka.
Dabar mes turime traukti dalykų iš jo,
kaip dab yra niekinis, mes nenorime tiesiog gražins false.
Mes norime, kad dabar traukti už mūsų naują sąrašą.
Patogus būdas tai padaryti - gerai, iš tikrųjų, yra daug būdų, kaip tai daryti.
Kas nors turite pasiūlymą?
Kur aš tai padaryti, arba kaip aš turėčiau tai padaryti?
Turime tik keletą minučių, tačiau kokių nors pasiūlymų?
Vietoj to, kad vienas iš būdų, o ne mūsų būklę, o
tai, ką mes šiuo metu ieško NOT NULL,
vietoj to, mes ketiname ir toliau eiti, kol mūsų sąrašas pati yra niekinis.
Taigi, jei mūsų sąrašą galų gale buvo niekinis,
tada mes paleisti iš dalykų, ieškoti, ieškoti per.
Bet tai reiškia, kad mūsų sąraše yra tik pirmas dalykas, bus pirmą mazgas.
Pats pirmas dalykas bus - mes nebereikia matyti, kad.
Taigi sąrašas-> n bus mūsų medžio.
sąrašas-> Kitas bus niekinis.
Ir dabar, o sąrašas nėra lygi null.
Dab ketina traukti ką nors iš mūsų sąraše.
Taigi dab ketina vienodo sąrašo> N.
Ir tada sąrašas vienodo sąrašo> N arba sąrašo> Toliau.
Taigi, jei dab vertė lygi vertę.
Dabar mes galime įdėti mūsų teisę žymeklį ir mūsų kairę rodyklę
tol, kol jie nėra lygus nuliui.
Žemyn čia, aš manau, mes turėtume padaryti, kad į pirmąją vietą.
If (dab-> teisus! = NULL)
tada mes ketiname įterpti tą mazgą į mūsų sąrašą.
If (dab-> į kairę), tai yra šiek tiek papildomo darbo, bet tai gerai.
If (dab-> kairę! = NULL),
ir mes ketiname įterpti į kairę į mūsų susijusi sąrašą,
ir kad turėtų būti ji.
Mes pakartoti - tol, kol mes turime ką nors į mūsų sąrašą,
mes turime kitą mazgą pažvelgti.
Taigi, mes ieškome tuo mazgas,
mes iš anksto mūsų sąrašą į kitą.
Jei tai mazgas yra vertė, mes ieškome, mes galime grįžti tiesa.
Kita įterpti tiek savo kairę ir į dešinę subtrees
tol, kol jie nėra lygus nuliui, į mūsų sąrašą
kad mes neišvengiamai pereiti per juos.
Taigi, jei jie nebuvo niekiniai,
jei mūsų šaknis rodyklė atkreipė dėmesį į du dalykus.
tada pirma, ką mes iškedentas, todėl mūsų sąraše baigiasi yra niekinis.
Ir tada mes įdėti du dalykus atgal, todėl dabar mūsų sąraše yra 2 dydžio.
Tada mes kilpa atgal į viršų ir mes tiesiog ketina traukti,
tarkim, kairįjį pelės žymeklį mūsų šakninis mazgas.
Ir kad bus tiesiog laikyti vyksta, mes galų gale kilpų virš visko.
>> Atkreipkite dėmesį, kad tai buvo gerokai sudėtingesnis
rekursinis tirpale.
Ir aš sakė kelis kartus
kad rekursinis sprendimas paprastai turi daug bendro su pasikartojantis sprendimą.
Čia būtent tai rekursinis sprendimas daro.
Vienintelis pakeitimas yra tai, kad, užuot netiesiogiai naudojant krūvą, programa kamino,
jūsų būdas sekti ką mazgai, jūs vis dar reikia aplankyti
dabar jūs turite aiškiai susietą sąrašą.
Abiem atvejais jūs sekti ką mazgas dar reikia lankėsi.
Rekursinis atveju tai tik lengviau, nes kamino
įgyvendinamos programos kamino.
Atkreipkite dėmesį, kad tai susijęs sąrašas, tai kamino.
Ką mes tiesiog įdėti į steką
iš karto, ką mes ketiname nutempti pluoštą ir aplankyti kitas.
Mes laiko, bet kokių nors klausimų?
[Studentų, nesuprantamas]
[Bowden] Taip. Taigi, jei mes turime susietą sąrašą,
dabartinis vyksta šis vaikinas,
ir dabar mes tiesiog plečiant mūsų susietą sąrašą sutelkti dėmesį į šį vaikiną.
Mes kirsti tos linijos per susietą sąrašą.
Ir tada aš manau, kad mes turėtų išlaisvinti mūsų susietą sąrašą ir kita
kartą prieš grįžtant true arba false, turime
pakartoti per Susietos sąrašą ir visada žemyn čia, manau,
jei mes dab teisė nėra lygus, įtraukite ją, todėl dabar mes norime išlaisvinti
dab nes, gerai, tai mes visiškai pamiršti apie šį sąrašą? Taip.
Todėl tai, ką mes norime padaryti čia.
Kur yra žymeklis?
Dab buvo tada - mes norime, struct sąrašą * 10 lygu sąrašą šalia.
Nemokama sąrašą, sąrašas = temp.
Ir tuo atveju, kai mes grįžtame tiesa, mes reikia pakartoti
per likusį mūsų susietą sąrašą nutekamosios dalykų.
Gražus dalykas, apie grįžtamojo sprendimas atlaisvinti dalykus
tiesiog reiškia, Popping factorings off kamino, kuris įvyks jums.
Taigi, mes perėjome nuo ko nors, kad kaip 3 eilutes sunkiai manote apie kodą
kažką, kad yra žymiai daug daugiau sunku-manote-apie eilučių kodo.
Ar turite klausimų?
Gerai. Mes geri. Bye!
[CS50.TV]