[Powered by Google Translate] [Дел 7: поудобно] [Роб Бауден] [Универзитетот Харвард] [Ова е CS50] [CS50.TV] Во ред. Значи како што реков во мојот мејл, ова ќе биде бинарни дрво-интензивна секција. Но таму не се толку многу прашања. Така ние ќе да се обиде да извлече секое прашање и да си одат на болни детали на сите од најдобрите начини на вршење на работите. Значи правото на почетокот, ние одиме преку примерок цртежи на бинарни дрва и работи. Значи тука "Запомнете дека бинарно дрво има јазли слични на оние на поврзани листа, освен наместо на еден покажувач постојат две: една за 'дете' на левата и друга за десниот 'дете' ". Па бинарно дрво е исто како поврзаните листа, освен struct се случува да имаат два покажувачи. Има трикомпонентните дрвја, кои ќе имаат три совети, постојат n-арен дрвја, кои само имаат генерички покажувачот што потоа треба да Примерок да биде доволно голем да имаат доволно совети за сите можни деца. Значи бинарно дрво само се случува да имаат константен број на две. Ако сакате, можете да даде поврзана листа како унарни дрво, но јас не верувам дека некој го нарекува тоа. "Нацртајте кутии-и-стрелките дијаграм на бинарно дрво јазол содржат омилен број на Nate, 7, каде што секое дете покажувачот е нула. " Значи iPad режим. Тоа ќе биде прилично јасна. Ние сме само ќе треба еден јазол, јас ќе го нацрта тоа како плоштад. И јас ќе подготви вредностите тука. Па вредност ќе одат во тука, а потоа надолу тука ќе имаме лево покажувачот на левата и десната покажувачот на правото. И тоа е многу, па конвенција да го наречеме лево и десно, на покажувачот имиња. И двете од овие се случува да биде нула. Тоа само ќе биде нула, и дека само ќе биде нула. Во ред. Па назад до тука. "Со поврзана листа, имавме само за чување покажувач на првиот јазол во листата со цел да се потсетиме на целиот поврзани листа, или целата листа. Исто така, со дрвја, ние само треба да се складира покажувачот на еден јазол, со цел да се потсетиме на целото дрво. Овој јазол е calle на "root" на дрвото. Изгради врз вашата дијаграм од пред или нацрта нова како што имате кутии-и-стрели опис на бинарно дрво со вредноста 7, тогаш 3 во лево, од 9 на десната страна, а потоа 6 на правото на 3. " Ајде да видиме дали можам да се сетам на сите дека во мојата глава. Значи ова ќе биде нашиот корен се тука. Ќе имаме некои покажувачот некаде, нешто што ќе го наречеме корен, и тоа укажува на овој човек. Сега да се направи нов јазол, она што го имаме, 3 на левата? Значи нов јазол со 3, и првично укажува нула. Јас само ќе се стави Н Сега ние сакаме да се направи кои одат лево од 7. Значи ние се промени овој покажувач до сега укажуваат на овој човек. И тоа го правиме истото. Сакаме 9 овде кој првично само вели нула. Ние ќе се промени овој покажувач, точка 9, и сега сакаме да се стави 6 до правото на 3. Па затоа се случува да - направи 6. И тоа човек ќе точка таму. Во ред. Значи тоа е се што бара од нас да се направи. Сега ајде да одиме над некои терминологија. Ние веќе разговаравме за тоа како коренот на дрвото е топ-повеќето јазол во стеблото. Оној кој содржи 7. Јазли на дното на дрвото се нарекуваат лисја. Било кој јазол кој само има нула како негови деца е лист. Па можно е, ако нашиот бинарно дрво е само еден јазол, дека дрвото е лист, и тоа е тоа. "На 'висина" на дрво е бројот на хмел треба да се направи да се добие од врвот на листот. " Ние ќе се влезе, во вториот, разликата помеѓу избалансиран и неизбалансирани бинарни дрва, но сега за сега, вкупната висина на ова дрво Јас би рекол е 3, иако, ако се брои бројот на хмел што треба да се направи со цел да се дојде до 9, тогаш тоа е навистина само височина од 2. Токму сега тоа е неурамнотежен бинарно дрво, но ние ќе зборуваме за рамномерен кога станува да бидат релевантни. Па сега можеме да зборуваме за јазли во дрво, во смисла во однос на други јазли во дрво. Така, сега имаме родители, деца, браќа и сестри, татковци, и потомци. Тие се прилично здрав разум, што тие значат. Ако ве прашаме - тоа е родители. Значи она што е родител на 3? [Студентите] 7. >> Да. Родителот е само ќе биде она што укажува на вас. Тогаш што се децата од 7? [Студентите] 3 и 9. >> Да. Забележете дека "децата" буквално значи децата, па 6 не ќе се применуваат, бидејќи тоа е како внуците. Но, тогаш ако одиме потомци, така што се потомци на 7? [Студентите] 3, 6 и 9. >> Да. Потомци на root јазол ќе биде сè во дрво, освен можеби на root јазол себе, ако не сакате да се разгледа што потомок. И, конечно, предци, па тоа е спротивна насока. Значи она што се предците на 6? [Студентите] 3 и 7. >> Да. 9 не е вклучен. Тоа е само директен лоза назад кон коренот ќе биде вашиот предци. "Велиме дека бинарно дрво е" нареди "ако за секој јазол во стеблото, сите негови потомци на левата имаат помала вредност и сите оние на десната имаат поголема вредност. На пример, дрвото погоре е наредено, но тоа не е единствениот можен нареди аранжман. " Пред да дојдеме до тоа, нареди бинарно дрво е исто така познат како бинарен за пребарување дрво. Еве ние се случи да биде нарекувајќи нареди бинарно дрво, но јас никогаш не слушнале тоа се нарекува нареди бинарно дрво пред, и на квиз, се многу поголеми шанси да се стави бинарни пребарување дрво. Тие се едно и исто, а тоа е важно да се признае разликата помеѓу бинарно дрво и бинарни пребарување дрво. А бинарно дрво е само едно дрво, што укажува на две работи. Секој јазол укажува на две работи. Нема размислување за вредностите што укажува. Значи се допаѓа овде, бидејќи тоа е бинарна пребарување дрво, ние знаеме дека ако ние одиме лево од 7, тогаш сите вредности што ние можеби може да достигне со одење лево од 7 треба да биде помал од 7. Забележете дека сите вредности помалку од 7 се 3 и 6. Тоа се сите лево од 7. Ако одиме на правото на 7, што треба да биде поголема од 7, па 9 е на правото на 7, па ние сме добри. Ова не е случај за бинарно дрво, за редовно бинарно дрво ние само може да имаат 3 на врвот, 7 лево, 9 лево од 7; нема нарачување на вредности она. Сега, ние всушност не ќе го направат тоа затоа што тоа е мачна и непотребни, но "се обиде да привлече што поголем број нареди дрвја како што може да мислам на користење на броевите 7, 3, 9 и 6. Колку различни аранжмани постојат? Што е висината на секој од нив? " Ние ќе направиме неколку, но главната идеја е, ова е во никој случај не единствена претстава на бинарно дрво содржат овие вредности. Сите ние треба е некои бинарно дрво што содржи 7, 3, 6 и 9. Друга можна валидна ќе биде коренот е 3, оди на лево и тоа е 6, оди на лево и тоа е 7, оди на лево и тоа е 9. Тоа е совршено валидна бинарни пребарување дрво. Тоа не е многу корисна, бидејќи тоа е само како поврзани листа и сите на овие совети се само нула. Но, тоа е валидна дрво. Да? [Студентски] Не вредностите треба да биде поголема од десната? Или ова - >> Овие мислев да одам на друг начин. Постои, исто така - да, ајде да се префрлат тоа. 9, 7, 6, 3. Добар улов. Таа се уште има да ги почитуваат она што бинарно дрво пребарување треба да прави. Па сè до левата треба да биде помал од која било дадена јазол. Ние може само да се движат, да речеме, оваа 6 и го ставив тука. Не, не можеме. Зошто го правите тоа? Да се ​​направи - тука е 6, тука е 7, 6 поени 3. Ова е сеуште валидна бинарни пребарување дрво. Што не е во ред ако јас - да видиме дали можам да излезе со аранжман. Да, во ред. Значи она што е во ред со оваа дрво? Претпоставувам дека веќе ви даде знак дека нешто не е во ред со него. Зошто го правите тоа? Во ред. Ова изгледа разумно. Ако ги погледнеме во секој јазол, како 7, а потоа на лево од 7 е 3. Значи имаме 3, нешто на правото на 3 е 6. И ако се погледне на 6, нешто на правото на 6 е 9. Значи, зошто е ова не е валидна бинарни пребарување дрво? [Студентите] 9 се уште е лево од 7. >> Да. Тоа мора да биде вистина дека сите вредности што веројатно може да се постигне со одење лево од 7 помалку од 7. Ако одиме лево од 7, ние дојдеме до 3, а ние се уште може да стигне до 6, ние се уште може да стигне до 9, но со тоа што помина помалку од 7, ние не треба да бидат способни да се стигне до бројот што е поголема од 7. Значи ова не е валиден бинарни пребарување дрво. Брат ми всушност имаше интервју прашање тоа беше во основа, само кодот од нешто да се провери дали дрво е бинарно пребарување дрво, и така првото нешто што го направив беше само да провериш ако лево и десно се точни, а потоа iterate таму долу. Но, не само да го направите тоа, вие мора да ги пратите на фактот дека сега дека сум отишол лево од 7, сè во овој поддрво смее да биде помал од 7. Точниот алгоритам треба да ги пратите на границите дека вредностите веројатно може да падне внатре Ние не ќе оди преку сите нив. Има убава повторување однос, иако не сме добиле оние, или ние нема да добие на оние, дефинирање колку таму всушност се. Па така постојат 14 од нив. Идејата за тоа како ќе го направи тоа математички е како, можете да изберете било само еден да биде коренот јазол, а потоа, ако јас земам 7 да биде root јазол, тогаш постојат, да речеме, некои бројки кои можат да одат биде мојата лева јазол, и има некои бројки кои можат да бидат моето право јазол, но ако имам n вкупниот број, тогаш износот што може да оди на лево плус износот што може да оди на правото е n - 1. Па на останатите броеви, тие треба да бидат во можност да одат или на лево или на десно. Се чини тешко, ако го ставам 3 првиот потоа се мора да оди на лево, но ако го ставам 7, а потоа некои работи може да тргне на лево и некои работи може да тргне кон десно. И со '3 прв "мислев што може да оди на десно. Тоа е навистина, само треба да се размислува за тоа како, колку работите можат да одат на следното ниво на дрвото. И излегува да биде 14 или може да се подготви сите од нив, а потоа ќе добиете 14. Кога ќе се вратам овде, "Нареди бинарни дрва се излади, бидејќи може да се бара преку нив во многу сличен начин да се бараат преку подредени низа. Да го стори тоа, ние започнуваме во коренот и работа на патот надолу на дрвото кон лисја, проверка вредности секој јазол против вредностите што барате. Ако вредноста на тековната јазол е помала од вредноста што го барате, одите до правото дете јазол. Во спротивно, ќе отидете на левата дете јазол. Во одреден момент, можете или ќе се најде вредноста што го барате, или ќе наидат на нула, укажува на вредноста не е во дрво. " Морам да ја прецрта дрвото имавме порано, дека ќе се земе втора. Но, ние сакаме да се погледне нагоре дали 6, 10 и 1 се во дрво. Значи она што беше, 7, 9, 3, 6. Во ред. Бројките дека сакате да го гледам нагоре, ние сакаме да се погледне до 6. Како функционира овој алгоритам работа? Па, ние исто така имаат некои корен покажувачот на нашите дрво. И ние ќе оди до коренот и да каже, дали е ова вредност еднаква на вредноста ние сме во потрага по? Па ние сме во потрага по 6, па тоа не е еднаква. Значи ние Продолжувам да одам, и сега ние се каже, во ред, па 6 е помалку од 7. Дали тоа значи дека ние сакаме да одиме на лево, или сакаме да одиме на правото? [Студентски] Лево. >> Да. Тоа е значително полесен, сите што треба да направите е да се подготви еден можен јазол на дрво а потоа можете don't - наместо да се обидува да се мисли во вашата глава, океј, ако тоа е помалку, можам да одам на лево или оди на десно, само гледајќи во сликата, тоа е многу јасно дека морам да одам од лево ако овој јазол е поголема од вредноста што јас барам. А ти оди кон лево, сега сум во 3. Сакам да - 3 е помала од вредноста барам, што е 6. Значи одиме право, и сега заврши во 6, која е вредноста Јас барам, па враќање вистина. Следниот вредност Одам да се погледне за е 10. Во ред. Па 10, сега, се случува да - отсече тоа - ќе ги следи коренот. Сега, 10 ќе биде поголема од 7, па сакам да се погледне на десната страна. Одам да дојди, 10 ќе биде поголем од 9, па јас сум ќе сакате да се погледне на десната страна. Јас доаѓам овде, но овде сега сум на нула. Што да правам ако јас хит нула? [Студентски] Врати се лажни? >> Да. Јас не најде 10. 1 ќе биде речиси идентичен случај, освен тоа е само ќе треба да се превртува, наместо на гледање одредување на десната страна, ќе одам да се погледне надолу на левата страна. Сега мислам дека ние всушност го кодот. Еве каде - се отвори CS50 апаратот и да стигнете на вашиот пат таму, но може само така да го направи тоа во просторот. Тоа е веројатно идеално да го направи тоа во просторот, затоа што можат да работат во просторот. "Прво, ќе треба нов вид дефиниција за бинарно дрво јазол содржи int вредности. Користење на boilerplate typedef подолу, создаде нова дефиниција на тип за еден јазол во бинарно дрво. Ако ви се заглавени. . . "Бла, бла, бла. Океј. Значи, да се стави на boilerplate тука, typedef struct јазол, и куп. Да, во ред. Па што се области ние ќе сакаат во нашата јазол? [Студентски] инт а потоа две насоки? >> Инт вредност, два совети? Како можам да пишувам на совети? [Студентски] struct. >> Јас треба да зумирате внатре Да, така struct јазол * лево, и struct јазол * во право. И се сеќавам на дискусијата од последниот пат, дека тоа не прави никаква смисла, ова не прави никаква смисла, ова нема никаква смисла. Ви треба се таму со цел да се дефинира овој рекурзивен struct. Океј, па тоа е она што нашите дрво ќе изгледа. Ако ние не трикомпонентните дрво, а потоа еден јазол може да изгледа како Б1, Б2, struct јазол * Б3, каде што б е гранка - всушност, јас сум повеќе слушнав лево, средно, право, но сеедно. Ние само се грижат за бинарни, па десно, лево. "Сега се изјасни за глобалната јазол * променлива за коренот на дрвото". Па ние нема да го направат тоа. Со цел да се направат нештата малку потешко и повеќе генерализирана, ние нема да имаме глобална јазол променлива. Наместо тоа, во главниот ние ќе прогласи сите наши јазол работи, а тоа значи дека подолу, кога ќе почнат да оперираат нашите Содржи функција и нашите вметнете функција, наместо на нашите Содржи функционира само со користење на оваа глобална јазол променлива, ние ќе мора да се земе како аргумент на дрво кое сакаме да се процесира. Ја на глобалната променлива требаше да се направат работите полесно. Ние ќе се направат работите потешко. Сега, земи една минута или така само да се направи овој вид на работа, каде во внатрешноста на главниот сакате да ја креирате оваа дрво, и тоа е се што сакате да го направите. Обидете се и изградба на ова дрво во главната функција. Во ред. Така да дури и не мора да се гради дрвото целиот начин уште. Но секој има нешто што може да се повлече до да се покаже како еден би можела да започне изградба на таков дрво? [Студентски] Некој удира, обидувајќи се да излезат. [Бауден] Секој удобно со нивната дрво конструкција? [Студентски] Секако. Тоа не е направено. >> Тоа е во ред. Ние само може да се заврши - ох, можете да го зачувате? Ура. Значи тука имаме - ох, јас сум малку отсечен. Јас зумира? Зумирате, движете надвор. >> Имам едно прашање. >> Да? [Студентски] Кога ќе се дефинира структурата, се работи како иницијализиран на нешто? [Бауден] бр >> Океј. Значи вие ќе треба да се иницијализира - [Бауден] бр Кога ќе се дефинира, или кога ќе се изјасни за структурата, тоа не е иницијализиран по дифолт, тоа е исто како ако прогласи int. Тоа е токму истото. Тоа е како секој од своите индивидуални полиња може да има ѓубре вредност во неа. >> И тоа е можно да се дефинираат - или да прогласи struct на начин на кој тоа го прави нив ја иницијализирам? [Бауден] Да. Значи, кратенка иницијализација синтакса ќе изгледа како - Има два начини да го направите тоа. Мислам дека треба да го компајлирате да бидете сигурни ѕвекот, исто така, го прави ова. Редоследот на аргументи што доаѓа во структурата, ќе се стави како цел на аргументите во внатрешноста на овие големи загради. Значи, ако сакате да го иницијализирате до 9 и се остава да се ништовни и потоа десен биде нула, тоа ќе биде 9, нула, нула. Алтернативата е и уредник не му се допаѓа оваа синтакса, и мисли дека сакаат нов блок, но алтернативата е нешто како - тука, јас ќе ја ставам на нов ред. Вие експлицитно може да се каже, јас заборавам точната синтакса. Па можете експлицитно да им се обратиме со името, и да каже, . В, или. Вредност = 9. Лев = NULL. Јас сум Сомневајќи се овие треба да биде запирки. . Десно = NULL, па на овој начин не ви всушност треба да го знае редоследот на struct, и кога ќе ја читаш ова, тоа е многу поексплицитни за тоа што вредноста е се иницијализира да. Ова се случува да биде една од работите што - така, во најголем дел, C + + е superset на В Можете да ги преземат C код, се движи над неа, C + +, и тоа треба да се компајлира. Ова е една од работите што C + + не поддржува, па луѓето имаат тенденција да не го стори тоа. Јас не знам дали тоа е единствената причина поради која луѓето имаат тенденција да не го направи тоа, но случајот каде што е потребно да го користите потребни за работа со C + + и така не можев да го користите овој. Друг пример за нешто што не работи со C + + е како Примерок враќа "празнина *," технички, но може само да се каже char * x = Примерок што, и тој автоматски ќе биде фрлен во знак *. Тоа автоматски фрлија не се случи во C + +. Тоа не би ги собере, и експлицитно ќе треба да се каже char *, Примерок, што, за да го дадат на char *. Не постојат многу нешта кои C и C + + не се согласуваат за, но тие се две. Значи ќе одиме со оваа синтакса. Но, дури и ако ние не одиме со тој синтакса, она што е - може да биде во ред со тоа? [Студентски] Јас не треба да Dereference тоа? >> Да. Запомнете дека стрелката има имплицитна Dereference, и така кога ние сме само се занимаваат со структурата, ние сакаме да го користите. да се добие во областа внатрешноста на struct. И само тогаш користете стрелките е кога ќе сакате да го направите - добро, стрелката е еквивалентно на - тоа е она што би значело ако јас се користи стрела. Сите стрелка значи, Dereference тоа, сега сум на struct, и може да се добие оваа област. Или да добијат полето директно или Dereference и да добијат поле - Претпоставувам дека ова треба да биде вредност. Но, тука сум се занимаваат само со структурата, а не покажувач на struct, и затоа не можам да го користите стрелката. Но, овој вид на нешто што може да направи за сите јазли. О, Боже. Ова е 6, 7, и 3. Тогаш може да се постави гранките во нашата дрво, можеме да имаме 7 - Ние може да има, нејзината лева треба да укажуваат на 3. Па, како го правиме тоа? [Студентите, неразбирливо] >> Да. Адресата на node3, и ако не имаат адреса, тогаш тоа едноставно не би ги собере. Но, се сеќавам дека овие се покажувачи кон следниот јазли. Правото треба да укажуваат на 9, и 3 треба да укажуваат на правото на 6. Мислам дека ова е сите во собата. Било какви коментари или прашања? [Студент, неразбирливо] Коренот ќе биде 7. Ние само може да се каже јазол * кон меморија = или корен, = & node7. За нашите цели, ние ќе треба да се занимаваат со вметнете, па ние ќе сакате да се напише функција да се вметне во оваа бинарно дрво и вметнете неизбежно ќе се јавите Примерок да се создаде нов јазол за ова дрво. Па работите се случува да добиете неуредна со фактот дека некои јазли се во моментов на магацинот и други јазли се случува да се заокружи на грамада кога ги внесете. Ова е совршено валидни, но единствената причина ние сме во можност да го направите тоа на магацинот е затоа што тоа е како измислена пример дека знаеме дрвото треба да биде изграден како 7, 3, 6, 9. Ако ние не го имаат ова, тогаш не би требало да Примерок на прво место. Како што ќе видиме малку подоцна, ние треба да се malloc'ing. Токму сега тоа е совршено разумно да се стави на магацинот, но, ајде да го промените ова во Примерок имплементација. Така што секоја од овие сега ќе биде нешто како јазол * node9 = Примерок (sizeof (јазол)). И сега ние ќе треба да направите нашите чек. ако (node9 == NULL) - Не сакав тоа - врати 1, а потоа можеме да направиме node9-> затоа што сега тоа е покажувач, вредност = 6, node9-> лево = NULL, node9-> десно = NULL, и ние ќе мора да го стори тоа за секој од овие јазли. Така, наместо, да го стави во внатрешноста на посебна функција. Ајде да го наречеме јазол * build_node, и ова е донекаде сличен на API-јата ние обезбеди за Хафман кодирање. Ние ви даде initializer функции за дрво и deconstructor "функции" за оние дрвја и истото за шуми. Па еве ние ќе имаат initializer функција само да се изгради еден јазол за нас. И тоа се случува да се погледне доста точно се допаѓа ова. И јас сум дури и ќе се мрзливи и не го смени името на променливата, иако node9 не прави никаква смисла повеќе. О, претпоставувам вредност node9 не треба да се 6. Сега ние може да се врати node9. И тука ние треба да се врати нула. Секој согласуваат дека Build-A-јазол функција? Па сега ние само може да се јавите дека за да се изгради било кој јазол со одредена вредност и null покажувачи. Сега можеме да го наречеме тоа, ние може да се направи јазол * node9 = build_node (9). И нека направи. . . 6, 3, 7, 6, 3, 7. И сега ние сакаме да се постави истиот покажувачи, освен сега сè е веќе во однос на покажувачи па не треба адресата на. Во ред. Значи она што е последното нешто што сакате да го направите? Има грешка проверка дека јас не правам. Што значи да се изгради јазол возврат? [Студент, неразбирливо] >> Да. Ако Примерок не успеа, таа ќе се врати нула. Па јас одам да мрзеливо го спуштија тука наместо да прави услов за секоја од нив. Ако (node9 == NULL, или - уште поедноставно, ова е еквивалент на само ако не node9. Значи, ако не node9, или не node6, или не node3, или не node7, врати 1. Можеби и ние треба да се печати Примерок не успеа, или нешто. [Студентски] е лажна еднакви на нула, како? [Бауден] Секое нула вредност е false. Значи нула е нула вредност. Нула е нула вредност. Лажни е нула вредност. Секоја - доста само 2 нула вредности се ништовни и нула, лажни е само хаш дефинира како нула. Тоа важи и ако ние ја декларираат глобалната променлива. Ако ние не имаат јазол * корен се тука, тогаш - На убаво нешто за глобални променливи е дека тие секогаш имаат почетна вредност. Тоа не е точно на функции, како внатре од тука, ако имаме, како, јазол * или јазол х. Немаме поим што x.value, x.whatever, или би можеле да ги испечатите и тие би можеле да бидат произволни. Тоа не е точно на глобални променливи. Значи јазол корен или јазол х. По дифолт, сето она што е глобален, ако не е експлицитно иницијализиран на некои вредност, има нула вредност како неговата вредност. Па еве, јазол * корен, ние не се експлицитно да се иницијализира на ништо, па нејзината стандардна вредност ќе биде нула, кој е нула вредност на покажувачи. Почетната вредност на x се случува да значи дека x.value е нула, x.left е нула, и x.right е нула. Значи, бидејќи тоа е struct, сите полиња на struct ќе биде нула вредности. Ние не треба да го користат тоа тука, иако. [Студентски] На structs се различни од другите променливи, и други променливи се ѓубре вредности; овие се нули? [Бауден] Други вредности премногу. Значи во x, x ќе биде нула. Ако тоа е во глобалниот опсег, таа има почетна вредност. >> Океј. [Бауден] Или почетна вредност ќе му го даде или нула. Мислам дека се грижи за сето ова. Во ред. Значи следниот дел од прашањето прашува, "Сега ние сакаме да се напише функција наречена содржи со прототип на bool содржи int вредност. " Ние нема да го стори bool содржи int вредност. Нашите прототип ќе изгледа како bool содржи (int вредност. А потоа ние сме, исто така, ќе го помине на дрвото дека треба да се проверуваат да видат дали има таа вредност. Значи јазол * дрво). Во ред. И тогаш можеме да го наречеме со нешто како, можеби ќе сакате да printf или нешто. Содржи 6, нашиот корен. Дека треба да се врати еден, или точно, а содржи 5 корен треба да се врати лажни. Значи донесе вториот за спроведување на оваа. Можете да го направи тоа или iteratively или рекурзивно. На убаво нешто за начинот на кој ние го поставите работите е тоа што тоа е подложна на нашите рекурзивен решение е многу полесно од глобалниот-променлива начин не. Затоа што ако ние само треба содржи int вредност, тогаш ние немаме начин на recursing надолу subtrees. Ние ќе мора да имаат посебна помошна функција која recurses по subtrees за нас. Но, бидејќи ние се промени тоа да се земе од дрвото како аргумент, кои треба секогаш биле на прво место, Сега можеме да recurse полесно. Па итеративен или рекурзивен, ќе одиме над двата, но ќе видиме дека рекурзивен завршува се прилично лесно. Во ред. Дали некој има нешто што може да работи со? [Студентски] Имам итеративен решение. >> Добро, итеративен. Океј, ова изгледа добро. Значи, сакате да ни помогне преку неа? [Студентски] Секако. Па јас се постави температура променлива да се добие првиот јазол од дрвото. А потоа јас само looped преку додека температура не еднакви на нула, па додека уште беше во дрво, претпоставувам. И ако вредноста е еднаква на вредноста која температура е да се покажува, тогаш тоа се враќа на таа вредност. Инаку, се проверува дали е на десната страна или на левата страна. Ако некогаш добиете ситуација каде што не постои повеќе дрво, тогаш тоа се враќа - тоа излегува на јамка и се враќа false. [Бауден] Во ред. Така што се чини дека е добро. Секој имате било какви коментари на нешто? Јас немам точноста коментари на сите. Едно нешто можеме да направиме е овој човек. Ох, тоа се случува да се искачам малку longish. Јас ќе утврдат дека до. Во ред. Секој треба да се сеќавам како троичен работи. Постојат дефинитивно е квизови во минатото кои ви даде функција со троичен оператор, и да каже, се преведе ова, направи нешто што не користи троичен. Значи ова е многу чест случај за тоа кога јас не би помислил да се користи троичен, каде што, ако некои услови постави променлива на нешто, друг во собата истата променлива на нешто друго. Тоа е нешто што многу често може да се трансформира во овој вид на работа каде што ја постави таа променлива на оваа - или, добро, дали е ова вистина? Тогаш ова, друго ова. [Студентски] Првиот е ако е точно, нели? [Бауден] Да. Начинот на кој јас секогаш го прочитате е, Temp еднаква вредност поголема од temp вредност, тогаш ова, друго ова. Тоа е поставување на прашање. Е поголема? Потоа направи првото нешто. Друг го стори Втората работа. Јас скоро секогаш - на дебелото црево, јас само - во мојата глава, јас ги прочитав како друго. Дали некој има рекурзивен решение? Во ред. Оваа една ние ќе - тоа веќе може да биде голема, но ние ќе се направи тоа дури и подобро. Ова е прилично многу исти точно идеја. Тоа е само, добро, сакаш да се објасни? [Студентски] Секако. Па ние сме си сигурен дека дрвото не е NULL прво, бидејќи ако дрвото е нула, тогаш тоа нема да се врати лажни, бидејќи ние не го најде. И ако има уште едно дрво, ние одиме во - ние прво проверете дали вредноста е моменталниот јазол. Враќање вистина ако е така, и ако ние не recurse на лево или десно. Дали тоа звучи соодветно? >> ММ-hmm. (Договор) Значи забележите дека ова е речиси - структурно многу слични во повторната решение. Тоа е само дека наместо recursing, имавме додека јамка. И на база случај тука каде што дрво не еднакви нула беше услов под кој избувна на време јамка. Тие се многу слични. Но, ние ќе ја искористам оваа чекор понатаму. Сега, ние го прават истото тука. Забележете ние враќање на истото во двата од овие линии, освен за еден аргумент е поинаква. Така ние ќе да се направи тоа во троичен. Јас хит опција нешто, а тоа го направи симбол. Во ред. Па ние ќе се вратат ги содржи тој. Ова е да успеат да бидат повеќе линии, добро, zoomed во тоа. Обично, како стилска работа, јас не мислам дека многу луѓе стави празно место по стрела, но претпоставувам дека ако сте доследни, тоа е во ред. Ако вредноста е помала од дрво вредност, ние сакаме да recurse на дрво лево, друго сакаме да recurse на дрво право. Значи тоа беше еден чекор од правење на ова изгледа помала. Чекор два за изработка на овој изглед помали - можеме да ја одвоиме ова на повеќе линии. Во ред. Чекор два прави да изгледа помала е тука, па вратената вредност е еднаква на дрво вредност, или содржи сеедно. Ова е важна работа. Не сум сигурен дали тој рече дека тоа експлицитно во класа, но тоа се вика краток спој евалуација. Идејата тука е вредноста == дрво вредност. Ако тоа е точно, тогаш ова е точно, и ние сакаме да 'или' дека со она што е овде. Па дури и без размислување за она што е овде, она што е на целиот израз ќе се врати? [Студентски] вистина? >> Да, затоа што важи и за ништо, or'd - или точно or'd со нешто е секогаш точно. Па штом гледаме повратната вредност = дрво вредност, ние сме само ќе се врати вистина. Дури и не ќе recurse понатаму содржи одредување на линија. Ние можеме да ја искористам оваа чекор понатаму. Врати дрво не еднакви нула и сето ова. Тоа го направи една линија функција. Ова е исто така пример за краток спој евалуација. Но, сега тоа е истата идеја - наместо - па ако дрво не е еднаков на нула - или, добро, ако дрво прави еднакви на нула, што е лош случај, ако дрво е еднаква на нула, тогаш првиот услов ќе биде лажна. Значи лажни anded со ништо нема да биде она што? [Студентски] Лажни. >> Да. Ова е другата половина од краток спој евалуација, каде што ако дрво не еднакви нула, тогаш ние нема да одат дури и - или ако дрво прави еднакви нула, тогаш ние не се случува да се направи вредност == дрво вредност. Ние сме само ќе веднаш да се врати лажни. Што е важно, бидејќи ако тоа не предизвикувајте краток спој оцени, а потоа, ако дрво прави еднакви на нула, ова вториот услов ќе секунда грешка, бидејќи дрво> вредност се dereferencing нула. Значи тоа е тоа. Може да се направи ова - префрлат еднаш завршена. Ова е многу честа работа, исто така, не прави оваа линија со ова, но тоа е заедничка работа во услови, можеби токму тука, но ако (дрво! = NULL, и дрво-> вредноста == вредност), го направи она што. Ова е многу честа состојба, каде што наместо да се скрши тоа во две IFS, каде се допаѓа, е дрво нула? Океј, тоа не е нула, па сега е дрво вредност еднаква вредност? Го направите тоа. Наместо тоа, оваа состојба, ова никогаш не ќе секунда грешка поради тоа што ќе се пробие, ако тоа се случува да биде нула. Па, претпоставувам дека ако вашиот дрво е сосема валиден покажувач, може уште секунда грешка, но тоа не може секунда грешка ако дрво е нула. Ако тоа се ништовни, тоа ќе се пробие пред Дали некогаш сте dereferenced покажувачот на прво место. [Студентски] Дали е ова т.н. мрзливи оценка? [Бауден] Lazy оценување е посебна работа. Мрзливи оценување е повеќе како ве праша за вредност, Ве молиме да се пресмета вредноста, вид, но вие не треба веднаш. Значи додека вие всушност треба, тоа не се оценува. Ова не е иста работа, но во Хафман pset, таа вели дека ние "мрзеливо" пишува. Причината поради која го направите тоа е затоа што ние сме всушност визуелниот пишуваат - ние не сакаме да се напише индивидуалните битови во еден момент, или индивидуални бајти во еден момент, ние наместо да сакате да добиете парче од бајти. Потоа еднаш имаме парче на бајти, тогаш ние ќе го напише. И покрај тоа што тој побара да се напише - и запишување и fread го стори истото вид на работа. Тие тампон вашиот чита и пишува. И покрај тоа што го побара веднаш да пишува, тоа веројатно нема. И не можете да бидете сигурни дека работите се случува да бидат напишани додека ти се јавам hfclose или што и да е, кои потоа вели, добро, јас сум затворање мојот датотека, тоа значи дека е подобро да напишете сè што не го имаат напишано уште. Тоа не треба да се напише се надвор додека не се затворање на датотека, а потоа таа треба да. Значи тоа е само она што мрзливи - чека се додека не мора да се случи. Ова - се 51 и ќе оди во тоа во повеќе детали, бидејќи OCaml и се што е во 51, што е рекурзија. Нема итеративен решенија, во основа. Сè што е рекурзија, и мрзливи евалуација ќе биде важна за многу околности каде што, ако не мрзеливо оцени, тоа би значело - На пример е струи, кои се бескрајно долго. Во теорија, може да се мисли на природните броеви како поток од 1-2-3-4-5-6-7, Па мрзеливо оценуваат работите се во ред. Ако кажам сакам десеттиот број, тогаш може да се оцени до десеттиот број. Ако сакам стоти број, тогаш може да се оцени до стоти број. Без мрзливи евалуација, а потоа тоа ќе се обиде да се оцени сите броеви веднаш. Ти си оценување бесконечно многу броеви, и тоа не е само можно. Па така постојат многу околности каде мрзливи евалуација е само од суштинско значење за добивање на работите на работа. Сега ние сакаме да се напише вметнете каде вметнете ќе биде Слично менува во својата дефиниција. Па сега тоа е bool вметнете (int вредност). Ние ќе го промени тоа да bool вметнете (int вредност, јазол * дрво). Ние сме всушност ќе се смени тоа повторно во малку, ние ќе се види зошто. И ајде да се движат build_node, само за грижам за тоа, над вметнете па ние не треба да се напише функција прототип. Што е знак дека ви се случува да се користи build_node во вметнете. Во ред. Земете една минута за тоа. Мислам дека спаси ревизија ако сакате да се повлече од тоа, или, барем, јас не сега. Сакав мала пауза да се размислува за логиката на вметнете, ако не можете да мислам на тоа. Во суштина, ти само ќе бидеш вметнување на лисја. Како, ако вметнете 1, тогаш јас сум неизбежно ќе биде вметнување 1 - Ќе се смени во црно - I'll се вметнување 1 овде. Или ако вметнете 4, сакам да биде вметнување 4 овде. Значи без разлика што правиш, си оди за да се вметнување на листот. Се што треба да направите е да iterate одредување на дрво додека не стигнете до јазол што треба да биде родител на јазол, родител на нов јазол, а потоа го промени својот лево или десно покажувач, во зависност од тоа дали тоа е поголема или помала од сегашната јазол. Промена дека покажувачот да укаже на вашиот нов јазол. Значи iterate долу на дрвото, направи лист точка на новиот јазол. Исто така мислам за тоа зошто тој забранува тип на ситуација пред, каде што конструирал бинарно дрво каде што беше правилна ако само погледна еден јазол, но 9 беше лево од 7 ако потврди долу сите на патот. Така што е невозможно во ова сценарио, бидејќи - мислите за вметнување 9 или нешто; на самиот прв јазол, Одам да видам 7 и јас сум само ќе оди на десно. Значи без оглед што правам, ако сум вметнување со одење на лист, и на лист со помош на соодветен алгоритам, тоа ќе биде невозможно за мене да вметнете 9 лево од 7 бидејќи штом ќе го погоди 7 Одам да одат на десно. Дали некој има нешто да се започне со? [Студентски] правам. >> Секако. [Студент, неразбирливо] [Други студент, неразбирливо] [Бауден] Тоа е добредојдена. Во ред. Сакате да се објасни? [Студентски] Бидејќи знаеме дека сме биле вметнување нови јазли на крајот на дрвото, Јас looped преку дрво iteratively додека не стигнав до еден јазол, која посочи на нула. И тогаш решив да го стави или на десната страна или на левата страна користење на ова право променлива, таа ми кажа каде да го стави. И тогаш, во суштина, јас само го направи тоа минатата - дека Темп јазол точка на новиот јазол дека тоа е креирање, или на левата страна или од десната страна, во зависност од она што вредност право беше. Конечно, јас во собата на нов јазол вредност на вредноста на тестирање. [Бауден] Океј, па гледам едно прашање тука. Ова е како 95% од пат таму. На едно прашање што гледам, добро, дали некој друг се види ова прашање? Што е околноста под кои тие се пробие на јамка? [Студентски] Ако температура е нула? >> Да. Па, како да се пробие на јамка е ако Темп е нула. Но, што да правам тука? Јас Dereference Temp, што е неизбежно нула. Па друга работа што треба да направите не е само да ги пратите до температура е нула, сакате да ги пратите на родител на сите времиња. Ние исто така сакаме јазол * родител, претпоставувам дека ние може да ги задржи дека во нула во прв план. Ова се случува да имаат чудно однесување за коренот на дрвото, но ние ќе дојдеме до тоа. Ако вредноста е поголема од она што тогаш Темп = Темп право. Но, пред да го направите тоа, родител = Temp. Или родители секогаш ќе еднаков температура? Е дека случајот? Ако температура не е нула, тогаш јас ќе одам да се движат надолу, без разлика што, на јазол за која температура е родител. Значи родител ќе биде Temp, а потоа се движи температура надолу. Сега температура е нула, но родителот укажува на родител на нешто што е нула. Значи тука долу, не сакате да го поставите право е еднаква на 1. Па јас се пресели во право, па ако правото = 1, и претпоставувам дека исто така, сакаат да се направи - ако се преселите на лево, сакате да го поставите право еднаква на 0. Или на друго место, ако некогаш се движи кон десно. Значи десно = 0. Ако десно = 1, сега ние сакаме да се направи родител право покажувачот newnode, друго сакаме да се направи родител левата покажувачот newnode. Прашања за тоа? Во ред. Значи ова е начинот на кој ние - и, всушност, наместо тоа, ние половина очекува да користите build_node. А потоа ако newnode еднаква на нула, се врати лажни. Тоа е тоа. Сега, ова е она што го очекуваше да се направи. Тоа е она што на вработените решенија направи. Јас не се согласувам со ова како "право" начин на одење за тоа но ова е совршено во ред и тоа ќе работи. Едно нешто што е малку чудно во моментов е ако дрвото почнува како нула, ние помине во нула дрво. Претпоставувам дека тоа зависи од тоа како го дефинирате однесувањето на донесување на нула дрво. Јас би помислил дека ако помине во нула дрво, потоа вметнување на вредноста во нула дрво само треба да се врати на дрво каде што е само вредноста е дека еден јазол. Дали луѓето се согласувате со тоа? Може, ако сака, ако помине во нула дрво и сакате да внесете вредност во неа, се врати лажни. Тоа е до вас да се дефинира тоа. За да го направите првото нешто што го рече, а потоа - Па, ви се случува да имаат проблеми да го направи тоа, затоа што тоа ќе биде полесно ако имавме глобалната покажувачот на работа, но не, па ако дрво е нула, нема ништо што можеме да направиме во врска со тоа. Ние само може да се врати лажни. Па ќе одам да се промени внесување. Ние технички само може да се промени ова право тука, како е процесирањето врз нештата, но јас ќе одам да се промени вметнете да се земе еден јазол ** дрво. Двоен совети. Што значи ова? Наместо да се занимава со покажувачи на јазли, нешто јас ќе одам да се манипулира е овој покажувач. Одам да се манипулира овој покажувач. Одам да се манипулира совети директно. Ова има смисла бидејќи, мислам за одредување на - Па, токму сега ова укажува на нула. Она што сакам да направите е да манипулира со оваа покажувачот да укаже НЕ NULL. Сакам да се укаже на мојот нов јазол. Ако јас само да ги пратите на покажувачи на мојот покажувачи, тогаш јас не треба да ги пратите на родител покажувач. Јас само да ги пратите да се види дали покажувачот се укажува на нула, и ако покажувачот се укажува на нула, промените да се укаже на јазол сакам. И можам да ја промените бидејќи имам покажувач на покажувач. Ајде да видиме ова право сега. Ти всушност може да го направи тоа рекурзивно прилично лесно. Сакаме да го направите тоа? Да, тоа го правиме. Ајде да го видиме рекурзивно. Прво, она што е нашата база случај ќе биде? Речиси секогаш нашата база случај, но, всушност, ова е вид на слабо. Првите нешта прво, ако (дрво == NULL) Претпоставувам дека ние сме само ќе се врати лажни. Ова е различно од вашето дрво се ништовни. Ова е покажувач кон вашиот корен покажувачот се ништовни што значи дека вашиот корен покажувачот не постои. Значи тука долу, ако го направам јазол * - ајде да повторна употреба ова. Јазол * корен = NULL, а потоа јас ќе одам да се јавите вметнете со нешто како, вметнете 4 во & корен. Така и корен, ако коренот е еден јазол * тогаш и коренот ќе биде еден јазол. ** Ова е валиден. Во овој случај, дрвото, до тука, дрво не е нула - или вметнете. Тука. Дрво не е нула; * дрво е нула, што е во ред бидејќи ако * дрво е нула, тогаш може да се манипулира до сега укажуваат на она што го сакате тоа да се укаже. Но, ако дрво е нула, тоа значи дека само што дојде овде и рече нула. Тоа не дава никаква смисла. Јас не може да направи ништо со тоа. Ако дрвото е нула, се врати лажни. Па јас во основа веќе рече дека она што нашата вистинска база случај е. И што е тоа што ќе биде? [Студент, неразбирливо] [Бауден] Да. Значи, ако (* дрво == NULL). Ова се однесува на случајот овде каде што ако мојот црвен покажувачот е покажувач сум фокусирани на, па како јас сум фокусиран на овој покажувач, сега сум фокусиран на овој покажувач. Сега сум фокусиран на овој покажувач. Значи, ако мојот црвен покажувач, што е мојот јазол **, е некогаш - ако *, мојот црвен покажувач, секогаш е нула, тоа значи дека сум во случај кога јас сум се фокусира на покажувач кој покажува - ова е показател дека припаѓа на лист. Сакам да го промените ова покажувачот да укаже на мојот нов јазол. Се врати овде. Мој newnode само ќе биде јазол * n = build_node (вредност) тогаш n, ако n = NULL, се врати лажни. Друго што сакаме да го промени она што го покажувачот моментално укажува на до сега укажуваат на нашите новоизградени јазол. Ние всушност може да го стори тоа овде. Наместо да се каже n, ние велиме * дрво = доколку * дрво. Секој разбере тоа? Кои од кои се занимаваат со покажувачи да покажувачи, можеме да го промениме нула покажувачи да се укаже на работи што сакаме од нив да се укаже. Тоа е нашата база случај. Сега нашите повторување, или нашите рекурзија, ќе биде многу сличен со сите други recursions сме правеле. Ние ќе сакате да го внесете вредност, и сега ќе одам да се користи троичен повторно, но она што е нашата состојба ќе биде? Што е тоа што го барате да одлучи дали ние сакаме да одиме лево или десно? Да го сториме тоа во одделни чекори. Ако (вредност <) што? [Студентски] вредност на дрвото? [Бауден] Значи се сеќавам дека сум во моментов - [Студентите, неразбирливо] [Бауден] Да, па токму тука, да речеме дека оваа зелена стрелка е пример на она дрво во моментов е, е покажувач кон овој покажувач. Па тоа значи дека јас сум покажувач кон покажувач до 3. На Dereference двапати звучеше добро. Што ми - како да го направам тоа? [Студентски] Dereference еднаш, а потоа направи стрелките на овој начин? [Бауден] Значи (* дрво) е Dereference еднаш, -> вредност се случува да ми даде на вредноста на јазол дека јас сум индиректно укажува на. Па јас исто така може да напише ** tree.value ако сакате тоа. Или работи. Ако тоа е случај, тогаш сакам да се јавам вметнете со вредност. И што е мојот обновено јазол ** ќе биде? Сакам да си одам од лево, па ** tree.left се случува да ми биде лево. И сакам го покажувачот во тој нешто така што ако левата завршува се на нула покажувач, Можам да го менувате за да се укаже на мојот нов јазол. И друг случај може да биде многу слични. Да, всушност се направи дека мојот троичен во моментов. Внесете вредност, ако вредноста <(** дрво). Вредност. Потоа сакаме да обновите нашата ** на лево, друго сакаме да обновите нашата ** десно. [Студентски] Дали тоа го добиете покажувач на покажувачот? [Бауден] Запомнете дека - ** tree.right е еден јазол ѕвезда. [Студент, неразбирливо] >> Да. ** Tree.right е вака покажувачот или нешто. Па со преземање на покажувачот на тоа, што ми дава она што го сакате на покажувачот во тој тип. [Студентски] можеме да одиме одново зошто ние сме со користење на два покажувачи? [Бауден] Да. Значи - не можеш, а тоа решение пред е начин да се направи тоа без да правиш две насоки. Вие треба да бидат способни да го разберат со помош на два покажувачи, и ова е почиста решение. Исто така, забележи дека, што се случува ако ми дрво - она што се случува ако мојот корен беше нула? Што се случува ако го направам овој случај токму тука? Значи јазол * корен = NULL, вметнете 4 во & корен. Што е коренот ќе биде по тоа? [Студент, неразбирливо] >> Да. Корен вредност ќе биде 4. Корен лево ќе биде нула, корен право ќе биде нула. Во случај каде што не помине корен адреса, ние не би можеле да менувате корен. Во случај кога дрвото - каде што коренот беше нула, ние едноставно мораше да се врати лажни. Нема ништо што можеше да стори. Ние не можеме да вметнете јазол во празен дрво. Но сега можеме, ние само се направи празен дрво во еден јазол дрво. Што е обично очекуваниот начин на кој што би требало да работат. Понатаму, ова е значително пократок од исто така, следење на родител, и за да можете iterate долу сите на патот. Сега имам моите родители, а јас само имам родител право покажувачот на сеедно. Наместо тоа, ако ние го сторивме тоа iteratively, тоа би било истата идеја со време јамка. Но, наместо да се занимаваат со моите родители покажувач, наместо тековната ми покажувачот ќе биде нешто дека сум директно менување на точка за мојот нов јазол. Јас не треба да се занимаваат со тоа дали тоа е покажувајќи кон лево. Јас не треба да се занимаваат со тоа дали тоа е покажувајќи кон десно. Тоа е само што овој покажувачот е, јас одам да го поставите да се укаже на мојот нов јазол. Секој разбере како тоа функционира? Ако не зошто ние сакаме да го направи тоа на овој начин, но барем дека тоа функционира како решение? [Студентски] Каде да се вратиме вистина? [Бауден] Тоа е веројатно е во право тука. Ако ние правилно го вметнете, враќање вистина. Друго, овде ние ќе сакаат да се вратат она што вметнете враќа. И, што е посебно за овој рекурзивен функција? Тоа е опашката рекурзивна, па додека ние се компајлира со некои оптимизација, тоа ќе го препознае тоа и никогаш нема да добие магацинот претекување од ова, дури и ако нашите дрво има висина од 10.000 или 10 милиони евра. [Студент, неразбирливо] [Бауден] Мислам дека тоа го прави во цртичка - или она што оптимизација ниво е потребно за опашка рекурзија да бидат признати. Мислам дека тоа го признава - GCC и ѕвекот исто така, има различни значења за оптимизација нивоа. Сакам да кажам тоа е DashO 2, за сигурни дека ќе ја признае опашка рекурзија. Но ние - вие може да се создаде како пример Fibonocci или нешто. Тоа не е лесно да се тестираат со ова, затоа што е тешко да се изгради бинарен дрво кој е толку голем. Но да, мислам дека е DashO 2, кој ако компајлира со DashO 2, тоа ќе изгледа за опашка рекурзија и оптимизирате тоа. Да се ​​вратиме на - вметнете е буквално последната работа е потребна. Да се ​​вратиме на вметнете овде каде што ние ќе го стори истото идеја. Таа се уште ќе имаат мааната на не можејќи да целосно да се справи со кога коренот себе е нула, или минатото влез е нула, но наместо да се занимаваат со родителот покажувач, ајде да се применуваат истата логика на водење на покажувачи на покажувачи. Ако тука ние ги одржуваме нашите јазол ** мом, и ние не треба да ги пратите на правото повеќе, но јазол ** мом = & дрво. А сега нашата додека јамка ќе биде додека * мом не еднакви нула. Не треба да ги пратите на родителите повеќе. Не треба да ги пратите на лево и десно. И јас ќе го наречеме Temp, затоа што ние сме веќе користите Темп. Во ред. Значи, ако (вредност> * Temp), тогаш и (* Temp) -> десно друго Темп = (* Temp) -> лево. И сега, во овој момент, откако тоа додека јамка, Јас само го направи тоа затоа можеби е полесно да се размислува за iteratively од рекурзивно, но по ова додека јамка, * Температура е покажувачот сакаме да се промени. Пред имавме родител, и сакавме да се промени или родител лево или родител право, но ако сакате да го промените родител право, потоа * температура е родител во право, а ние може да го промени директно. Значи тука долу, можеме да направиме * Temp = newnode, и тоа е тоа. Значи известување, сите ние го сторивме во овој беше извади линии на код. Со цел да ги пратите на родителот во сето тоа е дополнителен напор. Еве, ако ние само да ги пратите на покажувачот на покажувачот, и ако сакаме да се ослободиме од сите овие големи загради сега, го направите да изгледа пократко. Ова сега е иста решение, но помалку линии на код. Откако ќе почнете да Признавајќи го ова како добро решение, тоа е, исто така, полесно да се причина за од како, добро, Зошто имам ова знаме во int нели? Што значи тоа? Ох, тоа е означувајќи дека секој пат кога одам десно, јас треба да го поставите, друго, ако одам лево јас треба да го поставите на нула. Еве, јас не треба да се причина за тоа, тоа е само полесно да се размислува за. Прашања? [Студент, неразбирливо] >> Да. Океј, па во последната трошка - Претпоставувам еден брз и лесен функција можеме да направиме е, let's - заедно, претпоставувам, се обиде да напише содржи функција кој не му е гајле дали тоа е бинарна пребарување дрво. Таа содржи функција треба да се врати вистинската ако било каде во оваа општа бинарно дрво е вредноста што го барате. Значи ајде прво да го направи тоа рекурзивно, а потоа ќе го направи тоа iteratively. Ние можеме да всушност само го прават тоа заедно, бидејќи ова ќе биде навистина краток. Што е Мој база случај ќе биде? [Студент, неразбирливо] [Бауден] Значи, ако (дрво == NULL), тогаш што? [Студентски] Врати се лажни. [Бауден] друго, добро, јас не треба на друго место. Ако ми беше друга база случај. [Студентски] дрвото вредност? >> Да. Значи, ако (дрво> вредноста == вредност. Забележете ние сме назад кон јазол * не, јазол ** а? Содржи никогаш не ќе треба да користите еден јазол **, бидејќи ние не се менува совети. Ние само им traversing. Ако тоа се случи, тогаш ние сакаме да се врати вистина. Друго сакаме да напречни деца. Па ние не може да се причина за тоа дали се на лево е помалку и сè на правото е поголема. Значи она што е нашата состојба ќе биде тука - или, што ќе правиме? [Студент, неразбирливо] >> Да. Врати содржи (вредност, дрво> лево) или содржи (вредност, дрво> десно). И тоа е тоа. И забележите дека некои краток спој евалуација, каде што ако ние се случува да се најде вредноста на левата дрво, ние никогаш не треба да се погледне во право дрво. Тоа е целата функција. Сега ајде да го сториме тоа iteratively, кој се случува да биде помалку убаво. Ние ќе се вообичаените почетокот на јазол * мом = дрво. Додека (мом! = NULL). Брзо одење за да ја видите проблем. Ако мом - овде, ако некогаш се пробие на ова, тогаш ние ја стартувате од работите да се погледне, па се врати лажни. Ако (мом-> вредноста == вредност), враќање вистина. Па сега, ние сме на место - не знаеме дали ние сакаме да одиме лево или десно. Така произволно, ајде да одиме лево. Сум очигледно работи во прашање каде што сум целосно напуштени сè - Јас ќе само некогаш се провери од левата страна на дрво. Јас никогаш не ќе ги провери нешто што е право дете на ништо. Како можам да го надминете овој? [Студентски] Вие треба да ги пратите на левицата и десницата во оџак. [Бауден] Да. Значи, да се направи тоа struct листа, јазол * n, а потоа јазол ** следно? Мислам дека работи добро. Ние сакаме да одиме во текот на лево, или let's - до тука. Struct листа листа =, тоа ќе започне надвор во тоа struct листа. * List = NULL. Значи тоа ќе биде нашата поврзани листа на subtrees дека имаме прескокнат во текот. Ние ќе се обидеме да напречни остави сега, но бидејќи ние неизбежно треба да се врати на правото, Ние ќе го задржи на десната страна во внатрешноста на нашите struct листа. Тогаш ќе имаме new_list или struct, struct листа *, new_list = Примерок (sizeof (листа)). Одам да се игнорира грешка-проверка на тоа, но ќе треба да се провери да се види дали тоа е нула. New_list јазол се случува да се укаже - О, тоа е зошто јас го сакав тука. Тоа се случува да се укаже на вториот struct листа. Тоа е само како поврзани листи работа. Ова е исто како int поврзани листа освен ние сме само замена int со јазол *. Тоа е иста. Значи new_list, вредноста на нашите new_list јазол, ќе биде мом-> десно. Вредноста на нашите new_list-> Следниот ќе биде нашата изворна листа, а потоа ние ќе се ажурира нашата листа да се укаже new_list. Сега ние треба некој вид на начин на влечење работи, како ние ја минал целиот левата поддрво. Сега ние треба да се повлече нешто надвор од неа, како мом е нула; ние не сакаме само да се врати лажни. Ние сакаме да сега се повлече надвор од нашата нова листа. А удобен начин за тоа - и, всушност, има повеќе начини за тоа. Секој има сугестија? Каде што треба да го направите тоа или како можам да го направите ова? Ние имаме само неколку минути, но било сугестија? Наместо - еден начин, наместо нашата состојба се додека, она што ние сме во моментов бараат во не е нула, наместо ние ќе продолжиме да се оди до нашата листа се е нула. Значи, ако нашата листа завршува се нула, тогаш имаме снема нешта да барате, за пребарување преку. Но, тоа значи дека првата работа во нашата листа е само ќе биде првиот јазол. Самиот првото нешто што ќе биде - ние веќе не треба да се види тоа. Значи листа-> n ќе биде наш дрво. листа-> Следниот ќе биде нула. И сега, додека листата не еднакви нула. Мом се случува да се извлече нешто од нашата листа. Значи мом ќе еднаков листа-> n. А потоа списокот ќе еднаков листа-> n, или листа-> следната. Значи, ако мом вредност е еднаква вредност. Сега можеме да го додадете и нашето право покажувач и нашите левата покажувачот додека тие не се ништовни. Тука долу, претпоставувам дека ние треба да го направиле тоа на прво место. Ако (мом-> право! = NULL) тогаш се случува да се вметне тој јазол во нашата листа. Ако (мом-> лево), ова е малку дополнителна работа, но тоа е во ред. Ако (мом-> лево! = NULL), и ние ќе го вметнете лево во нашиот поврзани листа, и дека треба да биде тоа. Ние iterate - се додека имаме нешто во нашата листа, имаме друг јазол да се погледне. Значи гледаме дека јазол, ние ја подигнеме нашата листа на следниот. Ако тој јазол е вредноста што го барате, ние може да се врати вистина. Друго вметнете нашите лево и десно subtrees, додека тие не се нула, во нашата листа така што ние неизбежно одат над нив. Значи, ако тие не беа нула, ако нашиот корен покажувачот посочи две работи, тогаш прво се повлече нешто надвор така и нашата листа завршува се ништовни. А потоа ќе стави две работи назад, па сега нашата листа е на големината 2. Потоа ние ќе јамка назад и ние сме само ќе да се повлече, да речеме, на левата покажувачот на нашите root јазол. И тоа само ќе го задржи случува, ние ќе се заокружи looping над сè. Забележете дека ова е значително посложен во рекурзивен решение. И јас сум изјави повеќе пати дека рекурзивен решение обично има многу заедничко со повторната решение. Еве ова е токму она што рекурзивен решение го прави. Единствената промена е во тоа што наместо имплицитно користење на магацинот, програмата оџакот, како начин на следење на она што јазли се уште треба да ја посетите, сега ќе мора да експлицитно се користи поврзани листа. Во двата случаи ќе се следење на она што јазол уште треба да се посети. Во рекурзивен случај тоа е само полесно, бидејќи магацинот се спроведува за вас, како на програмата оџак. Забележете дека овој поврзани листа, тоа е оџакот. Што и да се само да ги ставите на магацинот е веднаш она што ние ќе треба да се повлече од оџакот да ја посетите следната. Ние сме надвор од времето, но било какви прашања? [Студент, неразбирливо] [Бауден] Да. Значи, ако ние имаме поврзани листа, сегашната се случува да се укаже на овој човек, а сега ние сме само унапредување на нашата поврзани листа да се фокусираат на овој човек. Ние сме traversing во текот на поврзани листа во таа линија. И тогаш претпоставувам дека треба да се ослободи нашите поврзани листа и работи еднаш пред да се врати лажни или вистинити, ние треба да се iterate преку нашиот поврзани листа и секогаш тука долу, претпоставувам, ако мом право не е еднаква, таа додаде, па сега ние сакаме да се ослободи мом бидејќи, сепак, не можеме целосно да заборавите за листата? Да. Значи тоа е она што сакате да го направите овде. Каде е покажувачот? Мом тогаш беше - сакаме на struct листа * 10 е еднакво на листата следната. Слободен листа, листа = Temp. И во случај кога ќе се вратиме точно, ние треба да iterate текот на остатокот од нашите поврзани листа ослободување работи. На убаво нешто за рекурзивен решение е ослободување работи само значи пукање factorings надвор од магацинот што ќе се случи за вас. Значи ние си отиде од нешто што е како 3 линии на хард-да-тинк-за код на нешто што е значително многу повеќе хард-да-тинк-за линии на код. Други прашања? Во ред. Ние сме добро. Bye! [CS50.TV]