logo

CTDL 2005 chuong 18

Ứng dụng danh sách liên kết và bảng băm
Chöông 18 – ÖÙng duïng danh saùch lieân keát vaø baûng baêm Chöông 18 – ÖÙNG DUÏNG DANH SAÙCH LIEÂN KEÁT VAØ BAÛNG BAÊM Ñaây laø moät öùng duïng coù söû duïng CTDL danh saùch vaø baûng baêm. Thoâng qua öùng duïng naøy sinh vieân coù dòp naâng cao kyõ naêng thieát keá höôùng ñoái töôïng, giaûi quyeát baøi toaùn töø ngoaøi vaøo trong. Ngoaøi ra, ñaây cuõng laø moät ví duï raát hay veà vieäc söû duïng moät CTDL ñuùng ñaén khoâng nhöõng ñaùp öùng ñöôïc yeâu caàu baøi toaùn maø coøn laøm taêng hieäu quaû cuûa chöông trình leân raát nhieàu. 18.1. Giôùi thieäu veà chöông trình Game_Of_Life Game_Of_Life laø moät chöông trình giaû laëp moät söï tieán trieån cuûa söï soáng, khoâng phaûi laø moät troø chôi vôùi ngöôøi söû duïng. Treân moät löôùi chöõ nhaät khoâng coù giôùi haïn, moãi oâ hoaëc laø oâ troáng hoaëc ñang coù moät teá baøo chieám giöõ. OÂ coù teá baøo ñöôïc goïi laø oâ soáng, ngöôïc laïi laø oâ cheát. Moãi thôøi ñieåm oån ñònh cuûa toaøn boä löôùi chuùng ta goïi laø moät traïng thaùi. Ñeå chuyeån sang traïng thaùi môùi, moät oâ seõ thay ñoåi tình traïng soáng hay cheát tuøy thuoäc vaøo soá oâ soáng chung quanh noù trong traïng thaùi cuõ theo caùc quy taéc sau: 1. Moät oâ coù taùm oâ keá caän. 2. Moät oâ ñang soáng maø khoâng coù hoaëc chæ coù 1 oâ keá caän soáng thì oâ ñoù seõ cheát do ñôn ñoäc. 3. Moät oâ ñang soáng maø coù töø 4 oâ keá caän trôû leân soáng thì oâ ñoù cuõng seõ cheát do quaù ñoâng. 4. Moät oâ ñang soáng maø coù 2 hoaëc 3 oâ keá caän soáng thì noù seõ soáng tieáp trong traïng thaùi sau. 5. Moät oâ ñang cheát trôû thaønh soáng trong traïng thaùi sau neáu noù coù chính xaùc 3 oâ keá caän soáng. 6. Söï chuyeån traïng thaùi cuûa caùc oâ laø ñoàng thôøi, coù nghóa laø caên cöù vaøo soá oâ keá caän soáng hay cheát trong moät traïng thaùi ñeå quyeát ñònh söï soáng cheát cuûa caùc oâ ôû traïng thaùi sau. 18.2. Caùc ví duï Chuùng ta goïi moät ñoái töôïng löôùi chöùa caùc oâ soáng vaø cheát nhö vaäy laø moät caáu hình. Trong hình 18.1, con soá ôû moãi oâ bieåu dieãn soá oâ soáng chung quanh noù, theo quy taéc thì caáu hình naøy seõ khoâng coøn oâ naøo soáng ôû traïng thaùi sau. Trong khi ñoù caáu hình ôû hình 18.2 seõ beàn vöõng vaø khoâng bao giôø thay ñoåi. Giaùo trình Caáu truùc döõ lieäu vaø Giaûi thuaät 401 Chöông 18 – ÖÙng duïng danh saùch lieân keát vaø baûng baêm Hình 18.1- Moät trang thaùi cuûa Game of Life Vôùi moät traïng thaùi khôûi ñaàu naøo ñoù, chuùng ta khoù löôøng tröôùc ñöôïc ñieàu gì seõ xaûy ra. Moät vaøi caáu hình ñôn giaûn ban ñaàu coù theå bieán ñoåi qua nhieàu böôùc ñeå thaønh caùc caáu hình phöùc taïp hôn nhieàu, hoaëc cheát daàn moät caùch chaäm chaïp, hoaëc seõ ñaït ñeán söï beàn vöõng, hoaëc chæ coøn laø söï chuyeån ñoåi laëp laïi giöõa moät vaøi traïng thaùi. Hình 18.2 – Caáu hình coù traïng thaùi beàn vöõng Hình 18.3 – Hai caáu hình naøy luaân phieân thay ñoåi nhau. 18.3. Giaûi thuaät Muïc ñích cuûa chuùng ta laø vieát moät chöông trình hieån thò caùc traïng thaùi lieân tieáp nhau cuûa moät caáu hình töø moät traïng thaùi ban ñaàu naøo ñoù. Giaûi thuaät: • Khôûi taïo moät caáu hình ban ñaàu coù moät soá oâ soáng. • In caáu hình ñaõ khôûi taïo. • Trong khi ngöôøi söû duïng vaãn coøn muoán xem söï bieán ñoåi cuûa caùc traïng thaùi: - Caäp nhaät traïng thaùi môùi döïa vaøo caùc quy taéc cuûa chöông trình. - In caáu hình. Giaùo trình Caáu truùc döõ lieäu vaø Giaûi thuaät 402 Chöông 18 – ÖÙng duïng danh saùch lieân keát vaø baûng baêm Chuùng ta seõ xaây döïng lôùp Life maø ñoái töôïng cuûa noù seõ coù teân laø configuration. Ñoái töôïng naøy caàn 3 phöông thöùc: initialize() ñeå khôûi taïo, print() ñeå in traïng thaùi hieän taïi vaø update() ñeå caäp nhaät traïng thaùi môùi. 18.4. Chöông trình chính cho Game_Of_Life #include "utility.h" #include "life.h" int main() // Chöông trình Game_Of_Life. /* pre: Ngöôøi söû duïng cho bieát traïng thaùi ban ñaàu cuûa caáu hình. post: Chöông trình in caùc traïng thaùi thay ñoåi cuûa caáu hình cho ñeán khi ngöôøi söû duïng muoán ngöng chöông trình. Caùch thöùc thay ñoåi traïng thaùi tuaân theo caùc quy taéc cuûa troø chôi. uses: Lôùp Life vôùi caùc phöông thöùc initialize(), print(), update(). Caùc haøm phuï trôï instructions(), user_says_yes(). */ { Life configuration; instructions(); configuration.initialize(); configuration.print(); cout Chöông 18 – ÖÙng duïng danh saùch lieân keát vaø baûng baêm 18.4.1. Phieân baûn thöù nhaát cho lôùp Life Trong phieân baûn thöù nhaát naøy, chuùng ta chöa söû duïng moät lôùp CTDL coù saün naøo, maø chæ suy nghó ñôn giaûn raèng ñoái töôïng Life caàn moät maûng hai chieàu caùc soá nguyeân ñeå bieåu dieãn löôùi caùc oâ. Trò 1 bieåu dieãn oâ soáng vaø triï 0 bieåu dieãn oâ cheát. Kích thöôùc maûng laáy theâm boán bieân döï tröõ ñeå vieäc ñeám soá oâ soáng keá caän ñöôïc thöïc hieän deã daøng cho caû caùc oâ naèm treân caïnh bieân hay goùc. Taát nhieân vôùi caùch choïn löïa naøy chuùng ta ñaõ phaûi lô qua moät ñoøi hoûi cuûa chöông trình: ñoù laø löôùi chöõ nhaät phaûi khoâng coù giôùi haïn. Ngoaøi caùc phöông thöùc public, lôùp Life caàn theâm moät haøm phuï trôï neighbor_count ñeå tính caùc oâ soáng keá caän cuûa moät oâ cho tröôùc. const int maxrow = 20, maxcol = 60; // Kích thöôùc ñeå thöû chöông trình class Life { public: void initialize(); void print(); void update(); private: int grid[maxrow + 2][maxcol + 2];// Döï tröõ theâm 4 bieân nhö hình veõ döôùi ñaây int neighbor_count(int row, int col); }; Hình 18.4 – Löôùi caùc oâ cuûa Life coù döï tröõ boán bieân Döôùi ñaây laø haøm neighbor_count ñöôïc goïi bôûi phöông thöùc update. int Life::neighbor_count(int row, int col) /* pre: Ñoái töôïng Life chöùa traïng thaùi caùc oâ soáng, cheát. row vaø col laø toïa ñoä hôïp leä cuûa moät oâ. post: Traû veà soá oâ ñang soáng chung quanh oâ taïi toïa ñoä row, col. */ { int i, j; int count = 0; Giaùo trình Caáu truùc döõ lieäu vaø Giaûi thuaät 404 Chöông 18 – ÖÙng duïng danh saùch lieân keát vaø baûng baêm for (i = row - 1; i Chöông 18 – ÖÙng duïng danh saùch lieân keát vaø baûng baêm while (row != -1 || col != -1) { if (row >= 1 && row = 1 && col Chöông 18 – ÖÙng duïng danh saùch lieân keát vaø baûng baêm do { // Laëp cho ñeán khi ngöôøi söû duïng goõ moät kyù töï hôïp leä. if (initial_response) cout Chöông 18 – ÖÙng duïng danh saùch lieân keát vaø baûng baêm caáu hình, chuùng ta coù theå xaùc ñònh soá oâ soáng chung quanh noù baèng caùch tra cöùu traïng thaùi cuûa chuùng. Trong hieän thöïc môùi cuûa chuùng ta cho phöông thöùc update, chuùng ta seõ duyeät qua taát caû caùc oâ coù khaû naêng thay ñoåi traïng thaùi, xaùc ñònh soá oâ soáng chung quanh moãi oâ nhôø söû duïng baûng, vaø choïn ra nhöõng oâ seõ thöïc söï soáng trong traïng thaùi keá. 18.4.2.2. Ñaëc taû caáu truùc döõ lieäu Tuy raèng baûng baêm chöùa taát caû caùc oâ ñang soáng, nhöng noù chæ tieän trong vieäc tra cöùu traïng thaùi cuûa töøng oâ maø thoâi. Chuùng ta cuõng seõ caàn duyeät qua caùc oâ soáng trong caáu hình ñoù. Vieäc duyeät moät baûng baêm thöôøng khoâng hieäu quaû. Do ñoù, ngoaøi baûng baêm, chuùng ta caàn moät danh saùch caùc oâ soáng nhö laø thaønh phaàn döõ lieäu thöù hai cuûa moät caáu hình Life. Caùc ñoái töôïng ñöôïc löu trong danh saùch vaø baûng baêm cuûa caáu hình Life cuøng chöùa thoâng tin veà caùc oâ soáng, nhöng chuùng ta coù hai caùch truy caäp khaùc nhau. Ñieàu naøy phuc vuï ñaéc löïc cho giaûi thuaät cuûa baøi toaùn nhö ñaõ phaân tích ôû treân. Chuùng ta seõ bieåu dieãn caùc oâ baèng caùc theå hieän cuûa moät caáu truùc goïi laø Cell: moãi oâ caàn moät caëp toïa ñoä. struct Cell { // Caùc constructor Cell() { row = col = 0; } Cell(int x, int y) { row = x; col = y; } int row, col; } Khi caáu hình Life nôùi roäng, caùc oâ ôû bìa ngoaøi cuûa noù seõ xuaát hieän daàn daàn. Nhö vaäy moät oâ môùi seõ xuaát hieän nhôø vaøo vieäc caáp phaùt ñoäng vuøng nhôù, vaø noù seõ chæ ñöôïc truy xuaát ñeán thoâng qua con troû. Chuùng ta seõ duøng moät List maø moãi phaàn töû chöùa con troû ñeán moät oâ (hình 18.5). Moãi phaàn töû cuûa List goàm hai con troû: moät chæ ñeán moät oâ ñang soáng vaø moät chæ ñeán phaàn töû keá trong List. Cho tröôùc moät con troû chæ moät oâ ñang soáng, chuùng ta coù theå xaùc ñònh caùc toïa ñoä cuûa oâ ñoù baèng caùch laàn theo con troû roài laáy hai thaønh phaàn row vaø col cuûa noù. Nhö vaäy, chuùng ta coù theå löu caùc con troû chæ ñeán caùc oâ nhö laø caùc baûn ghi trong baûng baêm; caùc toaï ñoä row vaø col cuûa caùc oâ, ñöôïc xaùc ñònh bôûi con troû, seõ laø caùc khoùa töông öùng. Chuùng ta caàn löïa choïn giöõa baûng baêm ñòa chæ môû vaø baûng baêm noái keát. Caùc phaàn töû seõ chöùa trong baûng baêm chæ coù kích thöôùc nhoû: moãi phaàn töû chæ caàn chöùa moät con troû ñeán moät oâ ñang soáng. Nhö vaäy, vôùi baûng baêm noái keát, kích thöôùc cuûa moãi baûn ghi seõ taêng 100% do phaûi chöùa theâm caùc con troû lieân keát trong caùc danh saùch lieân keát. Tuy nhieân, baûn thaân baûng baêm noái keát seõ coù kích thöôùc raát nhoû maø vaãn coù theå chöùa soá baûn ghi lôùn gaáp nhieàu laàn kích thöôùc chính noù. Vôùi baûng baêm Giaùo trình Caáu truùc döõ lieäu vaø Giaûi thuaät 408 Chöông 18 – ÖÙng duïng danh saùch lieân keát vaø baûng baêm ñòa chæ môû, caùc baûn ghi seõ nhoû hôn vì chæ chöùa ñòa chæ caùc oâ ñang soáng, nhöng caàn phaûi döï tröõ nhieàu vò trí troáng ñeå traùnh hieän töôïng traøn xaûy ra vaø ñeå quaù trình tìm kieám khoâng bò keùo daøi quaù laâu khi ñuïng ñoä thöôøng xuyeân xaûy ra. Hình 18.5 – Danh saùch lieân keát giaùn tieáp. Ñeå taêng tính linh hoaït, chuùng ta quyeát ñònh seõ duøng baûng baêm noái keát coù ñònh nghóa nhö sau: class Hash_table { public: Error_code insert(Cell *new_entry); bool retrieve(int row, int col) const; private: List table[hash_size]; // Duøng danh saùch lieân keát. }; ÔÛ ñaây, chuùng ta chæ ñaëc taû hai phöông thöùc: insert vaø retrieve. Vieäc truy xuaát baûng laø ñeå bieát baûng coù chöùa con troû chæ ñeán moät oâ coù toïa ñoä cho tröôùc hay khoâng. Do ñoù phöông thöùc retrieve caàn hai thoâng soá chöùa toïa ñoä row vaø col vaø traû veà moät trò bool. Chuùng ta daønh vieäc hieän thöïc hai phöông thöùc naøy nhö laø baøi taäp vì chuùng raát töông töï vôùi nhöõng gì chuùng ta ñaõ thaûo luaän veà baûng baêm noái keát trong chöông 12. Chuùng ta löu yù raèng Hash_table caàn coù nhöõng phöông thöùc constructor vaø destructor cuûa noù. Chaúng haïn, destructor cuûa Hash_table caàn goïi destructor cuûa List cho töøng phaàn töû cuûa maûng table. Giaùo trình Caáu truùc döõ lieäu vaø Giaûi thuaät 409 Chöông 18 – ÖÙng duïng danh saùch lieân keát vaø baûng baêm 18.4.2.3. Lôùp Life Vôùi caùc quyeát ñònh treân, chuùng ta seõ guùt laïi caùch bieåu dieãn vaø nhöõng ñieàu caàn löu yù cho lôùp Life. Ñeå cho vieäc thay ñoåi caáu hình ñöôïc deã daøng chuùng ta seõ löu caùc thaønh phaàn döõ lieäu moät caùch giaùn tieáp qua caùc con troû. Nhö vaäy lôùp Life caàn coù constructor vaø destructor ñeå ñònh vò cuõng nhö giaûi phoùng caùc vuøng nhôù caáp phaùt ñoäng cho caùc caáu truùc naøy. class Life { public: Life(); void initialize(); void print(); void update(); ~Life(); private: List *living; Hash_table *is_living; bool retrieve(int row, int col) const; Error_code insert(int row, int col); int neighbor_count(int row, int col) const; }; Caùc haøm phuï trôï retrieve vaø neighbor_count xaùc ñònh traïng thaùi cuûa moät oâ baèng caùch truy xuaát baûng baêm. Haøm phuï trôï khaùc, insert, khôûi taïo moät ñoái töôïng Cell caáp phaùt ñoäng vaø cheøn noù vaøo baûng baêm cuõng nhö danh saùch caùc oâ trong ñoái töôïng Life. 18.4.2.4. Caùc phöông thöùc cuûa Life Chuùng ta seõ vieát moät vaøi phöông thöùc vaø haøm cuûa Life ñeå minh hoïa caùch xöû lyù caùc oâ, caùc danh saùch vaø nhöõng gì dieãn ra trong baûng baêm. Caùc haøm coøn laïi xem nhö baøi taäp. Caäp nhaät caáu hình Phöông thöùc update coù nhieäm vuï xaùc ñònh caáu hình keá tieáp cuûa Life töø moät caáu hình cho tröôùc. Trong phieân baûn tröôùc, chuùng ta laøm ñieàu naøy baèng caùch xeùt moïi oâ coù trong löôùi chöùa caáu hình grid, tính caùc oâ keá caän chung quanh cho moãi oâ ñeå xaùc ñònh traïng thaùi keá tieáp cuûa noù. Caùc thoâng tin naøy ñöôïc chöùa trong bieán cuïc boä new_grid vaø sau ñoù ñöôïc cheùp vaøo grid. Chuùng ta seõ laëp laïi nhöõng coâng vieäc naøy ngoaïi tröø vieäc phaûi xeùt moïi oâ coù theå coù trong caáu hình do ñaây laø moät löôùi khoâng coù giôùi haïn. Thay vaøo ñoù, chuùng ta neân giôùi haïn taàm nhìn cuûa chuùng ta chæ trong caùc oâ coù khaû naêng seõ soáng trong traïng thaùi keá. Ñoù coù theå laø caùc oâ naøo? Roõ raøng ñoù chính laø caùc oâ ñang soáng trong traïng thaùi hieän taïi, chuùng coù theå cheát ñi nhöng cuõng coù theå tieáp tuïc soáng trong Giaùo trình Caáu truùc döõ lieäu vaø Giaûi thuaät 410 Chöông 18 – ÖÙng duïng danh saùch lieân keát vaø baûng baêm traïng thaùi keá. Ngoaøi ra, moät soá oâ ñang cheát cuõng coù theå trôû neân soáng trong traïng thaùi sau, nhöng ñoù chæ laø nhöõng oâ ñang cheát naèm keà nhöõng oâ ñang soáng (caùc oâ coù maøu xaùm trong hình 9.18). Nhöõng oâ xa hôn nöõa khoâng coù khaû naêng soáng daäy do chuùng khoâng coù oâ naøo keá caän ñang soáng. Hình 18.6 – Caáu hình Life vôùi caùc oâ cheát vieàn chung quanh. Trong phöông thöùc update, bieán cuïc boä Life new_configuration duøng ñeå chöùa caáu hình môùi: chuùng ta thöïc hieän voøng laëp cho taát caû nhöõng oâ ñang soáng vaø nhöõng oâ keá caän cuûa chuùng, ñoái vôùi moãi oâ nhö vaäy, tröôùc heát caàn xaùc ñònh xem noù ñaõ ñöôïc theâm vaøo new_configuration hay chöa, chuùng ta caàn phaûi caån thaän ñeå traùnh vieäc theâm bò laëp laïi hai laàn cho moät oâ. Neáu quaû thaät oâ ñang xeùt chöa coù trong new_configuration, chuùng ta duøng haøm neighbor_count ñeå quyeát ñònh vieäc coù theâm noù vaøo caáu hình môùi hay khoâng. ÔÛ cuoái phöông thöùc, chuùng ta caàn hoaùn ñoåi caùc thaønh phaàn List vaø Hash_table giöõa caáu hình hieän taïi vaø caáu hình môùi new_configuration. Söï hoaùn ñoåi naøy laøm cho ñoái töôïng Life coù ñöôïc caáu hình ñaõ ñöôïc caäp nhaät, ngoaøi ra, noù coøn baûo ñaûm raèng caùc oâ, danh saùch, vaø baûng baêm trong caáu hình cuõ cuûa ñoái töôïng Life seõ ñöôïc giaûi phoùng khoûi boä nhôù caáp phaùt ñoäng (vieäc naøy ñöôïc thöïc hieän do trình bieân dòch töï ñoäng goïi destructor cho ñoái töôïng cuïc boä new_configuration). void Life::update() /* post: Ñoái töôïng Life chöùa caáu hình ôû traïng thaùi keá. uses: Lôùp Hash_table vaø lôùp Life vaø caùc haøm phuï trôï. */ { Life new_configuration; Cell *old_cell; Giaùo trình Caáu truùc döõ lieäu vaø Giaûi thuaät 411 Chöông 18 – ÖÙng duïng danh saùch lieân keát vaø baûng baêm for (int i = 0; i < living->size(); i++) { // Laáy moät oâ ñang soáng. living->retrieve(i, old_cell); for (int row_add = -1; row_add < 2; row_add ++) for (int col_add = -1; col_add < 2; col_add++) { int new_row = old_cell->row + row_add, new_col = old_cell->col + col_add; new_row, new_col laø toaï ñoä cuûa oâ ñang xeùt hoaëc oâ keá caän cuûa noù. // if (!new_configuration.retrieve(new_row, new_col)) switch (neighbor_count(new_row, new_col)) { case 3: // Soá oâ soáng keá caän laø 3 thì oâ ñang xeùt trôû thaønh soáng. new_configuration.insert(new_row, new_col); break; case 2: // Soá oâ soáng keá caän laø 2 thì oâ ñang xeùt giöõ nguyeân traïng thaùi. if (retrieve(new_row, new_col)) new_configuration.insert(new_row, new_col); break; OÂ seõ cheát. default: // break; } } } // Traùo döõ lieäu trong configuration vôùi döõ lieäu trong new_configuration. new_configuration seõ ñöôïc doïn deïp bôûi destructor cuûa noù. List *temp_list = living; living = new_configuration.living; new_configuration.living = temp_list; Hash_table *temp_hash = is_living; is_living = new_configuration.is_living; new_configuration.is_living = temp_hash; } In caáu hình Ñeå in ñöôïc taát caû caùc oâ ñang soáng, chuùng ta coù theå lieät keâ laàn löôït moãi doøng moät oâ vôùi toïa ñoä row, col cuûa noù. Ngöôïc laïi neáu muoán bieåu dieãn ñuùng vò trí row, col treân löôùi, chuùng ta nhaän thaáy raèng chuùng ta khoâng theå hieån thò nhieàu hôn laø moät maåu nhoû cuûa moät caáu hình Life khoâng coù giôùi haïn leân maøn hình. Do ñoù chuùng ta seõ in moät cöûa soå chöõ nhaät ñeå hieån thò traïng thaùi cuûa 20 x 80 caùc vò trí ôû trung taâm cuûa caáu hình Life. Ñoái vôùi moãi oâ trong cöûa soå, chuùng ta truy xuaát traïng thaùi cuûa noù töø baûng baêm vaø in moät kyù töï traéng hoaëc khaùc traéng töông öùng vôùi traïng thaùi cheát hoaëc soáng cuûa noù. void Life::print() /* post: In moät traïng thaùi cuûa ñoái töôïng Life. uses: Life::retrieve. */ Giaùo trình Caáu truùc döõ lieäu vaø Giaûi thuaät 412 Chöông 18 – ÖÙng duïng danh saùch lieân keát vaø baûng baêm { int row, col; cout Chöông 18 – ÖÙng duïng danh saùch lieân keát vaø baûng baêm Destructor caàn giaûi phoùng moïi phaàn töû ñöôïc caáp phaùt ñoäng bôûi baát kyø moät phöông thöùc naøo ñoù cuûa lôùp Life. Beân caïnh hai con troû living vaø is_living ñöôïc khôûi taïo nhôø constructor coøn coù caùc ñoái töôïng Cell maø chuùng tham chieáu ñeán ñaõ ñöôïc caáp phaùt ñoäng trong phöông thöùc insert. Destructor caàn giaûi phoùng caùc ñoái töôïng Cell naøy tröôùc khi giaûi phoùng living vaø is_living. Life::~Life() /* post: Caùc thuoäc tính caáp phaùt ñoäng cuûa ñoái töôïng Life vaø caùc ñoái tuôïng do chuùng tham chieáu ñöôïc giaûi phoùng. uses: Caùc lôùp Hash_table, List. */ { Cell *old_cell; for (int i = 0; i < living->size(); i++) { living->retrieve(i, old_cell); delete old_cell; } // Goïi destructor cuûa Hash_table. delete is_living; // Goïi destructor cuûa List. delete living; } Ñoái vôùi nhöõng caáu truùc coù nhieàu lieân keát baèng con troû nhö theá naøy, chuùng ta luoân phaûi ñaët vaán ñeà veà khaû naêng taïo raùc do nhöõng sô suaát cuûa chuùng ta. Thoâng thöôøng thì destructor cuûa moät lôùp luoân laøm toát nhieäm vuï cuûa noù, nhöng noù chæ doïn deïp nhöõng gì thuoäc ñoái töôïng cuûa noù, chöù khoâng bieát ñeán nhöõng gì maø ñoái töôïng cuûa noù tham chieáu ñeán. Neáu chuùng ta chuû quan, vieäc doïn deïp khoâng dieãn ra ñuùng nhö chuùng ta töôûng. Khi chaïy, chöông trình coù theå laø queân doïn deïp, cuõng coù theå laø doïn deïp nhieàu hôn moät laàn ñoái vôùi moät vuøng nhôù ñöôïc caáp phaùt ñoäng. Ñaây cuõng laø moät vaán ñeà khaù lyù thuù maø sinh vieân neân töï suy nghó theâm. Haøm baêm Haøm baêm ôû ñaây coù hôi khaùc vôùi nhöõng gì chuùng ta ñaõ gaëp trong nhöõng phaàn tröôùc, thoâng soá cuûa noù coù ñeán hai thaønh phaàn (row vaø col), nhôø vaäy chuùng ta coù theå deã daøng söû duïng moät vaøi daïng cuûa pheùp troän. Tröôùc khi quyeát ñònh neân laøm nhö theá naøo, chuùng ta haõy xeùt tröôøng hôïp moät maûng chöõ nhaät nhoû coù aùnh xaï moät moät döôùi ñaây chính laø moät haøm chæ soá. Coù chính xaùc laø maxrow phaàn töû trong moãi haøng, caùc chæ soá i, j ñöôïc aùnh xaï ñeán i + maxrow*j ñeå ñaët maûng chöõ nhaät vaøo moät chuoãi caùc vuøng nhôù lieân tuïc, haøng naøy keá tieáp haøng kia. Chuùng ta neân duøng caùch aùnh xaï töông töï cho haøm baêm cuûa chuùng ta vaø seõ thay theá maxrow baèng moät soá thích hôïp, chaúng haïn nhö moät soá nguyeân toá, ñeå vieäc phaân phoái ñöôïc raûi ñeàu vaø giaûm söï ñuïng ñoä. Giaùo trình Caáu truùc döõ lieäu vaø Giaûi thuaät 414 Chöông 18 – ÖÙng duïng danh saùch lieân keát vaø baûng baêm const int factor = 101; int hash(int row, int col) /* post: Traû veà giaù trò haøm baêm töø 0 ñeán hash_size - 1 töông öùng vôùi toïa ñoä (row, col). */ { int value; value = row + factor * col; value %= hash_size; if (value < 0) return value + hash_size; else return value; } Caùc chöông trình con khaùc Caùc phöông thöùc coøn laïi cuûa Life nhö initialize, retrieve, vaø neighbor_count ñeàu ñöôïc xem xeùt töông töï nhö caùc haøm vöøa roài hoaëc nhö caùc haøm töông öùng trong phieân baûn thöù nhaát. Chuùng ta daønh chuùng laïi nhö baøi taäp. Giaùo trình Caáu truùc döõ lieäu vaø Giaûi thuaät 415 Chöông 18 – ÖÙng duïng danh saùch lieân keát vaø baûng baêm Giaùo trình Caáu truùc döõ lieäu vaø Giaûi thuaät 416
DMCA.com Protection Status Copyright by webtailieu.net