logo

CTDL 2005 chuong 10

Cây nhiều nhánh
Chöông 10 – Caây nhieàu nhaùnh Chöông 10 – CAÂY NHIEÀU NHAÙNH Chöông naøy tieáp tuïc nghieân cöùu veà caùc caáu truùc döõ lieäu caây, taäp trung vaøo caùc caây maø soá nhaùnh taïi moãi nuùt nhieàu hôn hai. Chuùng ta baét ñaàu töø vieäc trình baøy caùc moái noái trong caây nhò phaân. Keá tieáp chuùng ta tìm hieåu veà moät lôùp cuûa caây goïi laø trie ñöôïc xem nhö töø ñieån chöùa caùc töø. Sau ñoù chuùng ta tìm hieåu ñeán caây B-tree coù yù nghóa raát lôùn trong vieäc truy xuaát thoâng tin trong caùc taäp tin. Moãi phaàn trong soá naøy ñoäc laäp vôùi caùc phaàn coøn laïi. Cuoái cuøng, chuùng ta aùp duïng yù töôûng cuûa B-tree ñeå coù ñöôïc moät lôùp khaùc cuûa caây nhò phaân tìm kieám goïi laø caây ñoû-ñen (red-black tree). 10.1. Vöôøn caây, caây, vaø caây nhò phaân Nhö chuùng ta ñaõ thaáy, caây nhò phaân laø moät daïng caáu truùc döõ lieäu ñôn giaûn vaø hieäu quaû. Tuy nhieân, vôùi moät soá öùng duïng caàn söû duïng caáu truùc döõ lieäu caây maø trong ñoù soá con cuûa moãi nuùt chöa bieát tröôùc, caây nhò phaân vôùi haïn cheá moãi nuùt chæ coù toái ña hai con khoâng ñaùp öùng ñöôïc. Phaàn naøy laøm saùng toû moät ñieàu ngaïc nhieân thuù vò vaø höõu ích: caây nhò phaân cung caáp moät khaû naêng bieåu dieãn nhöõng caây khaùc bao quaùt hôn. 10.1.1. Caùc teân goïi cho caây Tröôùc khi môû roäng veà caùc loaïi caây, chuùng ta xeùt ñeán caùc ñònh nghóa. Trong toaùn hoïc, khaùi nieäm caây coù moät yù nghóa roäng: ñoù laø moät taäp baát kyø caùc ñieåm (goïi laø ñænh), vaø taäp baát kyø caùc caëp noái hai ñænh khaùc nhau (goïi laø caïnh hoaëc nhaùnh) sao cho luoân coù moät daõy lieân tuïc caùc caïnh (ñöôøng ñi) töø moät ñænh baát kyø ñeán moät ñænh baát kyø khaùc, vaø khoâng coù chu trình, nghóa laø khoâng coù ñöôøng ñi naøo baét ñaàu töø moät ñænh naøo ñoù laïi quay veà chính noù. Ñoái vôùi caùc öùng duïng trong maùy tính, chuùng ta thöôøng khoâng caàn nghieân cöùu caây moät caùch toång quaùt nhö vaäy, vaø khi caàn laøm vieäc vôùi nhöõng caây naøy, ñeå nhaán maïnh, chuùng ta thöôøng goïi chuùng laø caùc caây töï do (free tree). Caùc caây cuûa chuùng ta phaàn lôùn luoân coù moät ñænh ñaëc bieät, goïi laø goác cuûa caây, vaø caùc caây daïng naøy chuùng ta seõ goïi laø caùc caây coù goác (rooted tree). Moät caây coù goác coù theå ñöôïc veõ theo caùch thoâng thöôøng cuûa chuùng ta laø goác naèm treân, caùc nuùt vaø nhaùnh khaùc quay xuoáng döôùi, vôùi caùc nuùt laù naèm döôùi cuøng. Maëc duø vaäy, caùc caây coù goác vaãn chöa phaûi laø taát caû caùc daïng caây maø chuùng ta thöôøng duøng. Trong moät caây coù goác, thöôøng khoâng phaân bieät traùi hoaëc phaûi, hoaëc khi moät nuùt coù nhieàu nuùt con, khoâng theå noùi raèng nuùt naøo laø nuùt con thöù nhaát, thöù hai, v.v...Neáu khoâng vì moät lyù do naøo khaùc, söï thi haønh tuaàn töï caùc leänh thöôøng buoäc chaët moät thöù töï leân caùc nuùt con cuûa moät nuùt. Chuùng ta ñònh nghóa moät caây coù thöù Giaùo trình Caáu truùc döõ lieäu vaø Giaûi thuaät 237 Chöông 10 – Caây nhieàu nhaùnh töï (ordered tree) laø moät caây coù goác trong ñoù caùc con cuûa moät nuùt ñöôïc gaùn cho moät thöù töï. Löu yù raèng caùc caây coù thöù töï maø trong ñoù moãi nuùt coù khoâng quaù hai con vaãn chöa phaûi cuøng moät lôùp vôùi caây nhò phaân. Neáu moät nuùt trong caây nhò phaân chæ coù moät con, noù coù theå naèm beân traùi hoaëc beân phaûi, luùc ñoù ta coù hai caây nhò phaân khaùc nhau, nhöng chuùng cuøng laø moät caây coù thöù töï. Nhö moät nhaän xeùt cuoái cuøng lieân quan ñeán caùc ñònh nghóa, chuùng ta haõy löu yù raèng caây 2-tree maø chuùng ta ñaõ nghieân cöùu khi phaân tích caùc giaûi thuaät ôû nhöõng chöông tröôùc laø moät caây coù goác (nhöng khoâng nhaát thieát phaûi laø caây coù thöù töï) vôùi ñaëc tính laø moãi nuùt trong caây coù 0 hoaëc 2 nuùt con. Hình 10.1 - Caùc daïng khaùc nhau cuûa caây. Hình 10.1 cho thaáy raát nhieàu daïng caây khaùc nhau vôùi soá nuùt nhoû. Moãi lôùp caây keå töø caây ñaàu tieân coù ñöôïc baèng caùch keát hôïp caùc caây töø caùc lôùp coù tröôùc theo nhieàu caùch khaùc nhau. Caùc caây nhò phaân coù theå coù ñöôïc töø caùc caây coù thöù töï töông öùng, baèng caùch phaân bieät caùc nhaùnh traùi vaø phaûi. Giaùo trình Caáu truùc döõ lieäu vaø Giaûi thuaät 238 Chöông 10 – Caây nhieàu nhaùnh 10.1.2. Caây coù thöù töï 10.1.2.1. Hieän thöïc trong maùy tính Neáu chuùng ta muoán söû duïng moät caây coù thöù töï nhö moät caáu truùc döõ lieäu, moät caùch hieån nhieân ñeå hieän thöïc trong boä nhôù maùy tính laø môû roäng caùch hieän thöïc chuaån cuûa moät caây nhò phaân, vôùi soá con troû thaønh vieân trong moãi nuùt töông öùng soá caây con coù theå coù, thay vì chæ coù hai nhö ñoái vôùi caây nhò phaân. Chaúng haïn, trong moät caây coù moät vaøi nuùt coù ñeán möôøi caây con, chuùng ta caàn phaûi giöõ ñeán möôøi con troû thaønh vieân trong moät nuùt. Nhöng nhö vaäy seõ daãn ñeán vieäc caây phaûi chöùa moät soá raát lôùn caùc con troû chöùa trò NULL. Chuùng ta coù theå tính ñöôïc chính xaùc con soá naøy. Neáu caây coù n nuùt, moãi nuùt coù k con troû thaønh vieân, thì seõ coù taát caû laø n x k con troû. Moãi nuùt coù chính xaùc laø moät con troû tham chieáu ñeán noù, ngoaïi tröø nuùt goác. Nhö vaäy coù n-1 con troû khaùc NULL. Tæ leä caùc con troû NULL seõ laø: (n x k) – (n – 1) 1 ⎯⎯⎯⎯⎯⎯⎯ > 1-⎯ nxk k Neáu moät nuùt coù theå coù möôøi caây con, thì coù hôn 90% con troû laø NULL. Roõ raøng laø phöông phaùp bieåu dieãn caây coù thöù töï naøy hao toán raát nhieàu vuøng nhôù. Lyù do laø vì, trong moãi nuùt, chuùng ta ñaõ giöõ moät danh saùch lieân tuïc caùc con troû ñeán taát caû caùc con cuûa noù, vaø caùc danh saùch lieân tuïc naøy chöùa quaù nhieàu vuøng nhôù chöa ñöôïc söû duïng. Chuùng ta caàn tìm caùch thay theá caùc danh saùch lieân tuïc naøy bôûi caùc danh saùch lieân keát. 10.1.2.2. Hieän thöïc lieân keát Ñeå naém caùc con cuûa moät nuùt trong moät danh saùch lieân keát, chuùng ta caàn hai loaïi tham chieáu. Thöù nhaát laø tham chieáu töø nuùt cha ñeán nuùt con ñaàu tieân beân traùi cuûa noù, chuùng ta seõ goïi laø first_child. Thöù hai, moãi nuùt, ngoaïi tröø nuùt goác, seõ xuaát hieän nhö moät phaàn töû trong danh saùch lieân keát naøy, do ñoù noù caàn theâm moät tham chieáu ñeán nuùt keá trong danh saùch, nghóa laø tham chieáu ñeán nuùt con keá tieáp cuøng cha. Tham chieáu thöù hai naøy ñöôïc goïi laø next_sibling. Hieän thöïc naøy ñöôïc minh hoïa trong hình 10.2. Hình 10.2 – Hieän thöïc lieân keát cuûa caây coù thöù töï Giaùo trình Caáu truùc döõ lieäu vaø Giaûi thuaät 239 Chöông 10 – Caây nhieàu nhaùnh 10.1.2.3. Söï töông öùng töï nhieân Ñoái vôùi moãi nuùt cuûa caây coù thöù töï chuùng ta ñaõ ñònh nghóa hai tham chieáu first_child vaø next_sibling. Baèng caùch söû duïng hai tham chieáu naøy chuùng ta coù ñöôïc caáu truùc cuûa moät caây nhò phaân, nghóa laø, hieän thöïc lieân keát cuûa moät caây coù thöù töï laø moät caây nhò phaân lieân keát. Neáu muoán, chuùng ta coù theå coù ñöôïc moät hình aûnh deã nhìn hôn cho caây nhò phaân baèng caùch söû duïng hieän thöïc lieân keát cuûa caây coù thöù töï vaø quay theo chieàu kim ñoàng hoà moät goùc nhoû, sao cho caùc tham chieáu höôùng xuoáng (first_child) höôùng sang traùi, vaø caùc tham chieáu naèm ngang (next_sibling) höôùng sang phaûi. Ñoái vôùi hình 10.2, chuùng ta coù ñöôïc caây nhò phaân ôû hình 10.3. Hình 10.3 – Hình ñaõ ñöôïc quay cuûa hieän thöïc lieân keát 10.1.2.4. Söï töông öùng ngöôïc laïi Giaû söû nhö chuùng ta laøm ngöôïc laïi caùc böôùc cuûa quaù trình treân, baét ñaàu töø moät caây nhò phaân vaø coá gaéng khoâi phuïc laïi moät caây coù thöù töï. Ñieàu quan saùt ñaàu tieân chuùng ta caàn nhaän thaáy laø khoâng phaûi moïi caây nhò phaân ñeàu coù theå coù ñöôïc töø moät caây coù thöù töï bôûi quaù trình treân: do tham chieáu next_sibling cuûa nuùt goác cuûa caây coù thöù töï luoân baèng NULL neân goác cuûa caây nhò phaân töông öùng luoân coù caây con beân phaûi roãng. Ñeå tìm hieåu söï töông öùng ngöôïc laïi naøy moät caùch caån thaän, chuùng ta caàn phaûi xem xeùt moät lôùp caáu truùc döõ lieäu khaùc qua moät soá ñònh nghóa môùi döôùi ñaây. Giaùo trình Caáu truùc döõ lieäu vaø Giaûi thuaät 240 Chöông 10 – Caây nhieàu nhaùnh 10.1.3. Röøng vaø vöôøn Trong quaù trình tìm hieåu veà caây nhò phaân chuùng ta ñaõ coù kinh nghieäm veà caùch söû duïng ñeä quy, ñoái vôùi caùc lôùp khaùc cuûa caây chuùng ta cuõng seõ tieáp tuïc laøm nhö vaäy. Söû duïng ñeä quy coù nghóa laø thu heïp vaán ñeà thaønh vaán ñeà nhoû hôn. Do ñoù chuùng ta neân xem thöû ñieàu gì seõ xaûy ra neáu chuùng ta laáy moät caây coù goác hoaëc moät caây coù thöù töï vaø caét boû ñi nuùt goác. Nhöõng phaàn coøn laïi, neáu khoâng roãng, seõ laø moät taäp caùc caây coù goác hoaëc moät taäp coù thöù töï caùc caây coù thöù töï töông öùng. Thuaät ngöõ chuaån ñeå goïi moät taäp tröøu töôïng caùc caây ñoù laø röøng (forest), nhöng khi chuùng ta duøng thuaät ngöõ naøy, noùi chung chuùng ta thöôøng hình dung ñoù laø caùc caây coù goác. Cuïm töø “röøng coù thöù töï” (ordered forest) ñoâi khi coøn ñöôïc söû duïng ñeå goïi taäp coù thöù töï caùc caây coù thöù töï, do ñoù chuùng ta seõ ñeà cöû moät thuaät ngöõ coù tính ñaëc taû töông töï cho lôùp caùc caây coù thöù töï, ñoù laø thuaät ngöõ vöôøn (orchard). Löu yù raèng chuùng ta khoâng chæ coù ñöôïc moät röøng hoaëc moät vöôøn nhôø vaøo caùch loaïi boû ñi nuùt goác cuûa moät caây coù goác hoaëc moät caây coù thöù töï, chuùng ta coøn coù theå taïo neân moät caây coù goác hoaëc moät caây coù thöù töï baèng caùch baét ñaàu töø moät röøng hoaëc moät vöôøn, theâm moät nuùt môùi taïi ñænh, vaø noái caùc nhaùnh töø nuùt môùi naøy ñeán goác cuûa taát caû caùc caây trong röøng hoaëc vöôøn ñoù. Caùch naøy ñöôïc minh hoïa trong hình 10.4. Hình 10.4 – Loaïi boû vaø theâm nuùt goác. Chuùng ta seõ söû duïng quaù trình naøy ñeå ñöa ra moät ñònh nghóa ñeä quy môùi cho caùc caây coù thöù töï vaø caùc vöôøn. Tröôùc heát, chuùng ta haõy xem thöû neân baét ñaàu nhö theá naøo. Chuùng ta nhôù raèng moät caây nhò phaân coù theå roãng. Moät röøng hay moät vöôøn cuõng coù theå roãng. Tuy nhieân moät caây coù goác hay moät caây coù thöù töï khoâng theå laø caây roãng, vì noù phaûi chöùa ít nhaát laø moät nuùt goác. Neáu chuùng ta muoán baét ñaàu xaây döïng caây vaø röøng, chuùng ta coù theå löu yù raèng moät caây vôùi chæ moät nuùt coù theå coù ñöôïc baèng caùch theâm moät goác môùi vaøo moät röøng ñang roãng. Moät khi chuùng ta ñaõ coù caây naøy roài thì chuùng ta coù theå taïo ñöôïc moät röøng goàm bao nhieâu caây moät nuùt cuõng ñöôïc. Sau ñoù chuùng ta coù theå theâm goác môùi ñeå taïo caùc caây coù goác chieàu Giaùo trình Caáu truùc döõ lieäu vaø Giaûi thuaät 241 Chöông 10 – Caây nhieàu nhaùnh cao laø 1. Baèng caùch naøy chuùng ta coù theå tieáp tuïc taïo neân caùc caây coù goác phuø hôïp vôùi ñònh nghóa ñeä quy sau: Ñònh nghóa: Moät caây coù goác (rooted tree) bao goàm moät nuùt ñôn ν, goïi laø goác (root) cuûa caây, vaø moät röøng F (forest) goàm caùc caây goïi laø caùc caây con cuûa nuùt goác. Moät röøng F laø moät taäp (coù theå roãng) caùc caây coù goác. Moät quaù trình taïo töông töï cho caùc caây coù thöù töï vaø vöôøn. Ñònh nghóa: Moät caây coù thöù töï T (ordered tree) bao goàm moät nuùt ñôn ν, goïi laø goác (root) cuûa caây,vaø moät vöôøn O (orchard) goàm caùc caây ñöôïc goïi laø caùc caây con cuûa goác ν. Chuùng ta coù theå bieåu dieãn caây coù thöù töï baèng moät caëp coù thöù töï T = {ν, O}. Moät vöôøn O hoaëc laø moät taäp roãng, hoaëc goàm moät caây coù thöù töï T, goïi laø caây thöù nhaát (first tree) cuûa vöôøn, vaø moät vöôøn khaùc O’ (chöùa caùc caây coøn laïi cuûa vöôøn). Chuùng ta coù theå bieåu dieãn vöôøn baèng moät caëp coù thöù töï O = (T, O’). Löu yù raèng thöù töï cuûa caùc caây aån chöùa trong ñònh nghóa cuûa vöôøn. Moät vöôøn khoâng roãng chöùa caây thöù nhaát vaø caùc caây coøn laïi taïo neân moät vöôøn khaùc, vöôøn naøy laïi coù moät caây thöù nhaát vaø laø caây thöù hai cuûa vöôøn ban ñaàu. Tieáp tuïc ñoái vôùi caùc vöôøn coøn laïi chuùng ta coù caây thöù ba, thöù tö, v.v...cho ñeán khi vöôøn cuoái cuøng laø moät vöôøn roãng. Xem hình 10.5. Hình 10.5 – Caáu truùc ñeä quy cuûa caùc caây coù thöù töï vaø vöôøn. Giaùo trình Caáu truùc döõ lieäu vaø Giaûi thuaät 242 Chöông 10 – Caây nhieàu nhaùnh 10.1.4. Söï töông öùng hình thöùc Baây giôø chuùng ta coù theå coù moät keát quaû mang tính nguyeân taéc cho phaàn naøy. Ñònh lyù: Cho S laø moät taäp höõu haïn baát kyø goàm caùc nuùt. Coù moät aùnh xaï moät-moät f töø taäp caùc vöôøn coù taäp nuùt laø S ñeán taäp caùc caây nhò phaân coù taäp nuùt laø S. Chöùng minh ñònh lyù: Chuùng ta seõ duøng nhöõng kyù hieäu trong caùc ñònh nghóa ñeå chöùng minh ñònh lyù treân. Tröôùc heát chuùng ta caàn moät kyù hieäu töông töï cho caây nhò phaân. Moät caây nhò phaân B hoaëc laø moät taäp roãng ∅ hoaëc goàm moät nuùt goác ν vaø hai caây nhò phaân B1 vaø B2. Kyù hieäu cho moät caây nhò phaân khoâng roãng laø moät boä ba B = [ν, B1, B2]. Chuùng ta seõ chöùng minh ñònh lyù baèng phöông phaùp quy naïp toaùn hoïc treân soá nuùt trong S. Tröôøng hôïp thöù nhaát ñöôïc xeùt laø moät vöôøn roãng ∅, töông öùng vôùi moät caây nhò phaân roãng. f(∅) = ∅. Neáu vöôøn O khoâng roãng, noù ñöôïc kyù hieäu baèng moät boä hai O = (T, O2) vôùi T laø moät caây coù thöù töï vaø O2 laø moät vöôøn khaùc. Caây thöù töï T ñöôïc kyù hieäu bôûi moät caëp T ={ν, O1} vôùi ν laø moät nuùt vaø O1 laø moät vöôøn khaùc. Thay bieåu thöùc T vaøo bieåu thöùc O ta coù O = ({ν, O1}, O2). Theo giaû thieát quy naïp, f laø moät aùnh xaï moät-moät töø caùc vöôøn coù ít nuùt hôn S ñeán caùc caây nhò phaân, vôùi O1 vaø O2 nhoû hôn O, neân caùc caây nhò phaân f(O1) vaø f(O2) ñöôïc xaùc ñònh bôûi giaû thieát quy naïp. Neáu chuùng ta ñònh nghóa aùnh xaï f töø moät vöôøn ñeán moät caây nhò phaân bôûi f({ν, O1}, O2) = [ν, f(O1), f(O2)]. thì f laø moät söï töông öùng moät-moät giöõa caùc vöôøn vaø caùc caây nhò phaân coù cuøng soá nuùt. Vôùi baát kyø caùch thay theá naøo cho caùc kyù töï ν, O1, vaø O2 ôû veá traùi ñeàu coù chính xaùc moät caùch ñeå thay theá cho chuùng ôû veá phaûi, vaø ngöôïc laïi. Giaùo trình Caáu truùc döõ lieäu vaø Giaûi thuaät 243 Chöông 10 – Caây nhieàu nhaùnh 10.1.5. Pheùp quay Chuùng ta coù theå söû duïng daïng kyù hieäu cuûa söï töông öùng ñeå hình dung pheùp bieán ñoåi töø vöôøn sang caây nhò phaân. Trong caây nhò phaân [ν, f(O1), f(O2)] tham chieáu traùi töø ν ñeán nuùt goác cuûa caây nhò phaân f (O1), ñoù laø nuùt con thöù nhaát cuûa ν trong caây coù thöù töï {ν, O1}. Tham chieáu phaûi töø ν ñeán nuùt voán laø goác cuûa caây coù thöù töï keá tieáp veà beân phaûi trong vöôøn. Coù nghóa laø, “tham chieáu traùi” trong caây nhò phaân töông öùng vôùi “con thöù nhaát” trong caây coù thöù töï, vaø “tham chieáu phaûi” töông öùng “em keá”. Caùc quy taéc bieán ñoåi trong hình nhö sau: 1. Veõ vöôøn sao cho con thöù nhaát cuûa moãi nuùt naèm ngay döôùi noù, thay vì canh khoaûng caùch cho taát caû caùc con naèm ñeàu beân döôùi nuùt naøy. 2. Veõ moät tham chieáu thaúng ñöùng töø moãi nuùt ñeán nuùt con thöù nhaát cuûa noù, vaø veõ moät tham chieáu naèm ngang töø moãi nuùt ñeán em keá cuûa noù. 3. Loaïi boû taát caû caùc tham chieáu khaùc coøn laïi. 4. Quay sô ñoà 45 ñoä theo chieàu kim ñoàng hoà, sao cho caùc tham chieáu thaúng ñöùng trôû thaønh caùc tham chieáu traùi vaø caùc tham chieáu naèm ngang trôû thaønh caùc tham chieáu phaûi. 5. Quaù trình naøy ñöôïc minh hoïa trong hình 10.6 Hình 10.6 – Chuyeån ñoåi töø vöôøn sang caây nhò phaân. 10.1.6. Toång keát Chuùng ta ñaõ xem xeùt ba caùch bieåu dieãn söï töông öùng giöõa caùc vöôøn vaø caùc caây nhò phaân: Caùc tham chieáu first_child vaø next_sibling. • Pheùp quay caùc sô ñoà. • Söï töông ñöông kyù hieäu moät caùch hình thöùc. • Nhieàu ngöôøi cho raèng caùch thöù hai, quay caùc sô ñoà, laø caùch deã nhôù vaø deã hình dung nhaát. Caùch thöù nhaát, taïo caùc tham chieáu, thöôøng ñöôïc duøng ñeå vieát caùc chöông trình thöïc söï. Cuoái cuøng, caùch thöù ba, söï töông ñöông kyù hieäu moät caùch Giaùo trình Caáu truùc döõ lieäu vaø Giaûi thuaät 244 Chöông 10 – Caây nhieàu nhaùnh hình thöùc, thöôøng raát coù ích trong vieäc chöùng minh raát nhieàu ñaëc tính cuûa caây nhò phaân vaø vöôøn. 10.2. Caây töø ñieån tìm kieám: Trie Trong caùc chöông tröôùc chuùng ta ñaõ thaáy söï khaùc nhau trong vieäc tìm kieám trong moät danh saùch vaø vieäc tra cöùu trong moät baûng. Chuùng ta coù theå aùp duïng yù töôûng trong vieäc tra cöùu baûng vaøo vieäc truy xuaát thoâng tin trong moät caây baèng caùch söû duïng moät khoùa hoaëc moät phaàn cuûa khoùa. Thay vì tìm kieám baèng caùch so saùnh caùc khoùa, chuùng ta coù theå xem khoùa nhö laø moät chuoãi caùc kyù töï (chöõ caùi hoaëc kyù soá), vaø söû duïng caùc kyù töï naøy ñeå xaùc ñònh ñöôøng ñi taïi moãi böôùc. Neáu caùc khoùa cuûa chuùng ta chöùa caùc chöõ caùi, chuùng ta seõ taïo moät caây coù 26 nhaùnh töông öùng 26 chöõ caùi laø kyù töï ñaàu tieân cuûa caùc khoùa. Moãi caây con beân döôùi laïi coù 26 nhaùnh töông öùng vôùi kyù töï thöù hai, vaø cöù theá tieáp tuïc ôû caùc möùc cao hôn. Tuy nhieân chuùng ta cuõng coù theå tieán haønh phaân thaønh nhieàu nhaùnh ôû moät soá möùc ban ñaàu, sau ñoù neáu caây trôû neân quaù lôùn, chuùng ta coù theå duøng moät vaøi caùch thöùc khaùc naøo ñoù ñeå saép thöù töï cho nhöõng möùc coøn laïi. 10.2.1. Tries Coù moät phöông phaùp laø caét tæa bôùt caùc nhaùnh khoâng caàn thieát trong caây. Ñoù laø caùc nhaùnh khoâng daãn ñeán moät khoùa naøo. Laáy ví duï, trong tieáng Anh, khoâng coù caùc töø baét ñaàu bôûi ‘bb’, ‘bc’, ‘bf’, ‘bg’, ..., nhöng coù caùc töø baét ñaàu bôûi ‘ba’, ‘bd’, ‘be’. Do ñoù, moïi nhaùnh vaø nuùt cho caùc töø khoâng toàn taïi coù theå ñöôïc loaïi khoûi caây. Caây keát quaû naøy ñöôïc goïi laø Trie. Töø naøy nguyeân thuûy ñöôïc laáy töø retrieval, nhöng thöôøng ñöôïc ñoïc laø “try”. Ñònh nghóa: Moät caây Trie baäc m coù theå ñöôïc ñònh nghóa moät caùch hình thöùc laø moät caây roãng hoaëc goàm moät chuoãi noái tieáp coù thöù töï cuûa m caây Trie baäc m. 10.2.2. Tìm kieám moät khoùa Giaû söû caùc töø coù 3 kyù töï coù nghóa goàm caùc töø ñöôïc löu trong caây Trie ôû hình 10.7. Vieäc tìm kieám moät khoùa ñöôïc baét ñaàu töø nuùt goác. Kyù töï ñaàu tieân cuûa khoùa ñöôïc duøng ñeå xaùc ñònh nhaùnh naøo caàn ñi xuoáng. Nhaùnh caàn ñi roãng coù nghóa laø khoùa caàn tìm chöa coù trong caây. Ngöôïc laïi, treân nhaùnh ñöôïc choïn naøy, kyù töï thöù hai laïi ñöôïc duøng ñeå xaùc ñònh nhaùnh naøo trong möùc keá tieáp caàn ñi xuoáng, vaø cöù theá tieáp tuïc. Khi chuùng ta xeùt ñeán cuoái töø, laø chuùng ta ñaõ ñeán ñöôïc nuùt coù con troû tham chieáu ñeán thoâng tin caàn tìm. Ñoái vôùi nuùt töông öùng moät töø khoâng coù nghóa seõ coù con troû tham chieáu ñeán thoâng tin laø NULL. Chaúng haïn, töø a laø phaàn ñaàu cuûa töø aba, töø naøy laïi laø phaàn ñaàu cuûa töø abaca, nhöng chuoãi kyù töï abac khoâng phaûi laø moät töø coù nghóa, do ñoù nuùt bieåu dieãn abac coù con troû tham chieáu thoâng tin laø NULL. Giaùo trình Caáu truùc döõ lieäu vaø Giaûi thuaät 245 Chöông 10 – Caây nhieàu nhaùnh 10.2.3. Giaûi thuaät C++ Chuùng ta seõ chuyeån quaù trình tìm kieám vöøa ñöôïc moâ taû treân thaønh moät phöông thöùc tìm kieám caùc baûn ghi coù khoùa laø caùc chuoãi kyù töï. Chuùng ta seõ söû duïng phöông thöùc char key_letter(int position) traû veà kyù töï taïi vò trí position trong khoùa hoaëc kyù töï roãng neáu khoùa coù chieàu daøi ngaén hôn position, Hình 10.7 – Trie chöùa caùc töø ñöôïc caáu taïo töø a, b, c. vaø haøm phuï trôï int alphabetic_order(char symbol) traû veà thöù töï cuûa symbol trong baûng chöõ caùi. Haøm naøy traû veà 0 cho kyù töï roãng, 27 cho caùc kyù töï khoâng phaûi chöõ caùi. Trong hieän thöïc lieân keát, caây Trie chöùa moät con troû ñeán nuùt goác cuûa noù. class Trie { public: // Caùc phöông thöùc caäp nhaät, tìm kieám, truy xuaát. private: Trie_node *root; }; Giaùo trình Caáu truùc döõ lieäu vaø Giaûi thuaät 246 Chöông 10 – Caây nhieàu nhaùnh Moãi nuùt cuûa Trie caàn chöùa moät con troû chæ ñeán moät baûn ghi vaø moät maûng caùc con troû ñeán caùc nhaùnh. Soá nhaùnh laø 28 töông öùng keát quaû traû veà cuûa alphabetic_order. const int num_chars = 28; struct Trie_node { Caùc thuoäc tính // Record *data; Trie_node *branch[num_chars]; // constructors Trie_node(); }; Constructor cho Trie_node ñôn giaûn chæ gaùn taát caû caùc con troû laø NULL. 10.2.4. Tìm kieám trong caây Trie Phöông thöùc sau tìm moät baûn ghi chöùa khoùa cho tröôùc trong caây Trie. Error_code Trie::trie_search(const Key &target, Record &x) const /* post: Neáu tìm thaáy khoùa target, baûn ghi x chöùa khoùa seõ ñöôïc traû veà, phöông thöùc traû veà success. Ngöôïc laïi phöông thöùc traû veà not_present. uses: Caùc phöông thöùc cuûa lôùp Key. */ { int position = 0; char next_char; Trie_node *location = root; while (location!=NULL&&(next_char=target.key_letter(position))!=' ') { location = location->branch[alphabetic_order(next_char)]; // Ñi xuoáng daàn caùc nhaùnh töông öùng vôùi caùc kyù töï trong target. position++;// Ñeå xeùt kyù töï keá tieáp cuûa target. } if (location != NULL && location->data != NULL) { x = *(location->data); return success; } else return not_present; } Ñieàu kieän keát thuùc voøng laëp laø con troû location baèng NULL (khoùa caàn tìm khoâng coù trong caây), hoaëc kyù töï keá laø roãng (ñaõ xeùt heát chieàu daøi khoùa caàn tìm). Keát thuùc voøng laëp, con troû location neáu khaùc NULL chính laø con troû tham chieáu baûn ghi chöùa khoùa caàn tìm. 10.2.5. Theâm phaàn töû vaøo Trie Theâm moät phaàn töû vaøo caây Trie hoaøn toaøn töông töï nhö tìm kieám: laàn theo caùc nhaùnh ñeå ñi xuoáng cho ñeán khi gaëp vò trí thích hôïp, taïo baûn ghi chöùa döõ lieäu Giaùo trình Caáu truùc döõ lieäu vaø Giaûi thuaät 247 Chöông 10 – Caây nhieàu nhaùnh vaø cho con troû data chæ ñeán. Neáu treân ñöôøng ñi chuùng ta gaëp moät nhaùnh NULL, chuùng ta phaûi taïo theâm caùc nuùt môùi ñeå ñöa vaøo caây sao cho coù theå taïo ñöôïc moät ñöôøng ñi ñeán nuùt töông öùng vôùi khoùa môùi caàn theâm vaøo. Error_code Trie::insert(const Record &new_entry) /* post: Neáu khoùa cuûa new_entry ñaõ coù trong Trie, phöông thöùc traû veà duplicate_error. Ngöôïc laïi new_entry ñöôïc theâm vaøo Trie, phöông thöùc traû veà success. uses: caùc phöông thöùc cuûa caùc lôùp Record vaø Trie_node. */ { Error_code result = success; if (root == NULL) root = new Trie_node; // Taïo moät caây Trie roãng. // Vò trí kyù töï ñang xeùt trong new_entry. int position = 0; char next_char; // Ñi daàn xuoáng caùc nhaùnh trong Trie. Trie_node *location = root; while (location != NULL && (next_char = new_entry.key_letter(position)) != ' ') { int next_position = alphabetic_order(next_char); if (location->branch[next_position] == NULL) location->branch[next_position] = new Trie_node; location = location->branch[next_position]; position++; } // Khoâng coøn nhaùnh ñeå ñi tieáp hoaëc ñaõ xeùt heát caùc kyù töï cuûa new_entry. if (location->data != NULL) result = duplicate_error; else location->data = new Record(new_entry); return result; } 10.2.6. Loaïi phaàn töû trong Trie Caùch thöïc hieän cuûa vieäc theâm vaø tìm kieám phaàn töû cuõng ñöôïc aùp duïng cho vieäc loaïi moät phaàn töû trong caây Trie. Chuùng ta laàn theo ñöôøng ñi töông öùng vôùi khoùa caàn loaïi, khi gaëp nuùt naøy, chuùng ta gaùn NULL cho con troû data. Tuy nhieân, neáu nuùt naøy coù taát caû caùc thuoäc tính ñeàu laø caùc con troû NULL (caùc caây con vaø con troû data), chuùng ta caàn xoùa luoân chính noù. Vaø ñieàu naøy caàn phaûi ñöôïc thöïc hieän cho taát caû caùc nuùt treân cuûa noù treân ñöôøng ñi töø noù ngöôïc veà nuùt goác cho ñeán khi gaëp moät nuùt coù ít nhaát moät thuoäc tính thaønh vieân khaùc NULL. Ñeå laøm ñöôïc ñieàu naøy, chuùng ta coù theå taïo moät ngaên xeáp chöùa caùc con troû ñeán caùc nuùt treân ñöôøng ñi töø nuùt goác ñeán nuùt caàn tìm ñeå loaïi. Hoaëc chuùng ta coù theå söû duïng ñeä quy trong giaûi thuaät loaïi phaàn töû nhaèm traùnh vieäc söû duïng ngaên xeáp moät caùch töôøng minh. Caû hai caùch naøy ñeàu ñöôïc xem nhö baøi taäp. 10.2.7. Truy xuaát Trie Soá böôùc caàn thöïc hieän ñeå tìm kieám trong caây Trie (hoaëc theâm nuùt môùi vaøo Trie) tæ leä vôùi soá kyù töï taïo neân moät khoùa, khoâng phuï thuoäc vaøo logarit cuûa soá khoùa nhö caùc caùch tìm kieám döïa treân caùc caây khaùc. Neáu soá kyù töï nhoû so vôùi logarit cô soá 2 cuûa soá khoùa, caây Trie toû ra coù öu theá hôn caây nhò phaân tìm kieám Giaùo trình Caáu truùc döõ lieäu vaø Giaûi thuaät 248 Chöông 10 – Caây nhieàu nhaùnh nhieàu. Laáy ví duï, caùc khoùa goàm moïi khaû naêng cuûa moät chuoãi 5 kyù töï, thì caây Trie coù theå chöùa ñeán n = 265 = 11,881,376 khoùa vôùi moãi laàn tìm kieám toái ña laø 5 laàn laëp ñeå ñi xuoáng 5 möùc, trong khi ñoù caây nhò phaân tìm kieám toát nhaát coù theå thöïc hieän ñeán lg n ≈ 23.5 laàn so saùnh caùc khoùa. Tuy nhieân, trong nhieàu öùng duïng coù soá kyù töï trong moät khoùa lôùn, vaø taäp caùc khoùa thöïc söï xuaát hieän laïi ít so vôùi moïi khaû naêng coù theå coù cuûa caùc khoùa. Trong tröôøng hôïp naøy, soá laàn laëp caàn coù ñeå tìm moät khoùa trong caây Trie coù theå vöôït xa soá laàn so saùnh caùc khoùa caàn coù trong caây nhò phaân tìm kieám. Cuoái cuøng, lôøi giaûi toát nhaát coù theå laø söï keát hôïp cuûa nhieàu phöông phaùp. Caây Trie coù theå ñöôïc söû duïng cho moät ít kyù töï ñaàu cuûa caùc khoùa, vaø sau ñoù moät phöông phaùp khaùc coù theå ñöôïc söû duïng cho phaàn coøn laïi cuûa khoùa. 10.3. Tìm kieám ngoaøi: B-tree Töø tröôùc ñeán nay, chuùng ta ñaõ giaû söû raèng moïi caáu truùc döõ lieäu ñeàu ñöôïc giöõ trong boä nhôù toác ñoä cao; nghóa laø chuùng ta ñaõ chæ xem xeùt vieäc truy xuaát thoâng tin trong (internal information retrieval). Vôùi moät soá öùng duïng, giaû thieát naøy coù theå chaáp nhaän ñöôïc, nhöng vôùi nhieàu öùng duïng quan troïng khaùc thì khoâng. Chuùng ta haõy xem xeùt vaán ñeà truy xuaát thoâng tin ngoaøi (external information retrieval), trong ñoù caùc baûn ghi caàn tìm kieám vaø truy xuaát ñöôïc löu trong caùc taäp tin. 10.3.1. Thôøi gian truy xuaát Thôøi gian caàn coù ñeå thaâm nhaäp vaø truy xuaát moät töø trong boä nhôù toác ñoä cao nhieàu nhaát laø moät vaøi microgiaây. Thôøi gian caàn ñeå ñònh vò moät baûn ghi trong ñóa cöùng ñöôïc ño baèng miligiaây, ñoái vôùi ñóa meàm coù theå vöôït quaù moät giaây. Nhö vaäy thôøi gian cho moät laàn truy xuaát ngoaøi lôùn gaáp haøng ngaøn laàn so vôùi moät laàn truy xuaát trong. Khi moät baûn ghi naèm trong ñóa, thöïc teá moãi laàn khoâng phaûi chæ ñoïc moät töø, maø ñoïc moät trang lôùn (page) hay coøn goïi laø moät khoái (block) thoâng tin. Kích thöôùc chuaån cuûa khoái thöôøng töø 256 ñeán 1024 kyù töï hoaëc töø. Muïc ñích cuûa chuùng ta trong vieäc tìm kieám ngoaøi laø phaûi laøm toái thieåu soá laàn truy xuaát ñóa, do moãi laàn truy xuaát chieám thôøi gian ñaùng keå so vôùi caùc tính toaùn beân trong boä nhôù. Moãi laàn truy xuaát ñóa, chuùng ta coù ñöôïc moät khoái maø coù theå chöùa nhieàu baûn ghi. Baèng caùch söû duïng caùc baûn ghi naøy, chuùng ta coù theå choïn löïa giöõa nhieàu khaû naêng ñeå quyeát ñònh khoái naøo seõ ñöôïc truy xuaát keá tieáp. Nhôø ñoù maø toaøn boä döõ lieäu khoâng caàn phaûi löu ñoàng thôøi trong boä nhôù. Khaùi nieäm caây nhieàu nhaùnh maø chuùng ta seõ xem xeùt döôùi ñaây ñaëc bieät thích hôïp ñoái vôùi vieäc tìm kieám ngoaøi. Giaùo trình Caáu truùc döõ lieäu vaø Giaûi thuaät 249 Chöông 10 – Caây nhieàu nhaùnh 10.3.2. Caây tìm kieám nhieàu nhaùnh Caây nhò phaân tìm kieám ñöôïc toång quaùt hoùa moät caùch tröïc tieáp ñeán caây tìm kieám nhieàu nhaùnh, trong ñoù, vôùi moät soá nguyeân m naøo ñoù ñöôïc goïi laø baäc (order) cuûa caây, moãi nuùt coù nhieàu nhaát m nuùt con. Neáu k (k ≤ m) laø soá con cuûa moät nuùt thì nuùt naøy chöùa chính xaùc laø k-1 khoùa, vaø caùc khoùa naøy phaân hoaïch taát caû caùc khoùa cuûa caùc caây con thaønh k taäp con. Hình 10.8 cho thaáy moät caây tìm kieám coù 5 nhaùnh naèm xen keõ caùc phaàn töû töø thöù 1 vaø ñeán thöù 4 trong moãi nuùt, trong ñoù moät vaøi nhaùnh coù theå roãng. Hình 10.8 – Moät caây tìm kieám 5 nhaùnh (khoâng phaûi caây B-tree) 10.3.3. Caây nhieàu nhaùnh caân baèng Giaû söû moãi laàn ñoïc taäp tin, chuùng ta ñoïc leân ñöôïc moät khoái chöùa caùc khoùa trong cuøng moät nuùt. Nhôø söï phaân hoaïch caùc khoùa trong caùc caây con döïa treân caùc khoùa naøy, chuùng ta bieát ñöôïc nhaùnh naøo chuùng ta caàn tieáp tuïc coâng vieäc tìm kieám khoùa caàn tìm. Baèng caùch naøy soá laàn ñoïc ñóa toái ña chính laø chieàu cao cuûa caây. Vaø chi phí boä nhôù cuõng chæ daønh toái ña laø cho caùc nuùt treân ñöôøng ñi töø nuùt goác ñeán nuùt coù khoùa caàn tìm, chöù khoâng phaûi toaøn boä döõ lieäu löu trong caây. Muïc ñích cuûa chuùng ta söû duïng caây tìm kieám nhieàu nhaùnh ñeå laøm giaûm vieäc truy xuaát taäp tin, do ñoù chuùng ta mong muoán chieàu cao cuûa caây caøng nhoû caøng toát. Chuùng ta coù theå thöïc hieän ñieàu naøy baèng caùch cho raèng, thöù nhaát, khoâng coù caùc caây con roãng xuaát hieän beân treân caùc nuùt laù (nhö vaäy söï phaân hoaïch caùc khoùa thaønh caùc taäp con seõ hieäu quaû nhaát); thöù hai, raèng moïi nuùt laù ñeàu thuoäc cuøng moät möùc (ñeå cho vieäc tìm kieám ñöôïc baûo ñaûm laø seõ keát thuùc vôùi cuøng soá laàn truy xuaát Giaùo trình Caáu truùc döõ lieäu vaø Giaûi thuaät 250 Chöông 10 – Caây nhieàu nhaùnh taäp tin); vaø, thöù ba, raèng moïi nuùt, ngoaïi tröø caùc nuùt laù coù ít nhaát moät soá nuùt con toái thieåu naøo ñoù. Chuùng ta ñöa ra yeâu caàu raèng, moïi nuùt, ngoaïi tröø caùc nuùt laù, coù ít nhaát laø moät nöûa soá con so vôùi soá con toái ña coù theå coù. Caùc ñieàu kieän treân daãn ñeán ñònh nghóa sau: Ñònh nghóa: Moät caây B-tree baäc m laø moät caây m nhaùnh, trong ñoù, 1. Moïi nuùt laù coù cuøng möùc. 2. Moïi nuùt trung gian (khoâng phaûi nuùt laù vaø nuùt goác), coù nhieàu nhaát m nuùt con khaùc roãng, ít nhaát laø ⎡m/2⎤ nuùt con khaùc roãng. 3. Soá khoùa trong moãi nuùt trong nhoû hôn soá nuùt con khaùc roãng 1 ñôn vò, vaø caùc khoùa naøy phaân hoaïch caùc khoùa trong caùc caây con theo caùch cuûa caây tìm kieám. 4. Nuùt goác coù nhieàu nhaát m nuùt con, vaø neáu noù khoâng ñoàng thôøi laø nuùt laù (tröôøng hôïp caây chæ coù 1 nuùt), thì noù coù theå coù ít nhaát laø 2 nuùt con. Caây trong hình 10.8 khoâng phaûi laø caây B-tree, do moät vaøi nuùt coù caùc nuùt con roãng, moät vaøi nuùt coù quaù ít con, vaø caùc nuùt laù khoâng cuøng moät möùc. Hình 10.9 minh hoïa moät caây B-tree coù baäc laø 5 vôùi caùc khoùa laø caùc kyù töï chöõ caùi. Tröôøng hôïp naøy moãi nuùt trung gian coù ít nhaát 3 nuùt con (phaân hoaïch bôûi 2 khoùa). Hình 10.9 – Caây B-tree baäc 5. 10.3.4. Theâm phaàn töû vaøo B-tree Ñieàu kieän moïi nuùt laù thuoäc cuøng möùc nhaán maïnh haønh vi ñaëc tröng cuûa B- tree: Ngöôïc vôùi caây nhò phaân tìm kieám, B-tree khoâng cho pheùp lôùn leân taïi caùc nuùt laù; thay vaøo ñoù, noù lôùn leân taïi goác. Phöông phaùp chung ñeå theâm phaàn töû vaøo noù nhö sau. Tröôùc heát, thöïc hieän vieäc tìm kieám ñeå xem khoùa caàn theâm ñaõ coù trong caây hay chöa. Neáu chöa coù, vieäc tìm kieám seõ keát thuùc taïi moät nuùt laù. Khoùa môùi seõ ñöôïc theâm vaøo nuùt laù. Neáu nuùt laù voán chöa ñaày, vieäc theâm vaøo hoaøn taát. Giaùo trình Caáu truùc döõ lieäu vaø Giaûi thuaät 251 Chöông 10 – Caây nhieàu nhaùnh Khi nuùt laù caàn theâm phaàn töû môùi ñaõ ñaày, nuùt naøy seõ ñöôïc phaân laøm hai nuùt caïnh nhau trong cuøng moät möùc, khoùa chính giöõa seõ khoâng thuoäc nuùt naøo trong hai nuùt naøy, noù ñöôïc gôûi ngöôïc leân ñeå theâm vaøo nuùt cha. Nhôø vaäy, sau naøy, khi caàn tìm kieám, söï so saùnh vôùi khoùa giöõa naøy seõ daãn ñöôøng xuoáng tieáp caây con töông öùng beân traùi hoaëc beân phaûi. Quaù trình phaân ñoâi caùc nuùt coù theå ñöôïc lan truyeàn ngöôïc veà goác. Quaù trình naøy seõ chaám döùt khi coù moät nuùt cha naøo ñoù caàn ñöôïc theâm moät khoùa gôûi töø döôùi leân maø chöa ñaày. Khi moät khoùa ñöôïc theâm vaøo nuùt goác ñaõ ñaày, nuùt goác seõ ñöôïc phaân laøm hai vaø khoùa naèm giöõa cuõng ñöôïc gôûi ngöôïc leân, vaø noù seõ trôû thaønh moät goác môùi. Ñoù chính laø luùc duy nhaát caây B-tree taêng tröôûng chieàu cao. Quaù trình naøy coù theå ñöôïc laøm saùng toû baèng ví duï theâm vaøo caây B-tree caáp 5 ôû hình 10.10. Chuùng ta seõ laàn löôït theâm caùc khoùa a g f b k d h m j e s i r x c l n t u p vaøo moät caây roãng theo thöù töï naøy. Boán khoùa ñaàu tieân seõ ñöôïc theâm vaøo chæ moät nuùt, nhö trong phaàn ñaàu cuûa hình 10.10. Chuùng ñöôïc saép thöù töï ngay khi ñöôïc theâm vaøo. Tuy nhieân, ñoái vôùi khoùa thöù naêm, k, nuùt naøy khoâng coøn choã. Nuùt naøy ñöôïc phaân laøm hai nuùt môùi, khoùa naèm giöõa, f, ñöôïc chuyeån leân treân vaø taïo neân nuùt môùi, ñoù cuõng laø goác môùi. Do caùc nuùt sau khi phaân chia chæ chöùa moät nöûa soá khoùa coù theå coù, ba khoùa tieáp theo coù theå ñöôïc theâm vaøo maø khoâng gaëp khoù khaên gì. Tuy nhieân, vieäc theâm vaøo ñôn giaûn naøy cuõng ñoøi hoûi vieäc toå chöùc laïi caùc khoùa trong moät nuùt. Ñeå theâm j, moät laàn nöõa laïi caàn phaân chia moät nuùt, vaø laàn naøy khoùa chuyeån leân treân chính laø j. Moät soá laàn theâm caùc khoùa tieáp theo ñöôïc thöïc hieän töông töï. Laàn theâm cuoái cuøng, p, ñaëc bieät hôn. Vieäc theâm p vaøo tröôùc tieân laøm phaân chia moät nuùt voán chöùa k, l, m, n, vaø gôûi khoùa naèm giöõa m leân treân cho nuùt cha chöùa c, f, j, r, tuy nhieân, nuùt naøy ñaõ ñaày. Nhö vaäy, nuùt naøy laïi phaân chia laøm hai nuùt môùi, vaø cuoái cuøng nuùt goác môùi chöùa j ñöôïc taïo ra. Coù hai ñieåm caàn chuù yù khi quan saùt söï lôùn leân coù traät töï cuûa B-tree. Thöù nhaát, khi moät nuùt ñöôïc phaân ñoâi, noù taïo ra hai nuùt môùi, moãi nuùt chæ coù moät nöûa soá phaàn töû toái ña coù theå coù. Nhôø ñoù, nhöõng laàn theâm tieáp theo coù theå khoâng caàn phaûi phaân chia nuùt laàn nöõa. Nhö vaäy moät laàn phaân chia nuùt laø chuaån bò cho moät vaøi laàn theâm ñôn giaûn. Thöù hai, khoùa ñöôïc chuyeån leân treân luoân laø khoùa naèm giöõa chöù khoâng phaûi chính khoùa caàn theâm vaøo. Do ñoù, nhieàu laàn theâm laäp laïi seõ coù chieàu höôùng caûi thieän söï caân baèng cho caây, khoâng phuï thuoäc vaøo thöù töï caùc khoùa ñöôïc theâm vaøo. Giaùo trình Caáu truùc döõ lieäu vaø Giaûi thuaät 252 Chöông 10 – Caây nhieàu nhaùnh Hình 10.10 – Söï lôùn leân cuûa caây B-tree. 10.3.5. Giaûi thuaät C++: tìm kieám vaø theâm vaøo Ñeå phaùt trieån thaønh giaûi thuaät C++ tìm kieám vaø theâm vaøo moät caây B-tree, chuùng ta haõy baét ñaàu vôùi caùc khai baùo cho caây. Ñeå ñôn giaûn chuùng ta seõ xaây döïng caây B-tree trong boä nhôù toác ñoä cao, söû duïng caùc con troû chöùa ñòa chæ caùc nuùt trong caây. Trong phaàn lôùn caùc öùng duïng, caùc con troû naøy coù theå ñöôïc thay theá bôûi Giaùo trình Caáu truùc döõ lieäu vaø Giaûi thuaät 253 Chöông 10 – Caây nhieàu nhaùnh ñòa chæ cuûa caùc khoái hoaëc trang trong ñóa, hoaëc soá thöù töï caùc baûn ghi trong taäp tin. 10.3.5.1. Caùc khai baùo Chuùng ta seõ cho ngöôøi söû duïng töï do choïn löïa kieåu cuûa baûn ghi maø hoï muoán löu vaøo caây B-tree. Lôùp B-tree cuûa chuùng ta, vaø lôùp node töông öùng, seõ coù thoâng soá template laø lôùp Record. Thoâng soá template thöù hai seõ laø moät soá nguyeân bieåu dieãn baäc cuûa B-tree. Ñeå coù ñöôïc moät ñoái töôïng B-tree, ngöôøi söû duïng chæ vieäc khai baùo moät caùch ñôn giaûn, chaúng haïn:B-tree sample_tree; seõ khai baùo sample_tree laø moät caây B-tree baäc 5 chöùa caùc baûn ghi laø caùc soá nguyeân. template class B_tree { public: // Caùc phöông thöùc. private: // Thuoäc tính: B_node *root; // Caùc haøm phuï trôï. }; Beân trong moãi nuùt cuûa B-tree chuùng ta caàn moät danh saùch caùc phaàn töû vaø moät danh saùch caùc con troû ñeán caùc nuùt con. Do caùch danh saùch naøy ngaén, ñeå ñôn giaûn, chuùng ta duøng caùc maûng lieân tuïc vaø moät thuoäc tính count ñeå bieåu dieãn chuùng. template struct B_node { // Caùc thuoäc tính: int count; Record data[order - 1]; B_node *branch[order]; // constructor: B_node(); }; Thuoäc tính count chöùa soá baûn ghi hieän taïi trong töøng nuùt. Neáu count khaùc 0 thì nuùt coù count+1 nuùt con khaùc roãng. Nhaùnh branch[0] chæ ñeán caây con chöùa caùc baûn ghi coù caùc khoùa nhoû hôn khoùa trong data[0]; vôùi moãi trò cuûa position naèm giöõa 1 vaø count-1, keå caû hai caän naøy, branch[position] chæ ñeán caây con coù caùc khoùa naèm giöõa hai khoùa cuûa data[position-1] vaø data[position]; vaø branch[count] chæ ñeán caây con coù caùc khoùa lôùn hôn khoùa trong data[count- 1]. Constructor cuûa B_node taïo moät nuùt roãng baèng caùch gaùn count baèng 0. Giaùo trình Caáu truùc döõ lieäu vaø Giaûi thuaät 254 Chöông 10 – Caây nhieàu nhaùnh 10.3.5.2. Tìm kieám Nhö ví duï ñôn giaûn ñaàu tieân, chuùng ta vieát phöông thöùc tìm kieám trong moät caây B-tree cho moät baûn ghi coù khoùa truøng vôùi khoùa cuûa target. Trong phöông thöùc tìm kieám cuûa chuùng ta, nhö thöôøng leä, chuùng ta seõ giaû thieát raèng caùc baûn ghi naøy coù theå ñöôïc so saùnh bôûi caùc toaùn töû so saùnh chuaån. Cuõng nhö vieäc tìm kieám trong caây nhò phaân tìm kieám, chuùng ta baét ñaàu baèng caùch goïi moät haøm ñeä quy phuï trôï. template Error_code B_tree::search_tree(Record &target) /* post: Neáu tìm thaáy phaàn töû coù khoùa truøng vôùi khoùa trong target thì toaøn boä baûn ghi phaàn töû naøy ñöôïc cheùp vaøo target, phöông thöùc traû veà success. Ngöôïc laïi, phöông thöùc traû veà not_present . uses: Haøm ñeä quy phuï trôï recursive_search_tree */ { return recursive_search_tree(root, target); } Thoâng soá vaøo cho haøm ñeä quy phuï trôï recursive_search_tree laø con troû ñeán goác cuûa caây con trong B-tree vaø baûn ghi target chöùa khoùa caàn tìm. Haøm seõ traû veà maõ loãi cho bieát vieäc tìm kieám keát thuùc thaønh coâng hay khoâng; neáu tìm thaáy, target ñöôïc caäp nhaät bôûi baûn ghi chöùa khoùa ñöôïc tìm thaáy trong caây. Phöông phaùp chung ñeå tìm kieám baèng caùch laàn theo caùc con troû ñeå ñi xuoáng trong caây töông töï caùch tìm kieám trong caây nhò phaân tìm kieám. Tuy nhieân, trong moät caây nhieàu nhaùnh, chuùng ta caàn toán nhieàu coâng hôn trong vieäc xaùc ñònh ra nhaùnh caàn xuoáng tieáp theo trong moãi nuùt. Vieäc naøy seõ ñöôïc thöïc hieän bôûi moät haøm phuï trôï khaùc cuûa B-tree laø search_node, haøm naøy tìm baûn ghi coù khoùa truøng vôùi khoùa cuûa target trong soá caùc baûn ghi coù trong nuùt ñöôïc tham chieáu bôûi con troû current. Haøm search_node coù söû duïng tham bieán position, neáu tìm thaáy, tham bieán naøy seõ nhaän veà chæ soá cuûa baûn ghi chöùa khoùa caàn tìm trong nuùt tham chieáu bôûi current; ngöôïc laïi noù chöùa chæ soá cuûa nhaùnh beân döôùi tieáp theo caàn tìm. template Error_code B_tree::recursive_search_tree (B_node *current, Record &target) /* pre: current laø NULL hoaëc chæ ñeán goác moät caây con trong B_tree. post: Neáu khoùa trong target khoâng tìm thaáy, haøm traû veà not_present. Ngöôïc laïi, target ñöôïc caäp nhaät bôûi baûn ghi coù chöùa khoùa tìm döôïc trong caây, haøm traû veà success. uses: Haøm phuï trôï recursive_search_tree moät caùch ñeä quy vaø haøm search_node. */ { Error_code result = not_present; Giaùo trình Caáu truùc döõ lieäu vaø Giaûi thuaät 255 Chöông 10 – Caây nhieàu nhaùnh int position; if (current != NULL) { result = search_node(current, target, position); if (result == not_present) result=recursive_search_tree(current->branch[position], target); else target = current->data[position]; } return result; } Haøm treân ñöôïc vieát ñeä quy ñeå chöùng toû söï töông töï giöõa caáu truùc cuûa noù vôùi caáu truùc cuûa haøm theâm phaàn töû trong phaàn tieáp theo döôùi ñaây. Tuy nhieân, ñaây laø ñeä quy ñuoâi, vaø noù coù theå ñöôïc thay bôûi caáu truùc laëp. 10.3.5.3. Tìm kieám trong moät nuùt Haøm search_node döôùi ñaây thöïc hieän vieäc tìm tuaàn töï. Haøm naøy caàn xaùc ñònh xem target ñaõ coù trong nuùt hieän taïi hay chöa, neáu chöa, noù caàn xaùc ñònh nhaùnh naøo trong soá count+1 nhaùnh laø chöùa target. Döôùi ñaây laø caùch tìm tuaàn töï vôùi bieán taïm chaïy töø 0 ñeán vò trí tìm thaáy hoaëc vöøa vöôït qua khoùa cuûa target. template Error_code B_tree::search_node (B_node *current, const Record &target, int &position) /* pre: current chöùa ñòa chæ 1 nuùt trong B_tree. post: Neáu khoùa trong target ñöôïc tìm thaáy trong *current, thoâng soá position seõ chöùa vò trí cuûa phaàn töû target trong nuùt naøy, target ñöôïc caäp nhaät laïi, haøm traû veà success. Ngöôïc laïi, haøm traû veà not_present, position seõ laø chæ soá cuûa nhaùnh con beân döôùi caàn tieáp tuïc vieäc tìm kieám. uses: Caùc phöông thöùc cuûa lôùp Record. */ { position = 0; while (position < current->count && target >current->data[position]) // Tìm tuaàn töï. position++; if (position < current->count && target == current->data[position]) return success; else return not_present; } Ñoái vôùi caây B-tree coù caùc nuùt khaù lôùn, haøm treân caàn ñöôïc söûa ñoåi ñeå söû duïng caùch tìm nhò phaân thay vì tìm tuaàn töï. Trong moät vaøi öùng duïng, moãi baûn ghi cuûa caây B-tree chöùa raát nhieàu döõ lieäu, ñieàu naøy laøm cho baäc cuûa caây trôû neân töông ñoái nhoû, vaø vieäc tìm tuaàn töï trong moät nuùt laø thích hôïp. Trong nhieàu öùng duïng khaùc, chæ coù caùc khoùa laø ñöôïc chöùa trong caùc nuùt, neân baäc cuûa caây trôû neân khaù lôùn, chuùng ta caàn duøng caùch tìm nhò phaân ñeå tìm vò trí cuûa moät khoùa trong moät nuùt. Giaùo trình Caáu truùc döõ lieäu vaø Giaûi thuaät 256
DMCA.com Protection Status Copyright by webtailieu.net