Academia.eduAcademia.edu
Trương Hải Bằng-Cấu trúc dữ liệu 2 Tµi liÖu tham kh¶o hç trî m«n häc CÊu tróc d÷ liÖu 2 Trương Hải Bằng-Cấu trúc dữ liệu 2 http://www.ebook.edu.vn môc lôc Ch−¬ng 1. S¾p xÕp ngo¹i.................................................................................. 4 1.1. Thao t¸c trªn tÖp b»ng ng«n ng÷ lËp tr×nh C++ .....................................................4 1.1.1. §Þnh nghÜa tÖp ...................................................................................................4 1.1.2. C¸c kiÓu truy cËp tÖp: nhÞ ph©n vµ v¨n b¶n .......................................................5 1.1.3. C¸c hµm thao t¸c trªn tÖp ..................................................................................6 1.2. Ph−¬ng ph¸p trén run cã ®é dµi cè ®Þnh..................................................................7 1.2.1. M« t¶ thuËt to¸n.................................................................................................7 1.2.2. Cµi ®Æt ch−¬ng tr×nh ..........................................................................................9 1.3. Ph−¬ng ph¸p trén run tù nhiªn...............................................................................14 1.3.1. M« t¶ thuËt to¸n...............................................................................................14 1.3.2. Cµi ®Æt ch−¬ng tr×nh ........................................................................................15 1.4. Ph−¬ng ph¸p trén ®a lèi c©n b»ng (Balanced multiway merging).........................20 1.4.1. M« t¶ thuËt to¸n...............................................................................................20 1.4.2. Cµi ®Æt ch−¬ng tr×nh ........................................................................................21 1.5. Ph−¬ng ph¸p trén ®a pha (Polyphase merge)........................................................28 Ch−¬ng 2. B¶ng b¨m (Hash table) ................................................................ 29 2.1. Më ®Çu....................................................................................................................29 2.2. C¸c ph−¬ng ph¸p tr¸nh ®ông ®é ............................................................................30 2.2.1. Dïng danh s¸ch liªn kÕt ..................................................................................30 2.2.2. Dïng danh s¸ch kÒ ngoµi ................................................................................31 2.2.3. Ph−¬ng ph¸p dß tuyÕn tÝnh (linear probing method) ......................................31 2.2.4. Ph−¬ng ph¸p dß bËc hai (quadratic probing method) ....................................32 2.3. Cµi ®Æt b¶ng b¨m....................................................................................................32 2.3.1. Cµi ®Æt b¶ng b¨m dïng danh s¸ch liªn kÕt ngoµi ...........................................32 2.3.2. Cµi ®Æt b¶ng b¨m dïng danh s¸ch kÒ ngoµi ...................................................37 2.3.3. Cµi ®Æt b¶ng b¨m dïng liªn kÕt trong .............................................................43 2.3.4. Vµi nhËn xÐt vÒ b¶ng b¨m ...............................................................................45 Ch−¬ng 3. C©y ®á ®en .................................................................................... 46 3.1. Më ®Çu....................................................................................................................46 3.2. C©y nhÞ ph©n t×m kiÕm ............................................................................................47 3.3. C©y 2-3-4 ................................................................................................................48 3.3.1. §Þnh nghÜa c©y 2-3-4.......................................................................................48 3.3.2. T×m kiÕm trªn c©y 2-3-4..................................................................................49 3.3.3. Thªm khãa vµo c©y 2-3-4 ...............................................................................49 3.3.4. Lo¹i bá khãa trªn c©y 2-3-4 ...........................................................................50 3.3.5. Ph©n tÝch c¸c thuËt to¸n trªn c©y 2-3-4 ..........................................................52 3.4. C©y ®á ®en (Red-black tree) ...................................................................................52 http://www.ebook.edu.vn Trương Hải Bằng-Cấu trúc dữ liệu 2 3.4.1. §Þnh nghÜa .......................................................................................................52 3.4.2. Sù t−¬ng ®−¬ng gi÷a c©y ®á ®en vµ c©y 2-3-4................................................53 3.5. C©y c©n b»ng chiÒu cao (Height balanced tree) ....................................................53 3.5.1. Thao t¸c xoay c©y nhÞ ph©n.............................................................................53 3.5.2. ChØ sè c©n b»ng (balance factor) cña mét nót trªn c©y AVL ..........................54 3.5.3. C©n b»ng l¹i c©y khi thªm nót .........................................................................54 3.5.4. Xo¸ nót trªn c©y AVL ....................................................................................59 3.5.5. Vµi nhËn xÐt vÒ c©y AVL ................................................................................62 3.5.6. Cµi ®Æt c©y AVL.............................................................................................63 3.5.7. Cµi ®Æt c©y AVL trªn bé nhí ngoµi...............................................................73 Ch−¬ng 4. B - c©y vµ bé nhí ngoµi................................................................ 74 4.1. Më ®Çu....................................................................................................................74 4.2. B - c©y .....................................................................................................................74 4.2.1. C©y t×m kiÕm nhiÒu nh¸nh (Multiway Search Tree) .......................................74 4.2.2. §Þnh nghÜa B - c©y...........................................................................................75 4.2.3. T×m kiÕm trªn B - c©y......................................................................................75 4.2.4. Thªm khãa vµo B - c©y ...................................................................................75 4.2.5. Lo¹i bá khãa trªn B - c©y ................................................................................76 4.2.6. Ph©n tÝch c¸c thuËt to¸n trªn B - c©y ...............................................................78 4.3. Cµi ®Æt B - c©y ........................................................................................................78 4.4. B - c©y vµ bé nhí ngoµi ........................................................................................87 C©u hái vµ bµi tËp.............................................................................................. 89 Ch−¬ng 1. S¾p xÕp ngo¹i ...........................................................................................89 Ch−¬ng 2. B¶ng b¨m .................................................................................................89 Ch−¬ng 3. C©y ®á ®en ...............................................................................................90 Ch−¬ng 4. B-c©y ........................................................................................................90 C¸c bµi tËp lín dµnh cho sinh viªn kh¸ giái ................................................................90 Tµi liÖu tham kh¶o............................................................................................. 92 C¸c c©u hái lý thuyÕt vµ c¸c bµi thùc hµnh chuÈn bÞ cho thi hÕt m«n ......... 93 A. PhÇn lý thuyÕt............................................................................................................93 B. PhÇn thùc hµnh..........................................................................................................95 http://www.ebook.edu.vn Trương Hải Bằng-Cấu trúc dữ liệu 2 Ch−¬ng 1 S¾p xÕp ngo¹i Trong nhiÒu øng dông cña tin häc, ta ph¶i s¾p xÕp c¸c tËp tin rÊt lín. VÝ dô tÖp tin l−u th«ng tin nh©n sù cña mét tËp ®oµn s¶n xuÊt lín cã thÓ chøa hµng chôc ngµn b¶n ghi, mçi b¶n ghi l¹i chøa rÊt nhiÒu th«ng tin: hä tªn, quª qu¸n, ngµy sinh, qu¸ tr×nh c«ng t¸c,...NÕu cÇn s¾p xÕp theo mét tr−êng nµo ®ã nh− ngµy sinh ch¼ng h¹n, nÕu chØ sö dông ph−¬ng ph¸p s¾p xÕp trong bé nhí (internal sorting) th× ta ph¶i ®æ tÊt c¶ d÷ liÖu vµo bé nhí RAM vµ cã thÓ bé nhí nµy kh«ng ®ñ ®Ó chøa d÷ liÖu. Trong nh÷ng tr−êng hîp nµy ng−êi ta ph¶i t×m c¸ch s¾p xÕp tËp tin mµ chØ ®æ mét phÇn rÊt nhá d÷ liÖu vµo bé nhí cßn phÇn lín c¸c thao t¸c ®−îc thùc hiÖn trùc tiÕp trªn tËp tin. C¸ch s¾p xÕp nh− thÕ nµy ®−îc gäi lµ s¾p xÕp ngo¹i (external sorting). Khi s¾p xÕp mét d·y c¸c phÇn tö trong bé nhí ta cã thÓ truy xuÊt dÔ dµng c¸c thµnh phÇn cña d·y. VÝ dô ta cã thÓ ®æi chç c¸c phÇn tö, dÞch chuyÓn chóng b»ng c¸c phÐp g¸n gÇn nh− ®−îc thùc hiÖn tøc thêi. ViÖc truy xuÊt c¸c phÇn tö trªn tÖp, nhÊt lµ tÖp truy xuÊt tuÇn tù nh− b¨ng tõ ch¼ng h¹n, sÏ khã kh¨n vµ tèn kÐm h¬n nhiÒu so víi truy xuÊt trong bé nhí. V× vËy viÖc s¾p xÕp ngo¹i ph¶i xem viÖc h¹n chÕ dÞch chuyÓn vµ truy xuÊt trªn tÖp lµ mét ®iÒu kiÖn quan träng. Trong c¸c ph−¬ng ph¸p truyÒn thèng, ng−êi ta thÊy r»ng ph−¬ng ph¸p trén lµ thÝch hîp h¬n c¶ cho c«ng viÖc nµy. Trong ch−¬ng nµy chóng ta sÏ t×m hiÓu mét sè ph−¬ng ph¸p s¾p xÕp ngo¹i th−êng dïng lµ: trén c¸c run cã ®é dµi cè ®Þnh, trén tù nhiªn, trén ®a lèi c©n b»ng vµ trén ®a pha. MÆc dÇu trong thùc tÕ c¸c phÇn tö cña tËp tin th−êng lµ cã cÊu tróc phøc t¹p, nh−ng ®Ó ®¬n gi¶n vµ lét t¶ ®−îc b¶n chÊt thuËt to¸n, chóng ta chØ xÐt tËp tin nhÞ ph©n chøa c¸c phÇn tö lµ c¸c sè thùc (mçi sè thùc ®−îc chøa trong 4 byte). Chóng t«i kh«ng chän tr−êng hîp ®¬n gi¶n h¬n n÷a lµ c¸c ký tù hoÆc sè nguyªn, v× lo¹i d÷ liÖu nµy dÔ nhÇm víi chØ sè. Tr−íc khi t×m hiÓu cô thÓ c¸c thuËt to¸n, chóng t«i tãm t¾t l¹i mét sè lÖnh C++ liªn quan ®Õn tÖp. 1.1. Thao t¸c trªn tÖp b»ng ng«n ng÷ lËp tr×nh C++ Trong ch−¬ng nµy chóng ta sÏ nghiªn cøu vµ cµi ®Æt c¸c thuËt to¸n s¾p xÕp trªn tÖp b»ng ng«n ng÷ C++. §Ó c¸c b¹n nghe gi¶ng vµ ®äc tµi liÖu ®−îc thuËn lîi h¬n, sau ®©y chóng t«i xin giíi thiÖu s¬ l−îc vÒ c¸c thao t¸c trªn tÖp b¨ng ng«n ng÷ C++. Chóng t«i sÏ kh«ng giíi thiÖu chi tiÕt có ph¸p c¸c lÖnh, v× chóng ta cÇn dµnh thêi gian cho néi dung chÝnh lµ "CÊu tróc d÷ liÖu". 1.1.1. §Þnh nghÜa tÖp TÖp thùc chÊt lµ mét tËp hîp th«ng tin ®−îc ®Æt tªn trªn thiÕt bÞ nhí ngo¹i vi nh− ®Üa cøng, ®Üa mÒm, ®Üa CD, USB, b¨ng tõ...(tõ nay vÒ sau ta gäi ®¬n gi¶n lµ ®Üa). VÒ mÆt vËt lý, th«ng tin trªn tÖp cã thÓ kh«ng ®−îc l−u tr÷ mét c¸ch liªn tôc, nghÜa lµ c¸c phÇn cña tÖp cã thÓ n»m r¶i r¸c ë nhiÒu vÞ trÝ trªn ®Üa, nh−ng vÒ mÆt logic th× cã thÓ xem tÖp lµ mét d∙y liªn tiÕp c¸c byte tr¶i dµi liªn tôc tõ ®Çu tÖp ®Õn cuèi tÖp. Th−êng th× ë cuèi tÖp chøa mét sè byte cã gi¸ trÞ tèi ®a, tøc lµ tÊt c¶ gi¸ trÞ trong c¸c bit ®Òu b»ng 1 (nh− vËy m· ASCII më réng cña byte lµ 11111111 = 255). Tuy nhiªn c¸c byte nµy kh«ng ®−îc tÝnh vµo ®é lín cña tÖp. NÕu b¹n më mét tÖp vµ ch−a nhËp g× c¶ th× tÖp cã ®é lín = 0 byte, cßn nÕu b¹n nhËp vµo mét ký tù th× ®é lín tÖp lµ 1. HÖ ®iÒu hµnh sö dông b¶ng FAT (File Allocation Table) vµ b¶ng th− môc (Directory Table) ®−îc l−u tr÷ trªn ®Üa (th−êng lµ ë vïng ®Çu cña ®Üa) ®Ó l−u gi÷ c¸c th«ng tin liªn quan ®Õn tÖp. B¶ng th− môc chøa th«ng tin vÒ tªn tËp tin, kÝch cì tÝnh theo byte, ngµy cËp nhËt cuèi cïng, thuéc tÝnh, vÞ trÝ b¾t ®Çu trªn ®Üa,... cßn tÖp FAT ghi l¹i th«ng tin vÒ sù kÕt nèi c¸c vïng l−u tr÷ tÖp trªn ®Üa. C¸c byte trong tÖp cã thÓ cã gi¸ trÞ bÊt kú tõ 0 - 255. Tuy nhiªn nÕu ta dïng c¸c ch−¬ng tr×nh so¹n th¶o v¨n b¶n nh− NCEDIT hoÆc C hay Pascal th× chØ nhËp ®−îc c¸c ký tù cã trªn bµn phÝm do ®ã néi dung tÖp tr«ng nh− mét v¨n b¶n cã thÓ ®äc ®−îc. NÕu ta dïng ch−¬ng tr×nh so¹n th¶o v¨n b¶n ®Ó xem mét tÖp bÊt kú, vÝ dô tÖp cã ®u«i .EXE th× sÏ thÊy cã nhiÒu ký tù l¹, v× khi ®ã ch−¬ng tr×nh so¹n th¶o v¨n b¶n ®· cho hiÖn lªn c¶ nh÷ng ký tù kh«ng cã trªn bµn phÝm. http://www.ebook.edu.vn Trương Hải Bằng-Cấu trúc dữ liệu 2 1.1.2. C¸c kiÓu truy cËp tÖp: nhÞ ph©n vµ v¨n b¶n Trong ng«n ng÷ C++ ta cã thÓ truy cËp tÖp b»ng 2 c¸ch: nhÞ ph©n hoÆc v¨n b¶n. Víi mét tÖp bÊt kú ta ®Òu cã thÓ më vµ thao t¸c theo kiÓu nhÞ ph©n hoÆc v¨n b¶n. Hai c¸ch thao t¸c nµy cã mét sè kh¸c biÖt nh− sau: • Trong tÖp v¨n b¶n nÕu ta ghi vµo ký tù cã m· lµ 26 (tøc Ctrl+Z), hoÆc -1 (chÝnh lµ 255 nÕu lµ ký tù kh«ng dÊu unsigned char) th× khi ta dïng hµm fgetc() ®Ó ®äc khi gÆp gi¸ trÞ nµy ta sÏ nhËn ®−îc c = -1 (tøc lµ gi¸ trÞ cña h»ng EOF cã s½n trong C). Lóc nµy gi¸ trÞ cña hµm feof() sÏ nhËn gi¸ trÞ ®óng (tøc lµ gi¸ trÞ # 0) vµ ta kh«ng thÓ ®äc tiÕp ®−îc c¸c ký tù sau ®ã. • §èi víi tÖp v¨n b¶n khi ta ghi vµo tÖp ký tù cã m· 10 (LF = Line Feed tøc lµ xuèng dßng) th× C tù ®éng thªm ký tù 13 (CR = Carriage Return, tøc lµ ®−a con ch¹y vÒ ®Çu dßng) vµo tÖp phÝa tr−íc ký tù 10 (B¹n cã thÓ thö ®iÒu nµy: nÕu tÖp më theo kiÓu nhÞ ph©n th× khi ®−a ký tù 10 vµo tÖp cã ®é lín lµ 1, cßn nÕu më tÖp theo kiÓu v¨n b¶n th× tÖp l¹i cã ®é lín lµ 2 v× ®· ®−îc ghi thªm ký tù 13). • Víi tÖp nhÞ ph©n th× cho dï bªn trong tÖp cã chøa mét d·y liªn tiÕp c¸c ký tù -1 th× C vÉn kh«ng coi ®ã lµ cuèi tÖp. Nh− vËy víi tÖp nhÞ ph©n th× nhËn biÕt cuèi tÖp kh«ng chØ tõ c¸c ký tù ë cuèi tÖp. §Ó hiÓu râ h¬n nh÷ng ®iÒu trªn ®©y b¹n h·y ch¹y thö ch−¬ng tr×nh sau: void ThuTep() {FILE * f = fopen("a.dat","w+t"); fputc('A',f); fputc(26,f); fputc('B',f); fputc(255,f); fputc(255,f); fputc(10,f); fclose(f); char c; f = fopen("a.dat","rb"); while(!feof(f)) {c = fgetc(f);printf("%d ",c);} fclose(f); f = fopen("a.dat","rt"); printf("\n"); while(!feof(f)) {c = fgetc(f);printf("%d ",c); } fclose(f); } KÕt qu¶ trªn mµn h×nh lµ: 65 26 66 -1 -1 13 10 -1 65 -1 V× ta t¹o tÖp theo kiÓu v¨n b¶n nªn khi ghi lªn tÖp ký tù 10 th× ký tù 13 còng ®−îc chÌn vµo phÝa tr−íc (vËy lµ tr−íc khi xuèng dßng ph¶i vÒ ®Çu dßng). NÕu ta më l¹i tÖp theo kiÓu nhÞ ph©n th× cã thÓ ®äc ®−îc tÊt c¶ c¸c ký tù ®· ghi vµo. Cßn nÕu ta më tÖp theo kiÓu v¨n b¶n th× khi gÆp ký tù 26 ch−¬ng tr×nh cho lµ ®· hÕt tÖp vµ g¸n c = -1. Còng vÝ dô trªn nh−ng chóng ta thay lÖnh f = fopen("a.dat","w+t"); b»ng lÖnh f = fopen("a.dat","w+b"); th× kÕt qu¶ lµ: 65 26 66 -1 -1 10 -1 65 -1 Tøc lµ ký tù 13 kh«ng bÞ chÌn vµo tr−íc ký tù 10 nh− tr−êng hîp tÖp v¨n b¶n. http://www.ebook.edu.vn 5 Trương Hải Bằng-Cấu trúc dữ liệu 2 1.1.3. C¸c hµm thao t¸c trªn tÖp MÆc dÇu tÖp lµ tËp hîp th«ng tin ®−îc ®Æt tªn vµ ®−îc l−u tr÷ trªn ®Üa, nh−ng khi thao t¸c trªn tÖp th× tªn tÖp kh«ng ®−îc sö dông trùc tiÕp. C dïng mét con trá tÖp ®−îc l−u trong bé nhí ®Ó thao t¸c trªn tÖp. Con trá nµy cã kiÓu FILE, lµ mét kiÓu cÊu tróc ®−îc ®Þnh nghÜa s½n trong STDIO.H. a. Më vµ ®ãng tÖp Më tÖp: Có ph¸p: <Con trá tÖp> = fopen(<Tªn tÖp>,<KiÓu më>); <KiÓu më> lµ chuçi gåm 2 ký tù ®−îc quy ®Þnh nh− sau: ký tù ®Çu cho biÕt tÖp ®−îc më míi chØ ®äc, më míi cã thÓ ®äc ghi, më tÖp cã s½n chØ ®äc hay më tÖp cã s½n cã thÓ ®äc ghi; ký tù thø 2 cho biÕt c¸ch thøc truy cËp: b (binary) lµ nhÞ ph©n cßn t (text) lµ v¨n b¶n. Ta cã thÓ tãm t¾t c¸c <KiÓu më> trong b¶ng sau: KiÓu ý nghÜa KiÓu ý nghÜa më më wb Më tÖp nhÞ ph©n míi chØ ghi (nh− wt Më tÖp v¨n b¶n míi chØ ghi (nh− vËy vËy nÕu ®· cã tÖp cò cïng tªn th× nÕu ®· cã tÖp cò cïng tªn th× tÖp cò sÏ bÞ tÖp cò sÏ bÞ xãa) xãa) w+b Më tÖp nhÞ ph©n míi ®äc/ ghi w+t Më tÖp v¨n b¶n míi ®äc/ ghi rb Më tÖp nhÞ ph©n ®· cã chØ ®äc rt Më tÖp v¨n b¶n ®· cã chØ ®äc r+b Më tÖp nhÞ ph©n ®· cã ®äc/ ghi r+t Më tÖp v¨n b¶n ®· cã ®äc/ ghi §ãng tÖp: Có ph¸p: fclose(<Con trá tÖp>); VÝ dô ®o¹n ch−¬ng tr×nh sau sÏ t¹o mét tÖp cã tªn lµ A.DAT vµ ghi vµo 3 ký tù A,B,C råi ®ãng tÖp: FILE *f; f = fopen("A.DAT","wb"); fput('A',f); fput(66,f); fput('C',f); fclose(f). b. Ghi th«ng tin lªn tÖp Cã thÓ sö dông c¸c hµm sau ®Ó ghi th«ng tin lªn tÖp: - Ghi mét ký tù lªn vÞ trÝ hiÖn thêi cña tÖp: fput(<ký tù>, <con trá tÖp>); VÝ dô: fput('O',f); - Ghi mét chuçi ký tù lªn tÖp: fputs(<chuçi ký tù>, <Con trá tÖp>); VÝ dô: fputs("Chao",f); - Ghi c¸c biÓu thøc lªn tÖp: fprintf(<Con trá tÖp>,<Chuçi khu«n d¹ng>,<C¸c biÓu thøc>); LÖnh nµy ghi lªn tÖp m· ASCII cña c¸c ký tù VÝ dô lÖnh: fprintf(f,"A%6.1fB", 12.5); Ghi lªn tÖp 8 ký tù lµ 65 32 32 49 50 46 53 66 Ký tù 'A' DÊu c¸ch DÊu c¸ch Sè 1 Sè 2 DÊu . Sè 5 Ký tù B - Ghi c¸c khèi th«ng tin tõ mét ®Þa chØ trong bé nhí lªn vÞ trÝ hiÖn thêi cña tÖp: fwrite(<§Þa chØ>, <Sè byte mét khèi>, <Sè khèi>, <con trá tÖp>); VÝ dô: fwrite(&x, 12, 5, f); Cã nghÜa lµ lÊy th«ng tin trong 5 khèi d÷ liÖu, mçi khèi 12 byte, tæng céng lµ 12x5 = 60 byte b¾t ®Çu tõ ®Þa chØ cña biÕn x vµ ghi lªn vÞ trÝ hiÖn thêi cña tÖp. VÝ dô nµy chØ cã ý nghÜa minh häa, v× nÕu x lµ biÕn thùc th× chØ cã 4 byte t¹i ®Þa chØ cña nã lµ l−u gi¸ trÞ cña nã mµ th«i. c. §äc th«ng tin tõ tÖp vµ ®−a vµo biÕn bé nhí http://www.ebook.edu.vn 6 Trương Hải Bằng-Cấu trúc dữ liệu 2 C¸ch gi¶i thÝch c¸c lÖnh sau t−¬ng tù nh− tr−êng hîp ghi lªn tÖp nh−ng theo chiÒu ng−îc l¹i. ë ®©y chóng t«i chØ nªu c¸c vÝ dô: - char c = fgetc(f); §äc mét ký tù tõ vÞ trÝ hiÖn thêi cña tÖp vµ g¸n cho biÕn ký tù c. - fgets(<biÕn chuçi ký tù>,<Sè byte tèi ®a>, <con trá tÖp>);//LÖnh nµy chØ dïng cho tÖp v¨n b¶n. VÝ dô fgets(s, 100, f); //§äc tèi ®a lµ 100 ký tù tõ dßng hiÖn thêi (kÕt thóc b»ng dÊu xuèng dßng). Nh− vËy nÕu dßng cã 70 ký tù th× chØ ®äc 70 ký tù nµy. Cßn nÕu dßng cã 120 ký tù ch¼ng h¹n th× chØ ®äc 100 ký tù. V× mét dßng trong tÖp v¨n b¶n tèi ®a lµ 255 ký tù, nªn lÖnh fgets(s,255,f); sÏ b¶o ®¶m ®äc c¶ dßng v¨n b¶n. - fscanf(f,"%f", &x); SÏ ®äc sè ®−îc ghi d−íi d¹ng tõng ký tù riªng biÖt ë t¹i hoÆc sau vÞ trÝ hiÖn thêi cña con trá tÖp vµ g¸n cho biÕn x. - fread(<§Þa chØ>, <Sè byte mét khèi>, <Sè khèi>, <con trá tÖp>); VÝ dô: fread(&x, 12, 5, f); Cã nghÜa lµ lÊy th«ng tin trong 5 khèi d÷ liÖu, mçi khèi 12 byte, tæng céng lµ 12x5 = 60 byte trªn tÖp b¾t ®Çu tõ vÞ trÞ hiÖn thêi vµ g¸n cho biÕn x. VÝ dô nµy chØ cã ý nghÜa minh häa, v× nÕu x lµ biÕn thùc th× chØ cã 4 byte t¹i ®Þa chØ cña nã lµ l−u gi¸ trÞ cña nã mµ th«i. d. DÞch chuyÓn trªn tÖp Khi m«t tÖp më th× cã mét vÞ trÝ trªn tÖp ®−îc xem lµ con trá logic cña tÖp. Th«ng tin ®äc/ ghi trªn tÖp ®−îc thùc hiÖn tõ vÞ trÝ nµy. - LÖnh rewind(<Con trá tÖp>); sÏ ®−a con trá tÖp vÒ ®Çu tÖp. VÝ dô rewind(f); - fseek(<Con trá tÖp>, <Sè byte cÇn dÞch chuyÓn>, <VÞ trÝ xuÊt ph¸t>); <VÞ trÝ xuÊt ph¸t> = 0 nÕu xuÊt ph¸t tõ ®Çu tÖp, 1 nÕu xuÊt ph¸t tõ vÞ trÝ hiÖn thêi, 2 nÕu xuÊt ph¸t tõ cuèi tÖp. <Sè byte cÇn dÞch chuyÓn> > 0 sÏ dÞch chuyÓn vÒ cuèi tÖp, < 0 dÞch chuyÓn vÒ phÝa ®Çu tÖp. VÝ dô: fseek(f,0,0); lµ chuyÓn con trá vÒ ®Çu tÖp; fseek(f,0,2); lµ chuyÓn con trá vÒ cuèi tÖp. e. Hµm ftell() Hµm ftell(<con trá tÖp>) cho ta ®é lín cña tÖp tÝnh b»ng byte tÝnh tõ ®Çu tÖp ®Õn vÞ trÝ hiÖn thêi cña con trá. VÝ dô gi¶ sö tÖp víi con trá f chøa c¸c sè thùc ®−îc l−u theo kiÓu nhÞ ph©n (tøc lµ mét sè thùc chiÕm 4 byte) th× c¸c lÖnh sau sÏ cho ta n lµ sè phÇn tö trªn tÖp. fseek(f,0,2); n = ftell(f)/sizeof(float); 1.2. Ph−¬ng ph¸p trén run cã ®é dµi cè ®Þnh 1.2.1. M« t¶ thuËt to¸n Khi tr×nh bµy c¸c thuËt to¸n s¾p xÕp, ®Æc biÖt lµ ph−¬ng ph¸p trén, ta rÊt hay ph¶i dïng thuËt ng÷ "d·y ®· s¾p xÕp". V× vËy ng−êi ta ®· thay thuËt ng÷ nµy b»ng mét tõ ®¬n gi¶n lµ "Run". Chóng ta sÏ kh«ng dÞch thuËt ng÷ nµy sang tiÕng ViÖt v× rÊt khã t×m ®−îc tõ thÝch hîp. V× c¸c phÇn tö cña tËp tin vÒ mÆt logic cã thÓ xem lµ mét d·y tuyÕn tÝnh liªn tôc tõ ®Çu ®Õn cuèi tÖp, do ®ã ta cã thÓ dïng mét d·y c¸c phÇn tö A = {a0, a1,..., an-1} ®Ó m« t¶ c¸c phÇn tö trªn tÖp. ThuËt to¸n nµy cã thÓ m« t¶ nh− sau: B−íc 1: Ta xem tÖp A gåm n run 1 phÇn tö (mçi run cã ®é dµi cè ®Þnh p = 1). Ta sÏ lÇn l−ît ph©n bæ n run cho 2 tÖp B vµ C theo c¸ch a0 cho B, a1 cho C, a2 cho B... cø nh− thÕ cho ®Õn khi A hÕt phÇn tö. Cã thÓ thÊy r»ng nÕu n ch½n th× sè run trªn B vµ C n n nh− nhau, cßn nÕu n lÎ th× trªn B cã [ ]+1 run, cßn trªn C cã [ ] run. 2 2 http://www.ebook.edu.vn 7 Trương Hải Bằng-Cấu trúc dữ liệu 2 TiÕp theo ta lÇn l−ît trén tõng cÆp run trªn B vµ C víi nhau vµ ghi vµo A. NÕu sè run trªn B nhiÒu h¬n th× run cuèi cïng trªn B sÏ ®−îc ®−a vµo A mµ kh«ng ph¶i trén g× c¶. Trõ run cuèi cïng cã thÓ chØ cã 1 phÇn tö, c¸c run trªn A b©y giê ®· cã 2 phÇn tö. Vµ n n sè run lµ ⎡ ⎤ (hµm trÇn cña . 2 2 NÕu tËp A chØ gåm 2 phÇn tö th× trªn A b©y giê chØ cã 1 run duy nhÊt vµ viÖc s¾p xÕp hoµn tÊt. NÕu n>2 ta ®Æt p = p*2 = 2 vµ chuyÓn sang b−íc 2. Gi¶ sö d·y trong tÖp A lµ c¸c phÇn tö 1 2 9 8 7 6 5 ta cã thÓ m« t¶ b−íc nµy trong b¶ng sau: A B C A' 1 1 2 1 2 9 8 2 9 8 7 6 5 7 5 6 8 9 6 7 5 .. . B−íc k: Lóc nµy trõ run cuèi cïng, c¸c run trªn A ®é dµi cè ®Þnh p = 2(k-1) (cã tÊt c¶ [ n ]+1 p run). Ta sÏ lÇn l−ît ph©n bæ c¸c run cho 2 tÖp B vµ C. TiÕp theo ta lÇn l−ît trén tõng cÆp run trªn B vµ C víi nhau vµ ghi vµo A. Víi k = 2 trong vÝ dô trªn ta cã p = 2 vµ kÕt qu¶ ®−îc thÓ hiÖn trong b¶ng sau: A 1 2 8 9 6 7 5 B 1 2 6 7 C 8 9 5 A' 1 2 8 9 5 6 7 §Æt p = p*2. NÕu p ≥ n th× trªn A b©y giê chØ cã 1 run duy nhÊt vµ viÖc s¾p xÕp hoµn tÊt. NÕu p < n chuyÓn sang b−íc k+1. ... Trong vÝ dô trªn t¹i b−íc k = 3 ta cã p = 4 vµ kÕt qu¶ ph©n bæ vµ trén ®−îc thÓ hiÖn trong b¶ng sau: A 1 2 8 9 5 6 7 B 1 2 8 9 C 5 6 7 A' 1 2 5 6 7 8 9 Khi ®Æt p = p* 2 = 8 ta thÊy p ≥ n do ®ã xÕp. A chØ chøa mét run vµ tÖp A ®· ®−îc s¾p ThuËt to¸n trªn còng cã thÓ m« t¶ gän h¬n nh− sau: Input: TÖp A cã n phÇn tö th−êng lµ ch−a s¾p xÕp. Output: TÖp A ®−îc s¾p xÕp. B1. §Æt p = 1. ChuyÓn sang b−íc B2. B2. TÖp A gåm c¸c run ®é dµi p. Ta t¹o míi 2 tÖp B vµ C råi lÇn l−ît ph©n bæ c¸c run trªn A sang B vµ C cho ®Õn khi hÕt run trªn A. ChuyÓn sang b−íc B3. http://www.ebook.edu.vn 8 Trương Hải Bằng-Cấu trúc dữ liệu 2 B3. T¹o míi tÖp A sao cho trong A kh«ng chøa phÇn tö nµo. LÇn l−ît trén tõng cÆp run ®é dµi p (trõ run cuèi cïng trªn B hoÆc C cã thÓ cã ®é dµi ng¾n h¬n) trªn B vµ C råi ®−a vµo A cho ®Õn khi hÕt run trªn c¶ B vµ C. L−u ý lµ cÆp run cuèi cïng cã thÓ cã mét run rçng, lóc nµy phÐp trén ®−îc hiÓu lµ ®−a toµn bé run kh¸c rçng vµo A. B4. Sau khi thùc hiÖn b−íc B3 ta ®· cã trªn A c¸c run cã ®é dµi 2*p (trõ run cuèi cïng cã thÓ ng¾n h¬n). Do ®ã ta ®Æt p = p*2. NÕu p ≥ n th× kÕt thóc. NÕu kh«ng th× quay l¹i B2. Trong c¸c thuËt to¸n s¾p xÕp ngo¹i cßn l¹i chóng t«i ®Ó l¹i c¸ch m« t¶ thuËt to¸n nh− trªn ®©y cho c¸c b¹n sinh viªn thùc hiÖn. Chóng t«i sÏ dïng c¸ch m« t¶ dïng gi¶ ng«n ng÷ C (tøc lµ ng«n ng÷ gÇn gièng víi C, chñ yÕu ®Ó hiÓu ®−îc ý t−ëng thuËt to¸n) nh− sau: §Æt p = 1 while (p<n) { - T¹o míi 2 tÖp B vµ C råi lÇn l−ît ph©n bæ c¸c run cã ®é dµi p tõ tÖp A sang 2 tÖp B vµ C theo c¸ch: mét run sang B th× run tiÕp theo sang C, run sau ®ã sang B,... cho ®Õn khi hÕt run trªn A. Nh− vËy tÖp B cã thÓ chøa nhiÒu h¬n tÖp C mét run vµ run cuèi cïng trªn B cã thÓ cã ®é dµi < p. (NÕu n ch½n th× run cuèi cïng trªn C cã thÓ cã ®é dµi < p). - TiÕp theo t¹o míi tÖp A råi trén tõng cÆp run cã ®é dµi p trªn B vµ C thµnh mét run cã ®é dµi p*2 vµ l−u vµo tÖp A. Sau khi hoµn tÊt, tÖp A chøa c¸c run cã ®é dµi p*2 (trõ run cuèi cïng cã thÓ cã ®é dµi ng¾n h¬n). - §Æt p = p*2 (vµ chuyÓn sang vßng lÆp tiÕp theo). } 1.2.2. Cµi ®Æt ch−¬ng tr×nh Ch−¬ng tr×nh 11SXF.CPP sau ®©y cµi ®Æt thuËt to¸n s¾p xÕp mét tÖp b»ng ph−¬ng ph¸p trén ®é dµi run cè ®Þnh (hay cßn gäi lµ trén trùc tiÕp) trªn tÖp nhÞ ph©n. PhÇn khai b¸o chung, khai b¸o nguyªn mÉu hµm vµ hµm main: //11SXF.CPP Sap xep file bang phuong phap tron truc tiep tren tep nhi phan #include <conio.h> #include <stdio.h> #define true 1 #define false 0 #define sz (sizeof(float)) int FileNodes(char *TenTep); int EoF(FILE *f); void CreateFile(char *TenTep); void ViewFile(char *TenTep); void SplitFile(char *tepA,char *tepB, char *tepC, int p); void MergeFile(char *tepB,char *tepC, char *tepA, int p); void SortFile(char *TenTep); //===================== void main() {clrscr(); char *TenTep="A.DAT"; CreateFile(TenTep); ViewFile(TenTep); printf("\n\nTep sau khi sap xep la:"); SortFile(TenTep); ViewFile(TenTep); http://www.ebook.edu.vn 9 Trương Hải Bằng-Cấu trúc dữ liệu 2 getch(); }; Hµm int FileNodes(char *TenTep): Tr¶ vÒ sè phÇn tö (tøc lµ c¸c sè thùc) cã trong tÖp. Hµm nµy thùc hiÖn c«ng viÖc sau: chuyÓn vÒ cuèi tÖp. Dïng hµm ftell() ®Ó biÕt ®−îc tæng sè byte cña tÖp. LÊy tæng sè byte chia cho sè byte cña mét sè thùc th× ®−îc sè phÇn tö trong tÖp. int FileNodes(char *TenTep) {int k;float x; FILE *f = fopen(TenTep,"rb"); fseek(f,0,2);//Ve cuoi tep k = ftell(f)/sz; fclose(f); return(k); }; Hµm int EoF(FILE *f) : Tr¶ vÒ gi¸ trÞ true nÕu con trá tÖp ®· ®i qua sè thùc cuèi cïng trong tÖp. Së dÜ ta ph¶i dïng hµm nµy thay cho hµm feof() cña C v× lý do sau: Gi¶ sö ta ch¹y ®o¹n ch−¬ng tr×nh sau: float x; while(!feof(f)) {fread(&x,sz,1,f); cout<<x;} gi¶ sö phÇn tö cuèi cïng trªn tÖp lµ 10. Khi ®ã cã tr−êng hîp sau khi ®äc xong phÇn tö cuèi cïng nµy th× hµm feof(f) vÉn ch−a cã gi¸ trÞ true, nghÜa lµ !feof() vÉn nhËn gi¸ trÞ true vµ lÖnh fread vÉn ®−îc thùc hiÖn. Tuy nhiªn v× ®· v−ît qua sè thùc cuèi cïng nªn lÖnh nµy kh«ng ®äc ®−îc g× vµ gi¸ trÞ x vÉn lµ 10. Nh− vËy ta sÏ thÊy trªn mµn h×nh gi¸ trÞ 10 xuÊt hiÖn 2 lÇn. §iÒu nµy lµ kh«ng ®óng. Hµm EoF() ho¹t ®éng nh− sau: nÕu lÖnh fread ®äc ®−îc th«ng tin th× cã nghÜa lµ vÞ trÝ hiÖn thêi ch−a v−ît qua sè thùc cuèi cïng trong tÖp. §iÒu nµy cã nghÜa lµ vÞ trÝ tr−íc khi gäi hµm ch−a ph¶i ë cuèi tÖp vµ hµm tr¶ vÒ gi¸ trÞ false. Tuy nhiªn tr−íc khi tho¸t khái hµm cÇn lïi l¹i mét sè thùc ®Ó trë vÒ ®óng vÞ trÝ tr−íc khi gäi hµm. Cßn nÕu kh«ng ®äc ®−îc th«ng tin th× cã nghÜa lµ ®· v−ît qua sè thùc cuèi cïng vµ nh− vËy ®· ë cuèi tÖp. Trong tr−êng hîp nµy hµm tr¶ vÒ gi¸ trÞ true vµ còng kh«ng cÇn lïi l¹i. int EoF(FILE *f) {float x; if(fread(&x,sz,1,f)>0) {fseek(f,-1.0*sz,1); return(false); }; return(true); } Hµm void CreateFile(char *TenTep) : T¹o tÖp vµ nhËp vµo n sè thùc void CreateFile(char *TenTep) {int i,m;float x; FILE* f; f = fopen(TenTep,"wb"); rewind(f); char ch; do {clrscr(); printf("\nNhap du lieu vao tep:"); printf("\n1. Nhap truc tiep"); printf("\n2. Tao ngau nhien"); http://www.ebook.edu.vn 10 Trương Hải Bằng-Cấu trúc dữ liệu 2 printf("\n\n Hay chon 1 hoac 2: "); ch=getche(); } while(ch!='1'&& ch!='2'); printf("\nCho biet so phan tu can dua vao tep: "); scanf("%d",&m); if(ch=='1') {printf("\nHay nhap %d so: ",m); for(i=0;i<m;i++) {scanf("%f",&x); fwrite(&x,sz,1,f); } } else {randomize(); for(i=0;i<m;i++) {x=float(random(5*m)); fwrite(&x,sz,1,f); } } fclose(f); }; Hµm void ViewFile(char *TenTep) : Më mét tÖp nhÞ ph©n ®· cã vµ ®äc c¸c sè thùc ®−îc l−u trong tÖp vµ cho hiÖn lªn mµn h×nh. void ViewFile(char *TenTep) {float x; FILE* f; f = fopen(TenTep,"rb"); rewind(f); printf("\nCac phan tu tren tep %s: ",TenTep); while(fread(&x,sz,1,f)>0) printf("%5.0f",x); fclose(f); }; Hµm void SplitFile(char *tepA,char *tepB, char *tepC, int p) Gi¶ sö r»ng trªn tÖp A gåm c¸c run ®é dµi p (trõ run cuèi cïng). Hµm nµy lÇn l−ît ®äc c¸c run tõ tÖp A vµ ph©n bæ vµo 2 tÖp B vµ C. V× A lµ tÖp nguån, cßn B vµ C lµ c¸c tÖp ®Ých, nªn tÖp A ®−îc më chØ ®äc, cßn 2 tÖp B vµ C th× ®−îc më míi chØ ghi. LÖnh while(!EoF(a)) lµ ®iÒu kiÖn ®Ó kÕt thóc qu¸ tr×nh ph©n bæ. Râ rµng nÕu trªn tÖp A cßn phÇn tö (!EoF(a)) th× qu¸ tr×nh ph©n bæ ch−a kÕt thóc. Qu¸ trÝnh ph©n bæ run bao giê còng b¾t ®Çu b»ng viÖc ®äc mét run trong tÖp A vµ ghi vµo tÖp B. BiÕn dem ghi l¹i sè phÇn tö cña run hiÖn thêi ®· ®−îc ®äc vµ ghi vµo B. NÕu sè phÇn tö cßn trªn A mµ nhá h¬n p th× qu¸ tr×nh kÕt thóc tr−íc khi ®äc ®ñ p phÇn tö. Cßn nÕu kh«ng th× ®äc ®ñ p phÇn tö ghi vµo B sau ®ã chuyÓn sang ®äc p phÇn tö tiÕp theo ghi vµo C. Qu¸ tr×nh ghi vµo tÖp C còng t−¬ng tù nh− qu¸ tr×nh ghi vµo B. void SplitFile(char *tepA,char *tepB, char *tepC, int p) {FILE *a,*b,*c;float x;int dem; a = fopen(tepA,"rb"); b = fopen(tepB,"wb"); http://www.ebook.edu.vn 11 Trương Hải Bằng-Cấu trúc dữ liệu 2 c = fopen(tepC,"wb"); rewind(a);rewind(b);rewind(c); while(!EoF(a)) {//Chia p phan tu cho b dem = 0; while(dem<p && !EoF(a)) {fread(&x,sz,1,a); fwrite(&x,sz,1,b); dem++; } dem = 0; while(dem<p && !EoF(a)) {fread(&x,sz,1,a); fwrite(&x,sz,1,c); dem++; } } fclose(a);fclose(b);fclose(c); }; Hµm void MergeFile(char *tepB,char *tepC, char *tepA, int p) sÏ trén tõng cÆp run ®é dµi p tõ tÖp B vµ tÖp C thµnh mét run ®é dµi 2*p vµ ®−a vµo tÖp A (trõ run cuèi cïng). V× B vµ C lµ c¸c tÖp nguån, cßn A lµ tÖp ®Ých, nªn 2 tÖp B vµ C ®−îc më chØ ®äc, cßn tÖp A ®−îc më míi chØ ghi. V× qu¸ tr×nh trén chØ thùc hiÖn khi c¶ hai tÖp B vµ C ®Òu cßn phÇn tö. NÕu mét trong hai tÖp hÕt phÇn tö th× cã nghÜa lµ c¸c phÇn tö cßn l¹i ë tÖp kia kh«ng cßn run ®Ó trén vµ ®−îc chuyÓn sang tÖp A mµ kh«ng cÇn so s¸nh g× c¶. VËy lÖnh while(!EoF(b) && !EoF(c)) cã nghÜa lµ qu¸ tr×nh trén ®−îc tiÕp tôc nÕu c¶ hai tÖp A vµ B ®Òu cßn phÇn tö. V× sè phÇn tö trong mçi run kh«ng v−ît qu¸ p nªn ta dïng biÕn ix ®Ó ghi l¹i sè phÇn tö trong run hiÖn thêi cña tÖp B ®· ®−îc ghi sang A. T−¬ng tù, biÕn iy lµ sè phÇn tö trong run hiÖn thêi cña C ®· ®−îc ghi sang A. Khi míi b¾t ®Çu th× c¶ hai run ®Òu cã phÇn tö nªn ta ®äc lÇn l−ît phÇn tö ®Çu tiªn cña run trong B vµo x, vµ phÇn tö ®Çu tiªn trong run ë C vµo y b»ng c¸c lÖnh: fread(&x,sz,1,b); fread(&y,sz,1,c); Sau ®ã qu¸ tr×nh trén run ®−îc tiÕn hµnh. Qu¸ tr×nh nµy ®−îc thùc hiÖn nÕu ®iÒu kiÖn ix<p&&iy<p cßn tháa m·n. Trong ch−¬ng tr×nh ta thÊy lÖnh: while(ix<p && iy<p) Ta b¾t ®Çu so s¸nh hai phÇn tö ®Çu run b»ng lÖnh if(x<y). NÕu ®iÒu kiÖn nµy ®óng th× ta ghi x vµo A, t¨ng ix lªn 1. §ång thêi kiÓm tra xem nÕu ®· hÕt run trªn B (tøc lµ ix==p hoÆc EoF(b) th× ghi y lªn tÖp A vµ tho¸t ra khái qu¸ tr×nh trén 2 run hiÖn thêi. NÕu sau khi ghi x lªn A mµ vÉn cßn phÇn tö trong run ë B th× ®äc phÇn tö tiÕp theo g¸n vµo x. Tr−êng hîp biÓu thøc x<y sai th× lµm t−¬ng tù víi tÖp C. Khi tho¸t khái vßng lÆp while(ix<p && iy<p) th× cã thÓ run trªn B hoÆc trªn C vÉn ch−a hÕt. Do ®ã ta cÇn ghi nèt phÇn cßn l¹i cña run hiÖn thêi vµo tÖp A b»ng c¸c lÖnh: //Chep phan con lai cua p phan tu tren b len a while(ix<p && !EoF(b)) {fread(&x,sz,1,b); fwrite(&x,sz,1,a);ix++; } //Chep phan con lai cua p phan tu tren c len a while(iy<p && !EoF(c)) http://www.ebook.edu.vn 12 Trương Hải Bằng-Cấu trúc dữ liệu 2 {fread(&y,sz,1,c); fwrite(&y,sz,1,a);iy++; } Sau khi trén hÕt cÆp run th× cã thÓ trªn B hoÆc C vÉn cßn phÇn tö vµ ta cÇn ®äc nèt c¸c phÇn tö nµy vµ ghi lªn A. Sau ®©y lµ toµn v¨n hµm MergeFile: void MergeFile(char *tepB,char *tepC, char *tepA, int p) {FILE *a,*b,*c; float x,y; int ix,iy; b = fopen(tepB,"rb"); c = fopen(tepC,"rb"); a = fopen(tepA,"wb"); rewind(a);rewind(b);rewind(c); while(!EoF(b) && !EoF(c)) {ix = 0;//So phan tu cua b da ghi len a trong so 2*p phan tu can gi len a iy = 0;//So phan tu cua c da ghi len a trong so 2*p phan tu can gi len a fread(&x,sz,1,b); fread(&y,sz,1,c); while(ix<p && iy<p) {if(x<y) {fwrite(&x,sz,1,a);ix++; if(ix==p || EoF(b)) {fwrite(&y,sz,1,a);iy++;break;} //Chua du p phan tu va chua het file b fread(&x,sz,1,b); } else //x>=y) {fwrite(&y,sz,1,a);iy++; if(iy==p || EoF(c)) {fwrite(&x,sz,1,a);ix++;break;} //Chua du p phan tu va chua het file b fread(&y,sz,1,c); } }//Het vong while(ix<p && iy<p) //Chep phan con lai cua p phan tu tren b len a while(ix<p && !EoF(b)) {fread(&x,sz,1,b); fwrite(&x,sz,1,a);ix++; } //Chep phan con lai cua p phan tu tren c len a while(iy<p && !EoF(c)) {fread(&y,sz,1,c); fwrite(&y,sz,1,a);iy++; } } //Chep phan con lai tren b len a while(!EoF(b)) {fread(&x,sz,1,b); fwrite(&x,sz,1,a); } //Vi co the so run tren b nhieu hon tren c 1, nen tren c da het run fclose(a);fclose(b);fclose(c); }; http://www.ebook.edu.vn 13 Trương Hải Bằng-Cấu trúc dữ liệu 2 Hµm void SortFile(char *TenTep) sÏ s¾p xÕp tÖp cã tªn TenTep theo c¸c thuËt to¸n ®· tr×nh bµy ë trªn. C¸c hµm quan träng nhÊt ®· ®−îc tr×nh bµy, ë ®©y ta chØ cÇn gäi c¸c hµm ®ã mét c¸ch hîp lý. Chóng ta xuÊt ph¸t tõ p = 1, sau ®ã thùc hiÖn qu¸ tr×nh ph©n bæ tÖp A cho 2 tÖp B vµ C, råi trén B vµ C vµo A. Sau mçi b−íc ®Æt p = p*2 vµ thùc hiÖn qu¸ tr×nh lÆp chõng nµo p<n. NÕu p<n nh−ng 2*p ≥ n th× qu¸ tr×nh sÏ hoµn tÊt sau khi ph©n bæ A, råi trén B vµ C trë l¹i A. void SortFile(char *TenTep) {int p,n;char *tepB="vutb.dat",*tepC="vutc.dat"; n=FileNodes(TenTep); p=1; while(p<n) {SplitFile(TenTep,tepB,tepC,p); MergeFile(tepB,tepC,TenTep,p); p = 2*p; } } 1.3. Ph−¬ng ph¸p trén run tù nhiªn 1.3.1. M« t¶ thuËt to¸n Trong ph−¬ng ph¸p trén trùc tiÕp ta coi d·y ban ®Çu cã n run mµ kh«ng hÒ quan t©m ®Õn thùc tÕ lµ cã thÓ ®· cã nh÷ng run ®· cã ®é dµi > 1 ngay tõ b−íc xuÊt ph¸t. Trong phÇn nµy chóng ta sÏ ph©n bæ vµ trén c¸c run trªn c¬ së thùc tÕ: chóng ta sÏ xem xÐt c¸c run tù nhiªn trªn A vµ ph©n bæ chóng sang B vµ C. Khi trén c¸c run cña B vµ C vµo A ta còng xem xÐt c¸c run thùc tÕ trªn B, C. Qu¸ tr×nh nµy sÏ kÕt thóc khi chóng ta kiÓm tra vµ thÊy r»ng chØ cã mét run duy nhÊt trªn A. C¸ch trén nh− thÕ nµy ®−îc gäi lµ ph−¬ng ph¸p trén tù nhiªn. ThuËt to¸n nµy cã thÓ m« t¶ nh− sau: PhÐp lÆp: Ta xem tÖp A gåm c¸c run cã thÓ cã ®é dµi kh¸c nhau. Ta sÏ lÇn l−ît ph©n bæ c¸c run cho 2 tÖp B vµ C cho ®Õn khi A hÕt phÇn tö. TiÕp theo ta lÇn l−ît trén tõng cÆp run trªn B vµ C víi nhau vµ ghi vµo A. L−u ý r»ng sè run cã trªn B nãi chung nhá h¬n sè run mµ A ®· ph©n bæ cho B. V× nhiÒu khi nèi hai run bÊt kú mét c¸ch t×nh cê ta còng cã thÓ ®−îc mét run. Gi¶ sö d·y trong tÖp A lµ c¸c phÇn tö 1 2 9 8 7 6 5 ta cã thÓ m« t¶ b−íc nµy trong b¶ng sau: A B C A' 1 1 8 1 2 9 8 7 6 5 2 9 7 5 6 2 8 9 6 7 5 Sau khi trén B vµ C vµo A ta cÇn kiÓm tra nÕu A chØ cã mét run th× viÖc s¾p xÕp kÕt thóc, nÕu kh«ng ta quay l¹i thùc hiÖn phÐp lÆp. Cã thÓ m« t¶ qu¸ tr×nh trªn th«ng qua viÖc s¾p xÕp tÖp A víi c¸c gi¸ trÞ ban ®Çu ë trªn nh− sau: B−íc 1: A 1 2 9 8 7 6 5 B 1 2 9 7 5 C 8 6 A' 1 2 8 9 6 7 5 http://www.ebook.edu.vn 14 Trương Hải Bằng-Cấu trúc dữ liệu 2 B−íc 2: A B C A' 1 1 6 1 2 8 9 6 7 2 8 9 5 7 2 6 7 8 9 5 A B C A' 1 2 6 7 8 9 5 1 2 6 7 8 9 5 1 2 5 6 7 8 9 5 B−íc 3: T¹i b−íc 3 ta thÊy r»ng tÖp A ®· ®−îc s¾p xÕp vµ kÕt thóc. NÕu m« t¶ thuËt to¸n trªn b»ng gi¶ ng«n ng÷ C (tøc lµ ng«n ng÷ gÇn gièng víi C chñ yÕu ®Ó hiÓu ®−îc ý t−ëng thuËt to¸n) ta cã thÓ viÕt gän nh− sau: while (Sè run trong tÖp A >1) { - LÇn l−ît ph©n bæ c¸c run tù nhiªn tõ tÖp A sang 2 tÖp B vµ C theo c¸ch: mét run sang B th× run tiÕp theo sang C, run sau ®ã sang B,... cho ®Õn khi hÕt run trªn A. Nh− vËy tÖp B cã thÓ chøa nhiÒu h¬n tÖp C mét run. - TiÕp theo trén tõng cÆp run tù nhiªn trªn B vµ C thµnh mét run vµ ghi vµo tÖp A. - NÕu A ®· s¾p xÕp hay chØ cã mét run th× kÕt thóc, nÕu kh«ng quay l¹i vßng lÆp. } 1.3.2. Cµi ®Æt ch−¬ng tr×nh Ch−¬ng tr×nh 12SXF.CPP sau ®©y cµi ®Æt thuËt to¸n s¾p xÕp mét tÖp b»ng ph−¬ng ph¸p trén run tù nhiªn. PhÇn khai b¸o chung, khai b¸o nguyªn mÉu hµm vµ hµm main: //12SXF.CPP Sap xep file bang phuong phap tron tu nhien tren tep nhi phan #include <conio.h> #include <stdio.h> #define true 1 #define false 0 #define sz (sizeof(float)) int FileNodes(char *TenTep);//So phan tu tren tep int EoF(FILE *f);//Cuoi tep int EoR(FILE *f);//Cuoi Run void CreateFile(char *TenTep); void ViewFile(char *TenTep); void SplitFile(char *tepA,char *tepB, char *tepC); void MergeFile(char *tepB,char *tepC, char *tepA); int SortedFile(char *TenTep); void SortFile(char *TenTep); //===================== http://www.ebook.edu.vn 15 Trương Hải Bằng-Cấu trúc dữ liệu 2 void main() {clrscr(); char *TenTep="A.DAT"; CreateFile(TenTep); ViewFile(TenTep); printf("\n\nTep sau khi sap xep la:"); SortFile(TenTep); ViewFile(TenTep); getch(); }; Hµm int EoR(FILE *f) cã nghÜa lµ End of Run tr¶ vÒ gi¸ trÞ true nÕu con trá tÖp ®ang ë ngay phÝa sau phÇn tö cuèi cïng cña mét run. NÕu con trá ë ®Çu tÖp th× ta cho r»ng kh«ng ph¶i lµ EoR() vµ tr¶ vÒ gi¸ trÞ false. §iÒu nµy thÓ hiÖn qua lÖnh: if(ftell(f)==0) return(false); TiÕp theo nÕu con trá ®· ë sau phÇn tö cuèi cïng (tøc lµ EoF() = true) th× còng ®−îc xem lµ EoR. Trong tr−êng hîp cßn l¹i ta cÇn so s¸nh gi¸ trÞ y võa ®äc víi gi¸ trÞ tr−íc nã. Do ®ã sau khi ®äc xong y ta ph¶i quay l¹i 2 phÇn tö ®Ó ®äc x. NÕu x<=y th× vÞ trÝ hiÖn t¹i ch−a ph¶i lµ EoR. Trong tr−êng hîp nµy hµm tr¶ vÒ gi¸ trÞ false. §ã lµ lÖnh: if(x<=y) return(false); NÕu (x<=y) sai, tøc lµ x>y th× ®óng lµ ta ®· ë sau phÇn tö cuèi cïng cña run vµ ph¶i tr¶ vÒ gi¸ trÞ true. §ã lµ lÖnh: return(true); ë cuèi hµm. V× ta ®äc y, råi lïi l¹i 2 vÞ trÝ ®Ó ®äc x nªn con trá ®· ë vÞ trÝ tr−íc khi gäi hµm, nªn kh«ng ph¶i dÞch chuyÓn n÷a. int EoR(FILE *f) {float x,y; if(ftell(f)==0) return(false); if(fread(&y,sz,1,f)<=0) return(true); fseek(f,-2.0*sz,1); fread(&x,sz,1,f); if(x<=y) return(false); else return(true); } Hµm void SplitFile(char *tepA,char *tepB, char *tepC) sÏ ph©n bæ c¸c run tù nhiªn trªn A sang 2 tÖp B vµ C. V× A lµ tÖp nguån, cßn B vµ C lµ c¸c tÖp ®Ých, do ®ã tÖp A ®−îc më chØ ®äc, cßn c¸c tÖp B vµ C ®−îc më míi. ViÖc ph©n bæ sÏ ®−îc thùc hiÖn cho ®Õn khi kh«ng cßn phÇn tö trªn A. §iÒu nµy thÓ hiÖn ë dßng lÖnh: while(!EoF(a)) Mét l−ît ph©n bæ run sÏ ®−îc b¾t ®Çu b»ng viÖc ®äc mét phÇn tö ë ®Çu run trªn A vµ ghi sang B. ViÖc nµy chØ kÕt thóc khi hÕt run hiÖn thêi. §iÒu nµy ®−îc thÓ hiÖn ë c¸c lÖnh sau: fread(&x,sz,1,a); fwrite(&x,sz,1,b); while(!EoR(a)) {fread(&x,sz,1,a); fwrite(&x,sz,1,b); } Sau khi ghi mét run lªn B mµ trªn A vÉn cßn ph©n tö th× run tiÕp theo ®−îc ph©n bæ cho C b»ng c¸ch t−¬ng tù. Cø nh− vËy cho ®Õn hÕt A. http://www.ebook.edu.vn 16 Trương Hải Bằng-Cấu trúc dữ liệu 2 void SplitFile(char *tepA,char *tepB, char *tepC) {FILE *a,*b,*c;float x; a = fopen(tepA,"rb"); b = fopen(tepB,"wb"); c = fopen(tepC,"wb"); rewind(a);rewind(b);rewind(c); while(!EoF(a)) {//Chia 1 run tren a cho b fread(&x,sz,1,a); fwrite(&x,sz,1,b); while(!EoR(a)) {fread(&x,sz,1,a); fwrite(&x,sz,1,b); } if(EoF(a)) break; //Chia 1 run tren a cho c fread(&x,sz,1,a); fwrite(&x,sz,1,c); while(!EoR(a)) {fread(&x,sz,1,a); fwrite(&x,sz,1,c); } } fclose(a);fclose(b);fclose(c); }; Hµm void MergeFile(char *tepB,char *tepC, char *tepA) thùc hiÖn viÖc trén c¸c run tù nhiªn trªn B vµ C vµo A. C¸c tÖp B vµ C lµ c¸c tÖp nguån, do ®ã ®−îc më chØ ®äc. Cßn A lµ tÖp ®Ých nªn ®−îc më míi. ViÖc trén sÏ ®−îc thùc hiÖn chõng nµo cßn phÇn tö trªn c¶ B vµ C. §iÒu nµy thÓ hiÖn ë lÖnh: while(!EoF(b) && !EoF(c)) V× ta trén 2 run, mét ë trªn B vµ mét ë trªn C. ViÖc trén hai run hiÖn thêi chØ ®−îc thùc hiÖn chõng nµo c¶ hai run vÉn cßn phÇn tö. V× nÕu mét run hÕt phÇn tö th× chØ cÇn ghi phÇn cßn l¹i cña run kia lªn tÖp A. Chóng ta sÏ dïng 2 biÕn logic con_x vµ con_y ®Ó ghi l¹i tr¹ng th¸i nµy. con_x = true cã nghÜa lµ vÉn cßn phÇn tö trong run hiÖn thêi trªn B; con_y = true cã nghÜa lµ vÉn cßn phÇn tö trong run hiÖn thêi trªn C. Vßng lÆp thÓ hiÖn qu¸ tr×nh trén hai run hiÖn thêi thÓ hiªn ë lÖnh: while(con_x && con_y) Khi trén ta so s¸nh x vµ y (x lµ cña run trªn B vµ y lµ phÇn tö cña run trªn C). NÕu x<y th× ta ghi x vµo A. Sau khi ghi x lªn A th× ta kiÓm tra xem cßn phÇn tö trong run hiÖn thêi trªn B kh«ng. NÕu kh«ng cßn th× ghi nhËn tr¹ng th¸i nµy b»ng lÖnh con_x = false; nÕu cßn th× ®äc mét phÇn tö trong run vµo x ®Ó thay thÕ x ®· bÞ lÊy ®i. §iÒu nµy thÓ hiÖn ë dßng lÖnh: if(EoR(b)) con_x=false; else fread(&x,sz,1,b); NÕu x<y lµ sai, tøc lµ x>=y th× lµm t−¬ng tù víi C. Tho¸t khái vßng lÆp nµy cã thÓ x hoÆc y vÉn ch−a ®−îc ghi lªn a. Ta ghi nèt phÇn tö ch−a ®−îc ghi b»ng c¸c lÖnh: if(con_x) fwrite(&x,sz,1,a); if(con_y) fwrite(&y,sz,1,a); Sau khi trén 2 run th× chØ cã thÓ mét run vÉn cßn phÇn tö ch−a ®−îc ghi lªn tÖp A. Trong tr−êng hîp nµy ta ghi nèt phÇn tö sãt l¹i lªn A tr−íc khi thùc hiÖn viÖc trén run tiÕp theo. §iÒu nµy thÓ hiÖn trong ®o¹n lÖnh sau: //Chep phan con lai cua run hien thoi tu b len a while(!EoR(b)) http://www.ebook.edu.vn 17 Trương Hải Bằng-Cấu trúc dữ liệu 2 {fread(&x,sz,1,b); fwrite(&x,sz,1,a); } //Chep phan con lai cua run hien thoi tu c len a while(!EoR(c)) {fread(&x,sz,1,c); fwrite(&x,sz,1,a); } Khi ®· hÕt run ë mét trong hai tÖp th× ta ghi phÇn cßn l¹i trªn tÖp kia vµo A. §iÒu nµy thÓ hiÖn ë ®o¹n lÖnh sau: //Chep phan con lai tren b len a while(!EoF(b)) {fread(&x,sz,1,b); fwrite(&x,sz,1,a); } //Chep phan con lai tren c len a while(!EoF(c)) {fread(&y,sz,1,c); fwrite(&y,sz,1,a); } Chó ý. Kh¸c víi ph−¬ng ph¸p trén run trùc tiÕp, sau khi ph©n bæ, do c¸c run liÒn nhau cã thÓ t¹o run míi nªn rÊt cã thÓ run tù nhiªn trªn b Ýt h¬n trªn c, nªn kh«ng ch¾c lµ c hÕt tr−íc. Sau ®©y lµ toµn v¨n hµm MergeFile: void MergeFile(char *tepB,char *tepC, char *tepA) {FILE *a,*b,*c; float x,y;int con_x,con_y; //con_x = true co nghia la con phan tu trong run tren b //con_y = true co nghia la con phan tu trong run tren c b = fopen(tepB,"rb"); c = fopen(tepC,"rb"); a = fopen(tepA,"wb"); rewind(a);rewind(b);rewind(c); while(!EoF(b) && !EoF(c)) {fread(&x,sz,1,b);con_x=true; fread(&y,sz,1,c);con_y=true; while(con_x && con_y) {if(x<y) {fwrite(&x,sz,1,a); if(EoR(b)) con_x=false; else fread(&x,sz,1,b); //Neu sau khi ghi x vao a ma het run tren file b thi con_x=false } else //x>=y) {fwrite(&y,sz,1,a); if(EoR(c)) con_y=false; else fread(&y,sz,1,c); //Neu sau khi ghi y vao a ma het run tren file c thi con_y=false } } //Het Run tren b hoac c //Neu chua ghi x hoac y len a thi ghi not if(con_x) fwrite(&x,sz,1,a); if(con_y) fwrite(&y,sz,1,a); http://www.ebook.edu.vn 18 Trương Hải Bằng-Cấu trúc dữ liệu 2 //Chep phan con lai cua run hien thoi tu b len a while(!EoR(b)) {fread(&x,sz,1,b); fwrite(&x,sz,1,a); } //Chep phan con lai cua run hien thoi tu c len a while(!EoR(c)) {fread(&x,sz,1,c); fwrite(&x,sz,1,a); } } //Chep phan con lai tren b len a while(!EoF(b)) {fread(&x,sz,1,b); fwrite(&x,sz,1,a); } //Chep phan con lai tren c len a while(!EoF(c)) {fread(&y,sz,1,c); fwrite(&y,sz,1,a); } fclose(a);fclose(b);fclose(c); }; Hµm SortedFile(char *TenTep) dïng ph−¬ng ph¸p næi bät ®Ó kiÓm tra xem mét tÖp ®· s¾p xÕp ch−a. Ta lÇn l−ît ®äc c¸c phÇn tö trªn tÖp, mçi lÇn ®äc phÇn tö míi th× ghi nhËn l¹i phÇn tö cò b»ng lÖnh x = y; Ta thùc hiÖn viÖc so s¸nh 2 phÇn tö gÇn kÒ vµ chØ cÇn ph¸t hiÖn ra mét tr−êng hîp 2 phÇn tö gÇn kÒ ch−a s¾p theo thø tù t¨ng dÇn lµ ta kÕt thóc thuËt to¸n vµ tr¶ vÒ gi¸ trÞ false (ch−a s¾p). NÕu ®i qua tÖp mµ kh«ng ph¸t hiÖn ra tr−êng hîp so le nµo th× cã nghÜa lµ tÖp ®· s¾p xÕp vµ ta tr¶ vÒ gi¸ trÞ true. int SortedFile(char *TenTep) {FILE *f;float x,y; f = fopen(TenTep,"rb"); rewind(f); fread(&x,sz,1,f); while(fread(&y,sz,1,f)>0) {if(x>y) {fclose(f);return(false);} x = y; } fclose(f); return(true); } Cuèi cïng lµ hµm void SortFile(char *TenTep) thùc hiÖn viÖc s¾p xÕp mét tÖp ®· cho theo ®óng thuËt to¸n ®· tr×nh bµy. NghÜa lµ thùc hiÖn vßng lÆp : ph©n bæ vµ trén cho ®Õn khi tÖp A ®−îc s¾p. void SortFile(char *TenTep) {int i;char *tepB="vutb.dat",*tepC="vutc.dat"; while(!SortedFile(TenTep)) {SplitFile(TenTep,tepB,tepC); MergeFile(tepB,tepC,TenTep); } http://www.ebook.edu.vn 19 Trương Hải Bằng-Cấu trúc dữ liệu 2 } 1.4. Ph−¬ng ph¸p trén ®a lèi c©n b»ng (Balanced multiway merging) 1.4.1. M« t¶ thuËt to¸n Trong ph−¬ng ph¸p trén trùc tiÕp hoÆc trén run tù nhiªn, hai thao t¸c ®−îc sö dông ®an xen nhau lµ ph©n phèi run vµ trén run. Thao t¸c ph©n phèi run th−êng chiÕm mét l−îng thêi gian ®¸ng kÓ. Ng−êi ta c¶i tiÕn c¸c ph−¬ng ph¸p nµy b»ng c¸ch chØ ph©n phèi run mét lÇn ban ®Çu, sau ®ã chØ thùc hiÖn c¸c phÐp trén liªn tiÕp cho ®Õn khi nhËn ®−îc tÖp s¾p xÕp. §Ó lµm ®iÒu nµy ng−êi ta sö dông m tÖp nguån F = {tepN[0], tepN[1], ..., tepN[m-1]} vµ m tÖp ®Ých G = {tepD[0], tepD[1], ..., tepD[m-1]}. ë b−íc ®Çu tiªn c¸c run trong tÖp A ®−îc lÇn l−ît ph©n phèi cho m tÖp nguån theo c¸ch: run ®Çu tiªn ®−îc ph©n phèi cho tepN[0], run thø hai ®−îc ph©n phèi cho tepN[1],... cø nh− vËy. NÕu cã nhiÒu h¬n m run th× sau khi ph©n phèi run cho tÖp tepN[m-1] qu¸ tr×nh ph©n phèi l¹i quay l¹i tepN[0], vµ cø nh− vËy cho ®Õn khi toµn bé run ®−îc ph©n phèi. Thay v× trén c¸c run trë l¹i tÖp A, ng−êi ta t¹o ra c¸c tÖp G = {tepD[0], tepD[1], ..., tepD[m-1]} sau ®ã trén tõng bé m run n»m ë ®Çu c¸c tÖp nguån thµnh mét run vµ lÇn l−ît ghi vµo c¸c tÖp ®Ých. Sau khi hoµn tÊt viÖc trén, ng−êi ta ho¸n ®æi vai trß cña c¸c tÖp nguån vµ tÖp ®Ých. C¸c tÖp ®Ých trë thµnh c¸c tÖp nguån vµ c¸c tÖp nguån trë thµnh c¸c tÖp ®Ých. Th«ng th−êng sau khi trén th× sè tÖp ®Ých gi¶m xuèng. Cho ®Õn khi sè tÖp ®Ých lµ 1 th× qu¸ tr×nh s¾p xÕp hoµn tÊt. Gi¶ sö d·y ban ®Çu c¸c phÇn tö trong tÖp A ®−îc cho nh− sau: A 2 12 11 10 9 8 7 6 5 4 3 Gi¶ sö ta chän 3 ®−êng cÇn b»ng vµ ph©n bæ tÖp A vµo 3 tÖp nguån nh− sau: F1 2 12 9 6 3 F2 11 8 5 F3 10 7 4 LÇn l−ît trén c¸c bé 3 run ë c¸c tÖp vµ lÇn l−ît ghi vµo c¸c tÖp ®Ých G1, G2, G3 ta ®−îc G1 2 10 11 12 G2 7 8 9 G3 4 5 6 3 B©y giê ta l¹i xem c¸c tÖp G1, G2, G3 lµ c¸c tÖp nguån vµ trén c¸c run vµo c¸c tÖp ®Ých F1, F2, F3 vµ ®−îc kÕt qu¶ lµ: F1 2 4 5 6 7 8 9 10 11 12 F2 3 http://www.ebook.edu.vn 20 Trương Hải Bằng-Cấu trúc dữ liệu 2 Ta thÊy r»ng sè tÖp ®Ých ®· gi¶m ®i 1. B©y giê trén F1 vµ F2 ta ®−îc mét tÖp ®Ých duy nhÊt G1: G1 2 3 4 5 6 7 8 9 10 11 12 V× chØ cã duy nhÊt mét tÖp ®Ých, ®iÒu nµy còng cã nghÜa lµ chØ cã mét run ®−îc t¹o ra (v× nÕu cã hai run trë lªn th× G2 sÏ ®−îc ph©n phèi), vµ nh− vËy tÖp G1 ®· ®−îc s¾p xÕp. NÕu m« t¶ thuËt to¸n trªn b»ng gi¶ ng«n ng÷ C (tøc lµ ng«n ng÷ gÇn gièng víi C chñ yÕu ®Ó hiÓu ®−îc ý t−ëng thuËt to¸n) ta cã thÓ viÕt gän nh− sau: Ph©n bæ tÖp A cho c¸c tÖp nguån tepN[0], tepN[1], ..., tepN[m-1] while(true) { - LÇn l−ît trén c¸c bé gåm m run trªn c¸c tÖp nguån vµ lÇn l−ît ph©n bæ vµo c¸c tÖp ®Ých tepD[0], tepD[1], ..., tepD[m-1], mçi lÇn chØ ph©n bæ mét run cho mét tÖp ®Ých (lÇn trén run cuèi cïng th× sè run tham gia cã thÓ nhá h¬n m). - §Æt m = sè tÖp ®Ých ®· ®−îc ph©n bæ run. NÕu m = 1 th× kÕt thóc. NÕu kh«ng th× ®æi vai trß c¸c tÖp ®Ých vµ nguån: c¸c tÖp tepD[0], tepD[1], ..., tepD[m-1] trë thµnh c¸c tÖp nguån, cßn c¸c tÖp tepN[0], tepN[1], ..., tepN[m-1] trë thµnh c¸c tÖp ®Ých råi thùc hiÖn l¹i vßng lÆp. } 1.4.2. Cµi ®Æt ch−¬ng tr×nh Ch−¬ng tr×nh 13SXF.CPP sau ®©y cµi ®Æt thuËt to¸n s¾p xÕp mét tÖp b»ng ph−¬ng ph¸p trén ®a lèi c©n b»ng võa tr×nh bµy ë trªn. PhÇn khai b¸o chung, khai b¸o nguyªn mÉu hµm vµ hµm main: //13SXF.CPP Sap xep file bang phuong phap tron da loi can bang #include <stdio.h> #include <stdlib.h> #include <conio.h> #include <string.h> #define true 1 #define false 0 #define sz (sizeof(float)) //============================================= int FileNodes(char *TenTep);//So phan tu tren tep int EoF(FILE *f);//Cuoi tep int EoR(FILE *f);//Cuoi Run void CreateFile(char *TenTep); void ViewFile(char *TenTep); void SplitFile(char *TenTep,char *TepNguon[], int &nWay); void MergeFile(char *TepNguon[],char *TepDich[], int &nWay); int SortedFile(char *TenTep); void CopyFile(char *Tep1, char *Tep2); void SortFile(char *TenTep); /*TenTep la ten tep can sap xep, TepNguon[i] la ten cac tep nguon TepDich[i] la ten cac tep dich */ //===================== void main() http://www.ebook.edu.vn 21 Trương Hải Bằng-Cấu trúc dữ liệu 2 {clrscr(); char *TenTep; TenTep = new char[12]; strcpy(TenTep,"A.DAT"); CreateFile(TenTep); ViewFile(TenTep); SortFile(TenTep); printf("\n\nTep sau khi sap xep la:"); ViewFile(TenTep); getch(); }; Hµm void SplitFile(char *TenTep,char *TepNguon[], int &nWay) ph©n bæ c¸c run trªn tÖp cÇn s¾p xÕp cã tªn lµ TenTep (ta t¹m gäi ®¬n gi¶n lµ tÖp A) vµo c¸c tÖp nguån ban ®Çu cã c¸c tªn lµ TepNguon[0], TepNguon[1], ..., TepNguon[nWay-1]. nWay chÝnh lµ sè ®−êng c©n b»ng ban ®Çu. Ta khai b¸o biÕn nWay theo kiÓu tham chiÕu v× ta muèn r»ng sù thay ®æi gi¸ trÞ cña nWay bªn trong hµm sÏ ®−îc gi÷ nguyªn khi ra ngoµi. Ta cã thÓ thÊy r»ng nÕu sè run trªn tÖp A Ýt h¬n sè ®−êng c©n b»ng th× sau khi ch¹y hµm nµy sè ®−êng c©n b»ng sÏ gi¶m xuèng b»ng sè tÖp nguån ®−îc ph©n phèi run. C¸c lÖnh for(i=0;i<nWay && FileNodes(TepNguon[i])>0;i++); nWay=i; ë cuèi hµm ®Õm c¸c tÖp ng−ån cã chøa phÇn tö vµ g¸n cho nWay. V× c¸c tÖp nguån chØ chøa c¸c run ®−îc ph©n phèi nªn chóng ®−îc më míi. TÖp A dÜ nhiªn lµ ®−îc më chØ ®äc, v× nã chøa c¸c phÇn tö cÇn ph©n bæ. ViÖc dïng lÖnh rewind() ë ®Çu hµm cã vÎ kh«ng cÇn thiÕt v× khi míi më th× con trá tÖp lu«n ë ®Çu tÖp, nh−ng ®«i khi thao t¸c nµy l¹i cÇn thiÕt nh− mét sù kÝch ho¹t vËy. Qu¸ tr×nh ph©n bæ chØ kÕt thóc khi tÖp A hÕt phÇn tö. LÖnh while(!EoF(a)) chØ râ ®iÒu nµy. Chóng ta h¹n chÕ sè ®−êng trén lµ nWay ≤ 10. Chóng ta dïng mét m¶ng con trá tÖp ®Ó t¹o ra vµ thao t¸c víi c¸c tÖp nguån. LÖnh khai b¸o m¶ng c¸c con trá tÖp thao t¸c c¸c tÖp nguån vµ con trá tÖp ®Ó më tÖp A lµ: FILE *f[10], *a; Bëi v× vÞ trÝ b¾t ®Çu cña mét run míi trªn A còng lµ vÞ trÝ EoR cña run tr−íc ®ã, do ®ã khi b¾t ®Çu ghi mét run lªn tÖp nguån ta ch−a kiÓm tra ngay ®iÒu kiÖn EoR. VËy thao t¸c ghi mét run lªn tÖp f[i] ®−îc b¾t ®Çu b»ng viÖc kiÓm tra xem cßn phÇn tö trªn A kh«ng. NÕu hÕt th× tho¸t khái vßng lÆp vµ sau ®ã kÕt thóc viÖc ph©n phèi. (§iÒu kiÖn EoF(a) ®óng tøc lµ ! EoF(a) sai vµ vßng lÆp kÕt thóc). LÖnh for(i=0;i<nWay;i++) chØ ra qu¸ tr×nh ph©n phèi run cho c¸c tÖp f[0], f[1],..., f[nWay-1]. Khi b¾t ®Çu ghi mét run, ta kiÓm tra vµ nÕu cßn phÇn tö trªn A th× ®äc phÇn tö ®Çu tiªn cña run trªn A vµ ghi vµo f[i]. §iÒu nµy thÓ hiÖn trong c¸c lÖnh: if(EoF(a)) break; fread(&x,sz,1,a); fwrite(&x,sz,1,f[i]); sau khi ghi xong phÇn tö ®Çu tiªn cña run, ta tiÕp tôc ®äc c¸c phÇn tö trong run hiÖn thêi trªn A vµ ghi vµo tÖp f[i]: while(!EoR(a)) {fread(&x,sz,1,a); fwrite(&x,sz,1,f[i]); } http://www.ebook.edu.vn 22 Trương Hải Bằng-Cấu trúc dữ liệu 2 Khi gÆp EoR trªn tÖp A th× qu¸ tr×nh ghi run vµo f[i] kÕt thóc vµ chuyÓn sang ghi run tiÕp theo lªn f[i+1] nÕu i+1<nWay. NÕu i =nWay -1 tøc lµ ta ®· ghi run vµo tÖp nguån cuèi th× quay l¹i vßng lÆp while(!EoF(a)) vµ b¾t ®Çu chu kú míi víi i = 0 lµ ®iÓm xuÊt ph¸t. Cuèi cïng ta ®ãng tÊt c¶ c¸c tÖp vµ tÝnh l¹i nWay. Th«ng th−êng nWay cã xu h−íng gi¶m dÇn ®Õn 1. void SplitFile(char *TenTep,char *TepNguon[], int &nWay) { FILE *f[10], *a;float x;int i,j,k; for(i=0;i<nWay;i++) f[i] = fopen(TepNguon[i],"wb"); a = fopen(TenTep,"rb"); rewind(a); for(i=0;i<nWay;i++) rewind(f[i]); while(!EoF(a)) {//Chia xoay vong lan luot cac run tren a cho f[0],f[1],...,f[nWay-1] //hoac chi den f[k] nao do neu het phan tu tren a for(i=0;i<nWay;i++) {if(EoF(a)) break; fread(&x,sz,1,a); fwrite(&x,sz,1,f[i]); while(!EoR(a)) {fread(&x,sz,1,a); fwrite(&x,sz,1,f[i]); } } } fclose(a); for(i=0;i<nWay;i++) fclose(f[i]); for(i=0;i<nWay && FileNodes(TepNguon[i])>0;i++); nWay=i; }; Hµm void MergeFile(char *TepNguon[10],char *TepDich[10], int &nWay) thùc hiÖn lÇn l−ît trén c¸c bé gåm nWay run lÊy tõ TepNguon[0], TepNguon[1], ..., TepNguon[nWay-1] vµ ghi vµo c¸c tÖp ®Ých TepDich[0], TepDich[1], ..., TepDich[nWay-1]. Nh− ta ®· thÊy, c¸c tÖp nguån ë cuèi cã thÓ cã sè run Ýt h¬n 1 so víi sè c¸c run ë c¸c tÖp ë ®Çu, do ®ã lÇn trén cuèi cã thÓ kh«ng cã ®ñ nWay run. Thao t¸c trén ®−îc thùc hiÖn nh− sau: ta so s¸nh phÇn tö ë ®Çu c¸c run hiÖn thêi vµ chän ra phÇn tö nhá nhÊt ®Ó ghi lªn tÖp ®Ých hiÖn thêi. §Ó cã thÓ so s¸nh, ta ph¶i ®æ c¸c gi¸ trÞ ë ®Çu c¸c run vµo bé nhí vµ l−u trong m¶ng x[0], x[1], ..., x[nWay-1]. Tuy ë b−íc trén cuèi cïng cã thÓ kh«ng cã ®ñ nWay phÇn tö. Ngay trong c¸c b−íc trén cã ®Çy ®ñ run th× còng cã tr−êng hîp mét sè run sÏ hÕt phÇn tö tr−íc. VÝ dô gi¶ sö nWay = 3 vµ 3 run hiÖn thêi lµ {1,2,3}, {4,5,6,7} vµ {8,9} th× ban ®Çu ta cã x[0] = 1, x[1] = 4 vµ x[2] = 8. Ta thÊy r»ng x[0] lµ nhá nhÊt vµ ghi gi¸ trÞ nµy lªn tÖp ®Ých, sau ®ã ®äc gi¸ trÞ tiÕp theo cña run vµo x[0] vµ nhËn ®−îc x[0] = 2. ë b−íc thø 2 ta cÇn chän gi¸ trÞ nhá nhÊt trong 3 sè x[0] = 2, x[1] = 4 vµ x[2] = 8. Ta thÊy r»ng x[0] ®−îc chän ghi lªn tÖp ®Ých vµ gi¸ trÞ tiÕp theo cña run ®−îc g¸n cho x[0] vµ ta l¹i cã x[0] = 3, x[1] = 4 vµ x[2] = 8. T¹i b−íc nµy ta ghi x[0]=3 lªn tÖp ®Ých, nh−ng run hiÖn thêi ®· hÕt phÇn tö nªn ta ph¶i v« hiÖu hãa gi¸ trÞ x[0] mµ chØ so s¸nh x[1] víi x[2]. §Ó cã thÓ ®¸nh dÊu mét run hiÖn thêi nµo ®ã ®· hÕt phÇn tö, ta dïng mét m¶ng con_x[i] (cã nghÜa lµ cßn x[i]). NÕu cßn phÇn tö ë run hiÖn thêi trªn tÖp nguån i th× ta ®Æt con_x[i] = true, nÕu ®· hÕt th× ta ®Æt con_x[i] = false. B¾t ®Çu qu¸ tr×nh trén, chóng ta ph¶i më c¸c tÖp nguån theo kiÓu chØ ®äc, cßn c¸c tÖp ®Ých ®−îc t¹o míi. BiÕn CurrDich lµ chØ sè cña tÖp ®Ých hiÖn thêi. Ban ®Çu CurrDich=0, tøc lµ g[0] sÏ lµ http://www.ebook.edu.vn 23 Trương Hải Bằng-Cấu trúc dữ liệu 2 tÖp ®Ých ®Çu tiªn nh− thuËt to¸n ®· chØ ra. Sau mçi lÇn trén vµ run ®−îc ghi vµo tÖp ®Ých hiÖn thêi th× CurrDich t¨ng lªn 1, nghÜa lµ tÖp ®Ých hiÖn thêi sÏ lµ tÖp tiÕp theo cña tÖp ®Ých hiÖn thêi tr−íc ®ã. Tuy nhiªn nÕu tÖp ®Ých tr−íc ®ã lµ tÖp cuèi cïng th× chu kú sÏ quay l¹i tõ ®Çu, tøc lµ CurDich=0. §Ó b¾t ®Çu trén mét bé run chóng ta sÏ ®äc c¸c phÇn tö ®Çu mçi run vµ g¸n vµo m¶ng x[i]. Tuy nhiªn nh− ta ®· thÊy, cã thÓ chØ cã mét sè run cßn phÇn tö,. do ®ã ta ph¶i kiÓm tra xem viÖc ®äc cã thµnh c«ng kh«ng. NÕu thµnh c«ng th× g¸n con_x[i]=true, cßn nÕu kh«ng th× g¸n con_x[i]=false. Chóng ta dïng biÕn nNguon ®Ó ®Õm sè lÇn ®äc thµnh c«ng. NÕu nNguon=0 cã nghÜa lµ tÊt c¶ c¸c lÇn ®äc ®Òu kh«ng thµnh c«ng, vµ nh− vËy th× cã nghÜa lµ ®· hÕt d÷ liÖu trªn c¸c file nguån vµ qu¸ tr×nh trén kÕt thóc. §o¹n lÖnh sau thÓ hiÖn nh÷ng ®iÒu võa nãi: j=0; for(i=0;i<nWay;i++) if(fread(&t,sz,1,f[i])>0) {x[i]=t;con_x[i]=true;j++;} else con_x[i]=false; nNguon=j; if(nNguon==0) break;//Da het cac phan tu tren cac file nguon Sau b−íc khëi ®Çu nµy ta b¾t ®Çu thùc hiÖn vßng lÆp thùc hiÖn viÖc trén c¸c run hiÖn thêi vµ ghi lªn tÖp ®Ých hiÖn thêi. §iÒu kiÖn dõng cña vßng lÆp kh¸ phøc t¹p nªn ta t¹m ®Æt lµ while(true). Bªn trong th©n vßng lÆp sÏ cã ®iÒu kiÖn ®Ó tho¸t khái vßng lÆp. Khi b¾t ®Çu trén run th× cã mét sè phÇn tö trong m¶ng x[i]. Tuy nhiªn trong qu¸ tr×nh trén c¸c phÇn tö ®−îc ghi vµo tÖp ®Ých phÇn tö míi ®−îc ®äc tõ run t−¬ng øng ®Ó thay thÕ nÕu run vÉn cßn. Do vËy rÊt cã thÓ ®Õn lóc nµo ®ã trong m¶ng x[i] sÏ kh«ng cßn phÇn tö nµo c¶, khi ®ã viÖc trén run hiÖn thêi sÏ kÕt thóc. §Ó chän phÇn tö ghi vµo tÖp ®Ých hiªn thêi, ta cÇn chän k sao cho x[k] lµ phÇn tö nhá nhÊt trong c¸c phÇn tö cña m¶ng x[i] ®· ®−îc ®äc (con_x[i] = true). Theo th«ng th−êng th× ®Ó x¸c ®Þnh min cña mét m¶ng ®Çu tiªn ta chän phÇn tö ®Çu tiªn cña m¶ng vµ coi lµ phÇn tö nhá nhÊt. sau ®ã ta b¾t ®Çu duyÖt tõ phÇn tö thø 2 cho ®Õn phÇn tö cuèi cïng, mçi lÇn gÆp phÇn tö nhá h¬n min hiÖn thêi th× ta l¹i thay thÕ min hiÖn thêi b»ng phÇn tö ®ã. Tuy nhiªn trong tr−êng hîp chóng ta ®ang xÐt th× cã thÓ phÇn tö x[0], x[1] ®· ®−îc ghi vµ kh«ng cßn tham gia vµo qu¸ tr×nh chän (con_x[i]= false). Do ®ã chóng ta ph¶i quÐt tõ ®Çu m¶ng vµ t×m ra vÞ trÝ ®Çu tiªn mµ x[i] ch−a sö dông. NÕu kh«ng t×m ra vÞ trÝ nµy th× cã nghÜa lµ run ®· hÕt. CurrDich t¨ng lªn 1, nghÜa lµ tÖp ®Ých hiÖn thêi sÏ lµ tÖp tiÕp theo cña tÖp ®Ých hiÖn thêi tr−íc ®ã. Lóc nµy ta kÕt thóc vßng lÆp trén run hiÖn thêi vµ chuyÓn ®Õn tÖp ®Ých tiÕp theo. Tuy nhiªn nÕu ®ã lµ tÖp cuèi cïng th× chu kú sÏ quay l¹i tõ ®Çu, tøc lµ CurDich=0. Sau ®©y lµ ®o¹n lÖnh thùc hiÖn nh÷ng ®iÒu võa nãi: i=0;//Tim vi tri dau tien con phan tu trong run while(!con_x[i] && i<nWay)i++;//Tim run dang con phan tu if(i==nWay) //Het phan tu trong bo run, chuyen sang bo run khac {CurrDich++;CurrDich = CurrDich%nWay;break;} ë ®©y ta thÊy r»ng nÕu i = nWay th× cã nghÜa lµ tÊt c¶ con_x[j], j =0,1,...,nWay-1 ®Òu lµ false. Ng−îc l¹i nÕu i<nWay th× vÞ trÝ nµy chÝnh lµ vÞ trÝ ®Çu tiªn mµ con_x[i] = true. Ta cÇn chän vÞ trÝ k mµ con_x[k] true vµ x[k] lµ bÐ nhÊt. Ban ®Çu t¹m ®Æt min t¹m thêi lµ t=x[i] vµ nh− vËy k=i. §o¹n lÖnh sau sÏ duyÖt qua phÇn cßn l¹i cña m¶ng x[j] vµ t×m ra vÞ trÝ chøa phÇn tö bÐ nhÊt. t = x[i];k=i; for(j=i+1;j<nWay;j++) if(con_x[j] && x[j]<t) {t=x[j];k=j;} Sau khi x¸c ®Þnh ®−îc phÇn tö bÐ nhÊt, ta ghi nã vµo tÖp ®Ých hiÖn thêi b»ng lÖnh: fwrite(&t,sz,1,g[CurrDich]); http://www.ebook.edu.vn 24 Trương Hải Bằng-Cấu trúc dữ liệu 2 Sau khi ghi x[k] ta kiÓm tra xem run hiÖn thêi trªn tÖp nguån f[k] cã cßn phÇn tö kh«ng. NÕu cã th× ®äc phÇn tö cña run vµo x[k] vµ vÉn gi÷ nguyªn gi¸ trÞ con_x[k] = true. NÕu ®· hÕt run th× ta ®¸nh dÊu vÞ trÝ nµy b»ng lÖnh con_x[k]=false; if(EoR(f[k])) con_x[k]=false; else {fread(&t1,sz,1,f[k]); x[k]=t1; } Qu¸ tr×nh trªn ®©y ®−îc thùc hiÖn cho ®Õn khi hÕt tÊt c¶ c¸c phÇn tö trªn c¸c tÖp nguån. Khi viÖc trén ®· hoµn tÊt, cã thÓ sè tÖp ®Ých sÏ gi¶m xuèng vµ ta cÇn tÝnh l¹i. Ta dïng lÖnh for(i=0;i<nWay && FileNodes(TepDich[i])>0;i++); nWay=i; ®Ó thùc hiÖn ®iÒu nµy. ë ®©y ta vÉn cÇn ®iÒu kiÖn i<nWay ®Ó lo¹i trõ kh¶ n¨ng cã nh÷ng tÖp cïng tªn nh−ng kh«ng ph¶i lµ c¸c tÖp chóng ta quan t©m. void MergeFile(char *TepNguon[10],char *TepDich[10], int &nWay) {FILE *f[10], *g[10];float x[10],t,t1; int i,j,k,con_x[10],nNguon,CurrDich; /*Neu run tren f[i] chua het thi con_x[i] =true Neu het roi thi con_x[i] = false nNguon la so file nguon co phan tu nDich la so File dich da duoc cap phan tu CurrDich la file dich hien thoi duoc ghi run */ for(i=0;i<nWay;i++) {f[i] = fopen(TepNguon[i],"rb"); rewind(f[i]); g[i] = fopen(TepDich[i],"wb"); } CurrDich=0; while(true) //Se ket thuc khi het cac phan tu tren file nguon {//Vi cac run duoc phan phoi duoc phan bo tu i = 0 do do co the co //mot so tep o phan cuoi co it hon 1 run j=0; for(i=0;i<nWay;i++) if(fread(&t,sz,1,f[i])>0) {x[i]=t;con_x[i]=true;j++;} else con_x[i]=false; nNguon=j; if(nNguon==0) break;//Da het cac phan tu tren cac file nguon while(true) //Bat dau tron cac run va dua vao g[CurrDich] {//Tim phan tu be nhat o dau run trong bo run i=0;//Tim vi tri dau tien con phan tu trong run while(!con_x[i] && i<nWay)i++;//Tim run dang con phan tu if(i==nWay) //Het phan tu trong bo run, chuyen sang bo run khac {CurrDich++;CurrDich = CurrDich%nWay;break;} t = x[i];k=i; for(j=i+1;j<nWay;j++) if(con_x[j] && x[j]<t) {t=x[j];k=j;} //x[k] chinh la gia tri nho nhat trong bo run hien thoi fwrite(&t,sz,1,g[CurrDich]); http://www.ebook.edu.vn 25 Trương Hải Bằng-Cấu trúc dữ liệu 2 if(EoR(f[k])) con_x[k]=false; else {fread(&t1,sz,1,f[k]); x[k]=t1; } } } for(i=0;i<nWay;i++) {fclose(f[i]);fclose(g[i]);} for(i=0;i<nWay && FileNodes(TepDich[i])>0;i++); nWay=i; }; Hµm void CopyFile(char *Tep1, char *Tep2) sÏ copy mét tÖp gåm c¸c phÇn tö sè thùc cã tªn Tep1 sang tÖp cã tªn lµ Tep2. Chóng ta l−u ý lµ hµm nµy chØ copy mét tÖp chøa c¸c sè thùc mµ th«i. Chóng ta cÇn hµm nµy ®Ó copy tÖp ®Ých cuèi cïng vµo tÖp A ban ®Çu ®Ó nhËn ®−îc tÖp A ®· s¾p xÕp. void CopyFile(char *Tep1, char *Tep2) {FILE *f1, *f2;float x; f1 = fopen(Tep1,"rb"); f2 = fopen(Tep2,"wb"); rewind(f1); while(fread(&x,sz,1,f1)>0) fwrite(&x,sz,1,f2); fclose(f1);fclose(f2); } Hµm void SortFile(char *TenTep) sÏ thùc hiÖn viÖc s¾p xÕp tÖp TenTep theo ph−¬ng ph¸p ®a lèi c©n b»ng. Chóng ta cÇn 2 m¶ng c¸c chuçi lµ TepNguon[10] vµ TepDich[10]. V× chóng ta h¹n chÕ ®−êng trén lµ 10 nªn chØ ®Ó cì m¶ng 10. Tr−íc hÕt ta cÇn nhËp sè ®−êng trén n. Sau ®ã ch−¬ng tr×nh sÏ t¹o ra c¸c tÖp nguån vµ ®Ých cã d¹ng: ZZN0,ZZN1,ZZN2,...ZZD0,ZZD1,ZZD2,... VÝ dô nÕu n = 4 ta sÏ cã c¸c tÖp nguån lµ ZZN0, ZZN1, ZZN2, ZZN3 vµ c¸c tÖp ®Ých lµ ZZD0, ZZD1, ZZD2, ZZD3. Chóng ta ®· sö sông hµm itoa(<sè nguyªn cÇn chuyÓn sang d¹ng chuèi ký tù>, <chuçi kÕt qu¶>, <C¬ sè>); <c¬ sè> = 10 cã nghÜa lµ ta cÇn chuyÓn sang chuçi ký tù biÓu diÔn sè ë d¹ng thËp ph©n. Nh− vËy nÕu <c¬ sè> = 10 th× khi chuyÔn sè 11 ta sÏ ®−îc chuçi lµ "11", cßn ë c¬ sè 2 th× ®−îc chuçi lµ "1011". Hµm strcpy(<chuçi 1>, <chuçi 2>); thùc hiÖn g¸n <chuçi 2> cho <chuçi 1>. VÝ dô sau sÏ g¸n chuçi s thµnh "Ha Noi". char s[10]; strcpy(s,"Ha Noi"); Hµm strcat(<chuçi 1>, <chuçi 2>); thùc hiÖn ghÐp <chuçi 2> vµo phÝa sau <chuçi 1>. VÝ dô ®o¹n lÖnh char s[] = "Ha "; strcat(s,"Noi"); sÏ cho kÕt qu¶ lµ s ="Ha Noi". §o¹n lÖnh s = itoa(i,s,10); strcpy(TepNguon[i],"ZZN"); strcat(TepNguon[i],s); strcat(TepNguon[i],".DAT"); http://www.ebook.edu.vn 26 Trương Hải Bằng-Cấu trúc dữ liệu 2 víi i = 5 ch¼ng h¹n, sÏ cho ta gi¸ trÞ chuçi TepNguon[5] = "ZZN5.DAT". chóng t«i sö dông tªn tÖp b¾t ®Çu b»ng ZZ lµ cã ý ®Ó c¸c tÖp nµy hiÖn ë cuèi danh s¸ch c¸c tÖp, kh«ng bÞ v−íng khi xem c¸c tÖp kh¸c. C¸c lÖnh nWay=n; SplitFile(TenTep,TepNguon,nWay); sÏ ph©n bæ run trong tÖp ban ®Çu cho c¸c tÖp nguån. V× gi¸ trÞ nWay sÏ thay ®æi nªn ta kh«ng dïng trùc tiÕp gi¸ trÞ n. Ta muèn gi÷ l¹i n ®Ó sau nµy xo¸ c¸c tÖp ®· t¹o. §o¹n lÖnh while(true) {MergeFile(TepNguon,TepDich,nWay); if(nWay==1)break; for(i=0;i<nWay;i++) {strcpy(s,TepNguon[i]); strcpy(TepNguon[i],TepDich[i]); strcpy(TepDich[i],s); } } thùc hiÖn vßng lÆp trén c¸c tÖp cho ®Õn khi chØ cßn mét tÖp ®Ých duy nhÊt. Khi tÖp ®Ých ch−a ®−îc s¾p xÕp th× mçi lÇn b¾t ®Çu chu tr×nh míi chóng ta ph¶i ho¸n ®æi vai trß c¸c tÖp nguån vµ ®Ých. ë ®©y chóng ta ®· lµm ®iÒu ®ã b»ng c¸ch ho¸n ®æi tªn. Cuèi cïng ta copy tÖp ®Ých sang tÖp ban ®Çu vµ xo¸ c¸c tÖp nguån vµ ®Ých trung gian ®· sö dông. void SortFile(char *TenTep) {int i,n,nWay; char *TepNguon[10],*TepDich[10]; char *s; s= new char[12]; printf("\nSo duong can tron n (n>1) = ");scanf("%d",&n); for(i=0;i<n;i++) {TepNguon[i] = new char[12]; TepDich[i] = new char[12]; } for(i=0;i<n;i++) {s = itoa(i,s,10); strcpy(TepNguon[i],"ZZN"); strcat(TepNguon[i],s); strcat(TepNguon[i],".DAT"); strcpy(TepDich[i],"ZZD"); strcat(TepDich[i],s); strcat(TepDich[i],".DAT"); } nWay=n; SplitFile(TenTep,TepNguon,nWay); while(true) {MergeFile(TepNguon,TepDich,nWay); if(nWay==1)break; for(i=0;i<nWay;i++) {strcpy(s,TepNguon[i]); strcpy(TepNguon[i],TepDich[i]); strcpy(TepDich[i],s); } http://www.ebook.edu.vn 27 Trương Hải Bằng-Cấu trúc dữ liệu 2 } CopyFile(TepDich[0],TenTep); for(i=0;i<n;i++) {remove(TepNguon[i]);remove(TepDich[i]);} } 1.5. Ph−¬ng ph¸p trén ®a pha (Polyphase merge) Ph−¬ng ph¸p s¾p xÕp kiÓu ®a lèi c©n b»ng (hay nhiÒu ®−êng c©n b»ng) ®· cã nhiÒu −u ®iÓm. Tuy nhiªn khi sö dông c¸c b¨ng tõ lµm c¸c ®−êng c©n b»ng, ta thÊy r»ng mét nöa sè b¨ng dïng cho c¸c tÖp nguån vµ mét nöa sè b¨ng dïng cho tÖp ®Ých. Râ rµng sau mçi lÇn trén th× c¸c tÖp ®Ých vµ c¸c tÖp nguån ®æi vai trß cho nhau vµ sè l−îng c¸c b¨ng so víi sè b¨ng sö dông lóc ®Çu gi¶m dÇn cho tíi 1. Ng−êi ta nghÜ ra mét c¸ch ®Ó t¨ng sè l−îng c¸c b¨ng nguån. T¹i mçi thêi ®iÓm chØ cã mét b¨ng ®Ých, cßn tÊt c¶ c¸c b¨ng kh¸c lµ b¨ng nguån. Khi cã mét b¨ng nguån bÞ c¹n th× ng−êi ta l¹i sö dông nã lµm b¨ng ®Ých, b¨ng ®Ých ban ®Çu ®−îc sö dông lµm b¨ng nguån. Qu¸ tr×nh chuyÓn ®æi ®−îc xÈy ra mét c¸ch nhÞp nhµng cho ®Õn khi c¶ hÖ thèng chØ cßn mét b¨ng chøa d÷ liÖu ®· s¾p xÕp. Ph−¬ng ph¸p s¾p xÕp kiÓu nµy do R.L. Gilstar nªu ra n¨m 1960 vµ ®−îc gäi lµ trén ®a pha. Cã thÓ thÊy ngay lµ ®Ó cho qu¸ tr×nh trén ®a pha thùc hiÖn ®−îc th× d÷ liÖu ban ®Çu ph¶i ®−îc ph©n bæ mét c¸ch thÝch hîp trªn c¸c b¨ng nguån. VÝ dô nÕu ta cã 2 b¨ng nguån lµ T1, T2 vµ mét b¨ng ®Ých lµ T3. NÕu sè run trong T1 vµ trong T2 lµ c¸c sè Fibonacci liªn tiÕp th× ta cã thÓ ¸p dông phu¬ng ph¸p trén ®a pha nh− sau: T1 Fn (= Fn-1+Fn-2) Fn-2 Fn-3 (= Fn-4+Fn-5) ... T2 T3 Fn-1 Fn-2 (= Fn-3+Fn-4) Fn-4 ... Fn-1 (= Fn-2+Fn-3) Fn-3 ... VÝ dô víi n = 7 ta cã F7 = 13, F6 = 8. Qu¸ tr×nh trén ®−îc m« t¶ trong b¶ng sau: T1 T2 T3 13 8 5 8 5 3 3 2 1 2 1 1 1 Gi¶i thÝch Lóc ®Çu cã 13 run trong T1 vµ 8 run trong T2 Trén 8 run trong mçi run vµo T3, T1 cßn 5 run Trén 5 run vµo T2, trong T3 cßn 3 run... Trén 1 run trong T1 víi 1 run trong T3 ë b−íc tr−íc vµo T2, T3 cßn l¹i 1 run. Trén 1 run trong T2 víi 1 run trong T3 ë b−íc tr−íc vµo T1, chØ cßn l¹i mét run, qu¸ tr×nh kÕt thóc. C¸c sè Fibonacci th«ng th−êng nh− trªn ®©y ®−îc gäi lµ c¸c sè Fibonacci cÊp 1. Ta cã thÓ ®Þnh nghÜa c¸c sè Fibonacci cÊp cao h¬n vµ ¸p dông trén ®a pha cho nhiÒu b¨ng tõ h¬n. Tuy nhiªn trong thùc tÕ th× trong tÖp ban ®Çu ta cã sè run kh«ng nhÊt thiÕt lµ tæng cña c¸c sè Fibonacci liÒn nhau. Ng−êi ta ®· cã c¸c biÖn ph¸p kh¾c phôc vÊn ®Ò nµy. Tuy nhiªn chóng ta sÏ kh«ng ®i s©u t×m hiÓu ë ®©y. http://www.ebook.edu.vn 28 Ch−¬ng 2 B¶ng b¨m (Hash table) 2.1. Më ®Çu Th«ng th−êng c¸c thao t¸c t×m kiÕm, chÌn hay xãa mét phÇn tö lµ c¸c thao t¸c th−êng xuyªn ph¶i thùc hiÖn trªn mét cÊu tróc d÷ liÖu. ë cÊu tróc danh s¸ch, c¸c thao t¸c nµy cã thêi gian tÝnh to¸n tuyÕn tÝnh. Khi chuyÓn sang cÊu tróc c©y c©n b»ng ta ®· ®¹t ®−îc sù c¶i tiÕn ®¸ng kÓ: thêi gian tÝnh to¸n chØ cßn O(logn). Víi n lín râ rµng thao t¸c cã ®é phøc t¹p tÝnh to¸n O(logn) nhanh h¬n rÊt nhiÒu: NÕu nh− víi n=1000 ta cã log2n~10, cßn víi n=1000 000 th× log2n~20. Tuy nhiªn trong mét sè øng dông, thÝ dô viÖc t×m kiÕm vµ truy xuÊt th«ng tin trªn m¹ng, ng−êi ta mong muèn thêi gian truy xuÊt lµ tøc thêi, tøc lµ cã thêi gian tÝnh to¸n O(1). Khi t×m kiÕm mét b¶n ghi ta th−êng dùa vµo mét tr−êng nµo ®ã gäi lµ khãa. Ta ph¶i so s¸nh khãa cÇn t×m víi c¸c khãa cña c¸c b¶n ghi trong cÊu tróc d÷ liÖu. Ta sÏ cã thêi gian truy xuÊt lµ tøc thêi nÕu tõ gi¸ trÞ khãa x ta cã thÓ chØ ngay ®−îc vÞ trÝ cña b¶n ghi chøa khãa cÇn t×m. Tøc lµ ta cÇn t¹o ra mét ¸nh x¹ gi÷a gi¸ trÞ khãa x vµ ®Þa chØ b¶n ghi t−¬ng øng. Mét c¸ch tù nhiªn ta nghÜ ngay ®Õn c¸ch m· hãa c¸c khãa x sao cho c¸c m· ®ã t−¬ng øng víi ®Þa chØ. ThÝ dô nÕu khãa chóng ta lµ chuçi c¸c ký tù A -> Z, ta cã thÓ ký hiÖu A=1, B=2,..., Z=26 vµ hiÓu mét chuçi ký tù lµ mét sè trong hÖ c¬ sè 32. §Ó t×m vÞ trÝ bé nhí cña mét chuçi, thÝ dô AKEY ta tÝnh gi¸ trÞ sè t−¬ng øng b»ng c«ng thøc: 'Y'+32*('E'+32*('K'+32*'A')) = 25+32*(5+32*(11+32*1)) B»ng c¸ch nµy, viÖc tÝnh to¸n ®Þa chØ kh¸ dÔ dµng, nh−ng ta l¹i gÆp mét trë ng¹i lín: nh÷ng khãa dµi vµ b¾t ®Çu b»ng c¸c ký tù ë cuèi b¶ng ch÷ c¸i nh− x,y z sÏ cã ®Þa chØ rÊt lín, v−ît ra ngoµi ph¹m vi cña bé nhí th«ng th−êng. C¸c gi¸ trÞ khãa th−êng cã thÓ t¹o nªn tËp hîp rÊt lín, ta kh«ng thÓ t¹o nªn ¸nh x¹ 1 - 1 gi÷a c¸c gi¸ trÞ khãa vµ ®Þa chØ bé nhí ®−îc. Ngoµi ra ta cßn gÆp mét sè trë ng¹i kh¸c, vÝ dô gi¶ sö môc tin cña chóng ta chøa kh¸ nhiÒu th«ng tin vÒ nh©n sù vµ do ®ã mçi môc cã thÓ chiÕm mét vïng bé nhí kh¸ lín. Nh− vËy nÕu ta l−u tr÷ môc tin vÒ nh©n viªn cã tªn “LAM” trong vïng bé nhí cã ®Þa chØ lµ P = ‘L’*322+’A’*32 +’M’ th× ta ph¶i l−u tr÷ nh©n viªn cã tªn “LAN” ë ®Þa chØ ë ®Þa chØ P+1. Râ rµng ®Þa chØ nµy ®· bÞ chiÕm bëi nh©n viªn “LAM”. Cßn mét vÊn ®Ò n÷a, nÕu ta ¸nh x¹ khãa vµo bé nhí th× rÊt cã thÓ vïng bé nhí ®ã ®· bÞ chiÕm bëi mét ch−¬ng tr×nh kh¸c vµ nÕu ta cè t×nh sö dông vïng nµy ®Ó l−u tr÷ d÷ liÖu th× cã thÓ g©y sù cè kh«n l−êng. Râ rµng viÖc biÕn ®æi khãa thµnh ®Þa chØ l−u tr÷ d÷ liÖu nãi chung kh«ng kh¶ thi, v× ta kh«ng thÓ biÕt ®−îc vïng ®Þa chØ nµo cßn trèng. Ng−êi ta ®· t×m c¸ch gi¶i quyÕt vÊn ®Ò nµy b»ng c¸ch t¹o ra mét b¶ng chøa c¸c phÇn tö lµ c¸c ®Þa chØ cña c¸c môc d÷ liÖu. C¸c khãa thay v× ®−îc biÕn ®æi thµnh c¸c ®Þa chØ sÏ ®−îc biÕn ®æi thµnh c¸c gi¸ trÞ nguyªn chØ vÞ trÝ cña ®Þa chØ trong b¶ng. B¶ng cã cÊu tróc vµ môc ®Ých sö dông nh− võa nãi ®−îc gäi lµ b¶ng b¨m. Hµm h(x) chuyÓn ®æi khãa x thµnh vÞ trÝ trong b¶ng b¨m ®−îc gäi lµ hµm b¨m. B¶ng b¨m th«ng dông nhÊt lµ mét m¶ng gåm m thµnh phÇn H = (a0, a1,... am-1), trong ®ã ai lµ c¸c ®Þa chØ, tøc lµ c¸c con trá trá ®Õn c¸c b¶n ghi chøa d÷ liÖu. Hµm b¨m h(x) lµ hµm biÕn ®æi khãa x thµnh vÞ trÝ trong b¶ng b¨m. NÕu khãa lµ c¸c sè nguyªn hoÆc biÔu diÔn ®−îc b»ng sè nguyªn nh− c¸c chuçi ký tù, th× hµm b¨m ®−îc dïng nhiÒu nhÊt lµ hµm lÊy gi¸ trÞ phÇn d− khi chia x cho m, cã nghÜa lµ h(x)=x%m. Ng−êi ta th−êng chän m lµ sè nguyªn tè. Nh− vËy hµm b¨m kh«ng cho gi¸ trÞ ®Þa chØ trùc tiÕp mµ chØ cho vÞ trÝ cña ®Þa chØ trong b¶ng b¨m. Râ rµng víi ¸nh x¹ nh− vËy th× cã nhiÒu gi¸ trÞ khãa sÏ cho cïng mét vÞ trÝ ®Þa chØ. HiÖn t−îng nµy ®−îc gäi lµ hiÖn t−îng ®ông ®é (collision). Khi x©y dùng b¶ng b¨m, ta lu«n chØ râ hµm b¨m t−¬ng øng víi nã vµ ph−¬ng ph¸p tr¸nh ®ông ®é. Ph−¬ng ph¸p b¶ng b¨m th−êng c©n ®èi ®−îc thêi gian truy xuÊt vµ dung l−îng bé nhí nªn ®−îc sö dông kh¸ réng r·i trong c¸c hÖ thèng m¸y tÝnh nh»m cung cÊp truy xuÊt nhanh ®Õn mét l−îng lín d÷ liÖu. Sau ®©y ta sÏ kh¶o s¸t mét sè c¸ch cµi ®Æt b¶ng b¨m vµ c¸c ph−¬ng ph¸p tr¸nh hiÖn t−îng ®ông ®é. http://www.ebook.edu.vn CÊu tróc d÷ liÖu 2 – Ch−¬ng 2. B¶ng b¨m 2.2. C¸c ph−¬ng ph¸p tr¸nh ®ông ®é Khi cã tËp khãa K, ta ph¶i x©y dùng b¶ng b¨m, hµm b¨m sao cho tr¸nh ®−îc hiÖn t−îng ®ông ®é. Sau ®©y lµ mét sè ph−¬ng ph¸p th−êng dïng: 2.2.1. Dïng danh s¸ch liªn kÕt Còng gièng nh− trong phÇn cÊu tróc danh s¸ch chóng ta ®· nãi ®Õn, danh s¸ch liªn kÕt lµ mét tËp hîp c¸c b¶n ghi ®−îc s¾p tuyÕn tÝnh; mçi b¶n ghi cã 2 phÇn: phÇn chøa th«ng tin vµ phÇn chøa ®Þa chØ cña b¶n ghi tiÕp theo. Th«ng th−êng b¶n ghi cuèi cïng chØ ®Õn b¶n ghi rçng tøc lµ NULL. a. Ph−¬ng ph¸p liªn kÕt ngoµi C¸c thµnh phÇn cña H chøa ®Þa chØ ®Çu cña c¸c danh s¸ch liªn kÕt. C¸c nót bÞ xung ®ét t¹i vÞ trÝ i sÏ ®−îc kÕt nèi thµnh danh s¸ch liªn kÕt do con trá t¹i i trá tíi. Khi thªm mét nót míi vµo b¶ng b¨m, hµm b¨m h(k) sÏ x¸c ®Þnh vÞ trÝ i trong kho¶ng tõ 0 ®Õn m-1, sau ®ã nót nµy sÏ ®−îc thªm vµo danh s¸ch i. ThÝ dô nÕu hµm b¨m lµ hµm lÊy phÇn d− khi chia k cho m th× nót i sÏ trá ®Õn danh s¸ch liªn kÕt chøa c¸c b¶n ghi cã khãa k chia cho m d− i. H×nh 2.1 sau ®©y minh häa b¶ng b¨m víi hµm b¨m chia d− vµ m = 3 0 6 1 7 2 5 15 18 23 H×nh 2.1 B¶ng b¨m liªn kÕt ngoµi. ë ®©y c¸c « 0 ®−îc hiÓu lµ ®Þa chØ nót ®Çu cña danh s¸ch c¸c khãa ®ång d− víi 0 mod 3, « 1 ®−îc hiÓu lµ ®Þa chØ nót ®Çu cña danh s¸ch c¸c khãa ®ång d− víi 1 mod 3. b. Ph−¬ng ph¸p liªn kÕt trong Ta vÉn dïng danh s¸ch liªn kÕt ®Ó tr¸nh ®ông ®é, nh−ng ta chØ dïng c¸c nót trong b¶ng H mµ th«i. Mçi nót cña H b©y giê cã 2 tr−êng: tr−êng thø nhÊt Pkey chØ ®Õn b¶n ghi chøa d÷ liÖu, cßn tr−êng thø 2 lµ tr−êng next chØ ®Õn nót tiÕp theo trong danh s¸ch c¸c nót cã gi¸ trÞ khãa bÞ ®ông ®é. Khi khëi ®éng c¸c con trá Pkey chØ tíi NULL, c¸c tr−êng next = -1 ®Ó ¸m chØ lµ kh«ng cã nót nµo liªn kÕt víi nót ®ã. Khi thªm mét nót cã khãa k tr−íc hÕt ta tÝnh hµm i = h(k). NÕu vÞ trÝ i ch−a cã nót, nghÜa lµ tr−êng Pkey chØ ®Õn NULL th× ta ®Æt nót míi vµo vÞ trÝ i. NÕu nót ®ã ®· bÞ chiÕm th× ta ph©n biÖt 2 tr−êng hîp: a. NÕu gi¸ trÞ khãa trong b¶n ghi do H[i].Pkey chØ tíi (vÝ dô khãa nµy lµ x) cïng hä víi k (tøc lµ h(x)=h(k)) ta lÇn theo tr−êng next ®Ó ®i tíi b¶n ghi cuèi cïng trong danh s¸ch con; sau ®ã ta t×m mét nót trèng cuèi b¶ng ®Ó ®Æt nót míi vµo ®ã. §Æt con trá next cña phÇn tö cuèi cïng tr−íc ®ã trá tíi nót nµy vµ ®Æt con trá next cña nót nµy b»ng -1 vµ kÕt thóc. b. NÕu gi¸ trÞ khãa trong b¶n ghi do H[i].Pkey chØ tíi kh«ng cïng hä víi k (tøc lµ h(x)≠h(k)) ta t×m mét nót trèng cuèi b¶ng ®Ó ®Æt nót míi vµo ®ã. §Æt con trá next cña nót nµy b»ng -1 vµ kÕt thøc. Khi cÇn t×m kiÕm khãa x trªn b¶ng b¨m, tr−íc hÕt ta ®Æt i = h(x). NÕu tr−êng Pkey trong vÞ trÝ nµy chØ ®Õn nót cã khãa = x viÖc t×m kiÕm thµnh c«ng vµ kÕt thóc; Cßn nÕu kh«ng nh− vËy th× ta xem khãa do « nµy trá tíi cã cïng hä víi x kh«ng. NÕu cã th× ta lÇn theo tr−êng next , cho ®Õn khi gÆp khãa x th× viÖc t×m kiÕm thµnh c«ng kÕt thóc; nÕu gÆp next = -1 mµ vÉn kh«ng t×m http://www.ebook.edu.vn 30 CÊu tróc d÷ liÖu 2 – Ch−¬ng 2. B¶ng b¨m thÊy th× viÖc t×m kiÕm kh«ng thµnh c«ng. NÕu « thø i kh«ng cïng hä víi x th× ta b¾t ®Çu xuÊt ph¸t tõ ®¸y cña b¶ng, tøc lµ vÞ trÝ max-1 ®i dÇn lªn phÝa trªn ®Ó t×m vµ dõng l¹i khi gÆp « ®Çu tiªn cßn trèng. KÕt qu¶ t×m kiÕm phô thuéc vµo viÖc t×m thÊy x hay kh«ng. H×nh sau biÓu diÔn c¸ch thªm c¸c nót 35, 15,45 vµo b¶ng chia d− cã m=10. i 0 1 2 3 4 5 6 7 8 9 pkey next -1 -1 -1 -1 -1 9 -1 -1 -1 8 35 45 15 H×nh 2.2 B¶ng b¨m liªn kÕt trong. ë ®©y ta ghi gi¸ trÞ khãa thay cho ®Þa chØ cña c¸c nót th«ng tin chøa khãa. Nh− vËy sè 35 sÏ ®−îc hiÓu lµ ®Þa chØ cña khãa 35. 2.2.2. Dïng danh s¸ch kÒ ngoµi Ph−¬ng ph¸p nµy vÒ c¬ b¶n gièng víi ph−¬ng ph¸p liªn kÕt ngoµi. Ta còng dïng mét m¶ng H, nh−ng c¸c thµnh phÇn cña H b©y giê lµ c¸c danh s¸ch kÒ cµi ®Æt b»ng m¶ng ®éng. C¸c danh s¸ch con nµy tuy cã cì cè ®Þnh nh−ng ta cã thÓ dïng t¸c vô grow ®Ó t¨ng lªn khi cÇn thiÕt. Nh− vËy khi khai b¸o, ®Ó khái l·ng phÝ bé nhí ta chØ cÇn ®Æt cì cña danh s¸ch kh¸ nhá; khi cÇn thiÕt t¸c vô grow sÏ tù ®éng t¨ng cì cña danh s¸ch lªn. Cã thÓ m« t¶ b¶ng b¨m dïng danh s¸ch kÒ víi kÝch th−íc vµ c¸c khãa nh− ë h×nh 2.1. nh− sau: 0 6 1 7 2 5 15 18 23 H×nh 2.3 B¶ng b¨m dïng danh s¸ch kÒ ngoµi. Khi dïng danh s¸ch liªn kÕt ngoµi hoÆc danh s¸ch kÒ ngoµi ta thÊy r»ng nÕu cì cña b¶ng b¨m lµ M th× ta cÇn M danh s¸ch. Kinh nghiÖm cho thÊy r»ng nªn chän M ®ñ lín sao cho ®é dµi c¸c danh s¸ch chØ kho¶ng 10 phÇn tö. Nh− vËy M b»ng kho¶ng 1/10 sè khãa sö dông. 2.2.3. Ph−¬ng ph¸p dß tuyÕn tÝnh (linear probing method) B¶n chÊt cña ph−¬ng ph¸p nµy lµ nªu ra quy t¾c ®Ó dïng c¸c nót cßn trèng trong b¶ng ®Ó chøa c¸c nót bÞ ®ông ®é. Víi mét khãa k bÊt kú ta tÝnh hµm b¨m i = h(k) vµ thùc hiÖn c¸c b−íc sau: - NÕu nót i trèng th× thªm nót míi t¹i ®Þa chØ nµy. - NÕu bÞ xung ®ét th× dïng hµm b¨m l¹i h1(k) = (h(k)+1)%m - NÕu vÉn bÞ xung ®ét th× dïng hµm b¨m l¹i h2(k) = (h(k)+2)%m http://www.ebook.edu.vn 31 CÊu tróc d÷ liÖu 2 – Ch−¬ng 2. B¶ng b¨m Cø nh− vËy ®Õn b−íc thø j ta dïng hµm b¨m l¹i hj(k) = (h(k)+j) % m cho ®Õn khi t×m ®−îc vÞ trÝ trèng. L−u ý lµ nÕu dß ®Õn cuèi b¶ng th× ta l¹i quay l¹i tõ ®Çu (b¶n th©n hµm hj(k) ®· bao hµm ®iÒu nµy). NhËn xÐt b¶ng b¨m dïng ph−¬ng ph¸p dß tuyÕn tÝnh: - Khi t×m mét nót cã khãa k, tr−íc hÕt ta tÝnh i = h(k) ®Ó x¸c ®Þnh vÞ trÝ xuÊt ph¸t trong b¶ng b¨m. Sau ®ã ta xÐt tõng nót trong khèi ®Æc chøa c¸c nót xuÊt ph¸t tõ i, nót nµo cã khãa trïng víi k lµ nót cÇn t×m. - T¸c vô xãa nót kh¸ phøc t¹p. - B¶ng b¨m cµi ®Æt kiÓu nµy khi chØ cã c¸c nót th−a thít trªn b¶ng. Tr−êng hîp xÊu nhÊt lµ b¶ng b¨m gÇn ®Çy, lóc nµy h×nh thµnh mét khèi ®Æc cã n nót nªn tèc ®é truy xuÊt cã bËc O(n). 2.2.4. Ph−¬ng ph¸p dß bËc hai (quadratic probing method) B¶ng b¨m dß tuyÕn tÝnh bÞ h¹n chÕ lµ c¸c nót r¶i kh«ng ®Òu. Ng−êi ta dïng hµm b¨m l¹i bËc 2 víi hy väng r¶i c¸c nót ®Òu h¬n. C¸ch thùc hiÖn nh− sau: Khi cÇn thªm nót cã khãa k vµo b¶ng, tr−íc hÕt ta tÝnh i = h(k), lµ mét gi¸ trÞ trong kho¶ng tõ 0 ®Õn m-1 - NÕu vÞ trÝ i cßn trèng th× ®Æt nót cÇn thªm vµo vÞ trÝ i. - NÕu bÞ xung ®ét th× lÇn l−ît t×m t×m ë c¸c vÞ trÝ i+12 , i+22 , i+32 ,..., i+j2 víi l−u ý lµ ®Õn cuèi b¶ng ta trë vÒ dß tõ ®Çu b¶ng, thùc chÊt lµ dß ë vÞ trÝ (i+j2) % m. Khi thÊy vÞ trÝ trèng ®Çu tiªn th× ta ®Æt nót míi vµo vÞ trÝ ®ã. Khi t×m mét khãa th× tr−íc hÕt ta t×m ë vÞ trÝ i = h(k), nÕu kh«ng thÊy th× t×m ë c¸c vÞ trÝ hj(k) = (h(k)+j) % m , j=1,2,... Khi r¬i vµo vÞ trÝ trèng th× cã nghÜa lµ kh«ng t×m thÊy. Chó ý: B¶ng b¨m víi ph−¬ng ph¸p dß bËc 2 nªn chän m lµ sè nguyªn tè. 2.3. Cµi ®Æt b¶ng b¨m Sau ®©y chóng t«i giíi thiÖu 3 ch−¬ng tr×nh: cµi ®Æt b¶ng b¨m dïng danh s¸ch liªn kÕt ngoµi, b¶ng b¨m dïng danh s¸ch kÒ ngoµi vµ b¶ng b¨m dïng liªn kÕt trong. PhÐp b¨m dïng ®Õn trong cµi ®Æt lµ phÐp chia d−. B¹n ®äc cã thÓ tù cµi ®Æt c¸c lo¹i b¶ng b¨m kh¸c. 2.3.1. Cµi ®Æt b¶ng b¨m dïng danh s¸ch liªn kÕt ngoµi Chóng ta sÏ tËn dông cµi ®Æt danh s¸ch liªn kÕt trong phÇn tr−íc vµ dïng lÖnh #include ®Ó chÌn vµo ®Çu tÖp ch−¬ng tr×nh nguån cµi ®Æt b¶ng b¨m. B¶ng b¨m giê ®©y ®¬n gi¶n lµ mét m¶ng mµ mçi phÇn tö lµ mét cÊu tróc danh s¸ch. Khai b¸o vµ ®Þnh nghÜa cÊu tróc danh s¸ch b»ng ph−¬ng ph¸p liªn kÕt: Chóng ta sÏ khai b¸o vµ ®Þnh nghÜa mét líp danh s¸ch vµ l−u trong tÖp LIST_H.CPP. C¸c phÇn tö cña danh s¸ch lµ c¸c nót th«ng tin cã cÊu tróc ®−îc ®Þnh nghÜa trong ch−¬ng tr×nh cµi ®Æt b¶ng b¨m, tr−íc khi cã lÖnh # include ®Ó ®−a tÖp LIST_H.CPP vµo ch−¬ng tr×nh. CÊu tróc nót th«ng tin cã d¹ng: struct node {int key; node* next; } trong ®ã tr−êng key chøa th«ng tin, cßn tr−êng next lµ ®Þa chØ cña nót tiÕp theo trong danh s¸ch. ChØ cã mét sè t¸c vô c¬ b¶n ®−îc ®Þnh nghÜa trªn danh s¸ch nh− empty, display, dele, append, traverse, search, clear. B¹n ®äc cã thÓ t×m hiÓu trùc tiÕp tõ ch−¬ng tr×nh. http://www.ebook.edu.vn 32 CÊu tróc d÷ liÖu 2 – Ch−¬ng 2. B¶ng b¨m //LIST_H.CPP //Danh sach lien ket thuan class List {public: node* phead; //A pointer to the first item. node* pcurrent; //A pointer to the current item. int count; //So phan tu List();//Khoi tao ~List();//Huy khoi tao int empty();//Kiem tra danh sanh neu rong thi tra ve 1 void display();//Hien khoa hien thoi void dele();//Xoa ban ghi hien thoi void append(int);//Them mot phan tu cuoi danh sach co khoa da cho void traverse();//Xem toan bo danh sach int search(int);//Tim kiem khoa x void clear();//Xoa danh sach, giai phong bo nho }; //--------------------------List::List() {phead=NULL;pcurrent=NULL; count=0; }; //--------------------------List::~List() {node *p1,*p; p=phead; while(p) {p1=p; p=p->next; delete p1; } phead=NULL; } //--------------------------int List::empty() {return phead==NULL; } //--------------------------void List::display() {if(pcurrent) cout<<endl<<pcurrent->key<<" "; }; //--------------------------void List::dele() {if(empty()) return; node *p,*p1; p=phead; while(p && p!=pcurrent) {p1=p; http://www.ebook.edu.vn 33 CÊu tróc d÷ liÖu 2 – Ch−¬ng 2. B¶ng b¨m p=p->next; } if(p==pcurrent) //p la nut hien thoi, p1 la nut truoc nut ht {p1->next=p->next; if(p->next) pcurrent=p->next;else pcurrent=p1; delete p; count--; }; return; }; //--------------------------void List::append(int x) {node *p,*p1,*pp; p=phead; pp = new node; pp->key=x;pp->next=NULL; if(empty()) {phead=pp;pcurrent=pp;count++;return;} p1=NULL; p = phead; while(p!=NULL) {p1=p; p=p->next; } //Sau vong lap thi p1 la nut cuoi cung p1->next = pp; pcurrent=pp; count++; }; //--------------------------//Hien toan bo danh sach len man hinh. void List::traverse() {node* p=phead; while(p) {cout<<p->key<<" "; p=p->next; } } //--------------------------//Tim con tro co noi dung x trong danh sach int List::search(int x) {node* p=phead; while(p) {if(p->key==x) {pcurrent=p;return(true);} p=p->next; } return(false); }; //--------------------------//Xoa danh sach, tuc giai phong tat ca cac nut trong danh sach. http://www.ebook.edu.vn 34 CÊu tróc d÷ liÖu 2 – Ch−¬ng 2. B¶ng b¨m void List::clear() {node *p1,*p; p=phead; while(p!=NULL) {p1=p; p=p->next; delete p1; } phead=NULL; } PhÇn cµi ®Æt b¶ng b¨m: ƒ Khai b¸o b¶ng b¨m Chóng ta dïng m¶ng ®éng H ®Ó cµi ®Æt b¶ng b¨m. Mçi phÇn tö cña m¶ng b©y giê kh«ng ph¶i lµ sè nguyªn, ký tù hay nót th«ng tin nh− th−êng lÖ mµ lµ mét ®èi t−îng danh s¸ch. BiÕn max lµ cì cña b¶ng b¨m, c¬ së cña phÐp chia d−. Nh− vËy mét khãa x bÊt kú sÏ ®−îc chÌn vµo phÇn tö thø i = x%max cña b¶ng b¨m, tøc lµ chÌn vµo danh s¸ch liªn kÕt thø i. Con trá pcurrent lµ ®Þa chØ cña nót hiÖn thêi, lµ ®Þa chØ quy −íc dïng trong c¸c t¸c vô t×m kiÕm. C¸c thao t¸c trªn b¶ng b¨m kh¸ ®¬n gi¶n, v× chñ yÕu c¸c thao t¸c nµy gäi ®Õn c¸c t¸c vô trªn danh s¸ch. struct node {int key; node* next; }; //--------------------------#include "List_h.cpp" //--------------------------class HashTab {private: List* H; int max; //size of Hash table node* pcurrent; //current node of the hash table int count; //So phan tu trong bang bam public: HashTab(int); ~HashTab(); void display(); int empty(); int search(int x); void insert(int x); void InsertMany(); void traverse(); }; ƒ Khëi t¹o b¶ng b¨m T¸c vô khëi t¹o b¶ng b¨m cã tham sè m, ®−îc ®Æt ngÇm ®Þnh lµ 10, lµ cì cña b¶ng b¨m. Nh− vËy khi khai b¸o mét biÕn cã kiÓu b¶ng b¨m mµ ta kh«ng chØ râ cì th× cì cña b¶ng sÏ ®−îc lÊy lµ http://www.ebook.edu.vn 35 CÊu tróc d÷ liÖu 2 – Ch−¬ng 2. B¶ng b¨m 10. Trong t¸c vô nµy mét m¶ng ®éng gåm max danh s¸ch ®−îc cÊp ph¸t bé nhí. Tuy nhiªn lóc ®Çu c¸c danh s¸ch cßn rçng, nªn thùc ra max danh s¸ch còng chØ lµ max con trá. void HashTab::HashTab(int m = 10) {max=m; H = new List [max];pcurrent=NULL;; return; } ƒ Hñy khëi t¹o b¶ng b¨m Khi kÕt thóc sö dông b¶ng b¨m ta gi¶i phãng vïng bé nhí ®· cÊp cho b¶ng b¨m. LÇn l−ît ®i tõ ®Çu b¶ng ®Õn cuèi b¶ng, ta gäi t¸c vô clear cña danh s¸ch ®Ó gi¶i phãng vïng bé nhí t−¬ng øng. void HashTab::~HashTab() {for(int i=0;i<max;i++) H[i].clear(); delete [] H; return; } ƒ T×m kiÕm trªn b¶ng b¨m §Ó t×m kiÕm mét khãa x trªn b¶ng b¨m, ®Çu tiªn ta x¸c ®Þnh danh s¸ch mµ trªn ®ã cã thÓ cã x. Danh s¸ch cÇn x¸c ®Þnh chÝnh lµ danh s¸ch thø i = x%max trªn b¶ng b¨m. Ta dïng t¸c vô search cña danh s¸ch nµy ®Ó t×m kiÕm khãa x. NÕu t×m thÊy th× t¸c vô tr¶ vÒ gi¸ trÞ true, con trá pcurrent chØ nót t×m thÊy trªn danh s¸ch; NÕu kh«ng t×m thÊy th× t¸c vô tr¶ vÒ gi¸ trÞ false. int HashTab::search(int x) {int i=x%max; if(H[i].search(x)) {pcurrent=H[i].pcurrent; return true; } return false; } ƒ ChÌn phÇn tö x vµo b¶ng b¨m §Ó chÌn mét phÇn tö vµo b¶ng b¨m, tr−íc hÕt ta tÝnh i = x%max, sau ®ã phÇn tö x ®−îc chÌn vµo danh s¸ch thø i theo gi¶i thuËt insert cña danh s¸ch nµy. void HashTab::insert(int x) {int i=x%max; H[i].append(x); pcurrent=H[i].pcurrent; count++; } ƒ ChÌn nhiÒu phÇn tö vµo b¶ng b¨m void HashTab::InsertMany() {clrscr();int m,i,x; printf("\Nhap du lieu vao bang bam:"); printf("\n1. Nhap truc tiep"); http://www.ebook.edu.vn 36 CÊu tróc d÷ liÖu 2 – Ch−¬ng 2. B¶ng b¨m printf("\n2. Tao ngau nhien"); printf("\n\n Hay chon 1 hoac 2: "); fflush(stdin); char ch=getch(); printf("\nCho biet so phan tu can dua vao bang bam: "); fflush(stdin); scanf("%d",&m); if(ch=='1') {printf("\nHay nhap %d so: ",m); for(i=0;i<m;i++) {scanf("%d",&x); insert(x); } } else {randomize(); for(i=0;i<m;i++) {x=random(5*m); insert(x); } } }; ƒ DuyÖt b¶ng b¨m §Ó duyÖt b¶ng b¨m, ta ®i tõ ®Çu b¶ng ®Õn cuèi b¶ng vµ duyÖt tõng danh s¸ch mét. void HashTab::traverse() {for(int i=0;i<max;i++) {cout<<endl<<i<<": ";H[i].traverse();} } 2.3.2. Cµi ®Æt b¶ng b¨m dïng danh s¸ch kÒ ngoµi Chóng ta sÏ tËn dông cµi ®Æt danh s¸ch kÒ trong phÇn tr−íc vµ dïng lÖnh #include ®Ó chÌn vµo ®Çu tÖp ch−¬ng tr×nh nguån cµi ®Æt b¶ng b¨m. B¶ng b¨m giê ®©y ®¬n gi¶n lµ mét m¶ng mµ mçi phÇn tö lµ mét cÊu tróc danh s¸ch. Khai b¸o vµ ®Þnh nghÜa cÊu tróc danh s¸ch kÒ: Chóng ta sÏ khai b¸o vµ ®Þnh nghÜa mét líp danh s¸ch vµ l−u trong tÖp LISTKE_H.CPP. C¸c phÇn tö cña danh s¸ch cã kiÓu nguyªn, cïng kiÓu víi khãa. Trong c¸c bµi to¸n thùc tÕ, c¸c phÇn tö nµy cã thÓ cã cÊu tróc phøc t¹p h¬n. ChØ cã mét sè t¸c vô c¬ b¶n ®−îc ®Þnh nghÜa trªn danh s¸ch nh− empty, full, display, dele, append, traverse, sort, sorted, bsearch, insert, clear. B¹n ®äc cã thÓ t×m hiÓu trùc tiÕp tõ ch−¬ng tr×nh. //LISTKE_H.CPP //Danh sach cai dat bang mang dong (contiguous list). class List {public: int *a; //the list itself: a dynamic array of type int; http://www.ebook.edu.vn 37 CÊu tróc d÷ liÖu 2 – Ch−¬ng 2. B¶ng b¨m int max; //Starting size of storage array... int delta; //Increment size of storage array... int count; //number of items in list... int current; //currently indicated item (for search etc...) int grow(); //Function to increase list size. List(int); //Khoi tao mang chua danh sach co co size ~List(); //Huy khoi tao int empty();//Kiem tra neu danh sach rong thi tra ve true int full(); //Kiem tra neu danh sach day thi tra ve gia tri true void display(); void dele(); void append(int);//Them mot phan tu cuoi danh sach co khoa da cho void traverse(); //Duyet danh sach void sort(); //Sap xep danh sach int sorted(); //Kiem tra neu danh sach da sap xep thi tra ve true int search(int);//Tim kiem tuyen tinh tren danh sach int bsearch(int);//Tim kiem nhi phan tren danh sach void insert(int);//Chen phan tu vao danh sach da sap xep void clear(); //Xoa danh sach, giai phong bo nho }; //--------------------------List::List(int size=10) {max=size; delta=max/2; count=0; a=new int[max]; current=EOF; }; //--------------------------List::~List() {delete [] a;} //--------------------------void List::clear() {delete [] a;} //--------------------------int List::empty() {return count==0; }; //--------------------------int List::full() {return count==max; }; //--------------------------int List::grow() //Increase the size of the list by delta. {int newmax=max+delta; int* newa=new int [newmax]; if(!newa) return false; //Allocation failed. //Copy original list contents to new space... http://www.ebook.edu.vn 38 CÊu tróc d÷ liÖu 2 – Ch−¬ng 2. B¶ng b¨m for(int i=0;i<max;i++) newa[i]=a[i]; delete [] a; //Get rid of old storage. a=newa; //Pointer to new list now in data. max=newmax; return true; } //--------------------------void List::display() {if(current==EOF) {cout<<"EOF";return;}; cout<<endl<<"a["<<current<<"] = "<<a[current]; }; //--------------------------void List::dele() {if(empty()) return; if(current==EOF) {cout<<"EOF";return;} for(int i=current;i<count-2;i++) a[i]=a[i+1];count--; }; //--------------------------void List::append(int x) {if(full() && !grow()) {cout<<"Danh sach bi day";return;} a[count++]=x; }; //--------------------------//Duyet danh sach va cho hien tren man hinh. void List::traverse() {int i; for(i=0;i<count;i++) cout<<a[i]<<" "; } //--------------------------//Kiem tra xem day da sap xep chua void List::sort() {int i,j,k,t; for(i=0;i<count-1;i++) {k=i; for(j=i+1;j<count;j++) if(a[j]<a[k]) k = j; if(k!=i) {t=a[i];a[i]=a[k];a[k]=t;} } } //--------------------------//Kiem tra xem day da sap xep chua int List::sorted() {int i,k; for(i=0;i<count-1;i++) if(a[i]>a[i+1]) return(false); return true; } //--------------------------/*Tim kiem tuyen tinh vi tri co gia tri x. http://www.ebook.edu.vn 39 CÊu tróc d÷ liÖu 2 – Ch−¬ng 2. B¶ng b¨m /*Tim thay thi dat current=vi tri tim thay va tra ve true, khong tim thay tra ve false*/ int List::search(int x) {int i; for(i=0;i<count;i++) if(a[i]==x) {current=i;return(true);} return(false); }; //--------------------------/*Tim kiem tuyen nhi phan khoa x. /*Tim thay thi dat current=vi tri tim thay va tra ve true, khong tim thay tra ve false*/ int List::bsearch(int x) {//Kiem tra xem danh sach da sap xep chua if(!sorted()) {cout<<"Danh sach chua sap xep";return false;} int bottom,mid,top; bottom=0,top=count-1; while(bottom<=top) {mid=(bottom+top)/2; if(a[mid]==x) {current=mid;return true;}; if(x<a[mid]) top=mid-1; else bottom=mid+1; } return false; }; //--------------------------//Chen gia tri x vao danh sach da duoc sap xep. void List::insert(int x) {int i,j; if(full() && !grow()) {cout<<"Danh sach bi day";return;} //Kiem tra xem danh sach da sap xep chua if(!sorted()) {cout<<"Danh sach chua sap xep";return;} for(i=0;x>a[i] && i<count;i++); for(j=count;j>i;j--) {a[j]=a[j-1];} //Dich cac thanh phan tu i len mot vi tri a[i]=x;count++; } PhÇn cµi ®Æt b¶ng b¨m: ƒ Khai b¸o b¶ng b¨m Chóng ta dïng m¶ng ®éng H ®Ó cµi ®Æt b¶ng b¨m. Mçi phÇn tö cña m¶ng lµ mét ®èi t−îng danh s¸ch. BiÕn max lµ cì cña b¶ng b¨m, c¬ së cña phÐp chia d−. Nh− vËy mét khãa x bÊt kú sÏ ®−îc chÌn vµo phÇn tö thø i = x%max cña b¶ng b¨m, tøc lµ chÌn vµo danh s¸ch kÒ thø i. Con trá pcurrent lµ ®Þa chØ cña nót hiÖn thêi, lµ ®Þa chØ quy −íc dïng trong c¸c t¸c vô t×m kiÕm. C¸c thao t¸c trªn b¶ng b¨m kh¸ ®¬n gi¶n, v× chñ yÕu c¸c thao t¸c nµy gäi ®Õn c¸c t¸c vô trªn danh s¸ch. #include "listke_h.cpp" class HashTab {private: List* H; //the list itself: a dynamic array of type List; http://www.ebook.edu.vn 40 CÊu tróc d÷ liÖu 2 – Ch−¬ng 2. B¶ng b¨m int max; //size of Hash table int* pcurrent; //current a of the hash table int count; public: HashTab(int); ~HashTab(); void display(); int empty(); int search(int x); void insert(int x); void InsertMany(); void traverse(); }; ƒ Khëi t¹o b¶ng b¨m T¸c vô khëi t¹o b¶ng b¨m cã tham sè m, ®−îc ®Æt ngÇm ®Þnh lµ 10, lµ cì cña b¶ng b¨m. Nh− vËy khi khai b¸o mét biÕn cã kiÓu b¶ng b¨m mµ ta kh«ng chØ râ cì th× cì cña b¶ng sÏ ®−îc lÊy lµ 10. Trong t¸c vô nµy mét m¶ng ®éng gåm max danh s¸ch ®−îc cÊp ph¸t bé nhí. Tuy nhiªn lóc ®Çu c¸c danh s¸ch cßn rçng, nªn thùc ra max danh s¸ch còng chØ lµ max con trá. void HashTab::HashTab(int m = 10) {max=m; H = new List [max];pcurrent=NULL;; return; } ƒ Hñy khëi t¹o b¶ng b¨m Khi kÕt thóc sö dông b¶ng b¨m, ta gi¶i phãng vïng bé nhí ®· cÊp cho b¶ng b¨m. LÇn l−ît ®i tõ ®Çu b¶ng ®Õn cuèi b¶ng, ta gäi t¸c vô clear cña danh s¸ch ®Ó gi¶i phãng vïng bé nhí t−¬ng øng. void HashTab::~HashTab() {for(int i=0;i<max;i++) H[i].clear(); delete [] H; return; } ƒ T×m kiÕm nhÞ ph©n trªn b¶ng b¨m §Ó t×m kiÕm mét khãa x trªn b¶ng b¨m, ®Çu tiªn ta x¸c ®Þnh danh s¸ch mµ trªn ®ã cã thÓ cã x. Danh s¸ch cÇn x¸c ®Þnh chÝnh lµ danh s¸ch thø i = x%max trªn b¶ng b¨m. Ta dïng t¸c vô t×m kiÕm nhÞ ph©n bsearch cña danh s¸ch nµy ®Ó t×m kiÕm khãa x. NÕu t×m thÊy th× t¸c vô tr¶ vÒ gi¸ trÞ true, con trá pcurrent chØ ®Þa chØ cña phÇn tö t×m thÊy trªn danh s¸ch; nÕu kh«ng t×m thÊy th× t¸c vô tr¶ vÒ gi¸ trÞ false. int HashTab::search(int x) {int i=x%max; if(H[i].bsearch(x)) {pcurrent=&H[i].a[H[i].current]; return true; } return false; http://www.ebook.edu.vn 41 CÊu tróc d÷ liÖu 2 – Ch−¬ng 2. B¶ng b¨m } ƒ ChÌn phÇn tö x vµo b¶ng b¨m §Ó chÌn mét phÇn tö vµo b¶ng b¨m, tr−íc hÕt ta tÝnh i = x%max, sau ®ã phÇn tö x ®−îc chÌn vµo danh s¸ch thø i theo gi¶i thuËt insert cña danh s¸ch nµy. void HashTab::insert(int x) {int i=x%max; H[i].insert(x); pcurrent=&H[i].current; } ƒ DuyÖt b¶ng b¨m Theo c¸ch chÌn c¸c phÇn tö míi vµo b¶ng b¨m trªn ®©y ta cã ®−îc c¸c danh s¸ch ®· ®−îc s¾p thø tù. §Ó cã thÓ duyÖt c¸c phÇn tö b¶ng b¨m theo thø tù t¨ng dÇn ta ¸p dông ph−¬ng ph¸p s¾p xÕp trén (mergesort) nh− sau: Tr−íc hÕt ta t¹o ra mét m¶ng c¸c sè nguyªn p[i], khëi ®Çu ta ®Æt tÊt c¶ c¸c gi¸ trÞ cña p[i] b»ng 0. B−íc tiÕp theo ta b¾t ®Çu so s¸nh c¸c gi¸ trÞ H[i].a[p[i]], i = 0,1,2,..., max-1, tøc lµ nh÷ng phÇn tö ®øng ®Çu c¸c phÇn tö ch−a ®−îc xÐt trong tõng danh s¸ch (lµ nh÷ng phÇn tö nhá nhÊt trong c¸c phÇn tö ch−a ®−îc xÐt trong tõng danh s¸ch), chän phÇn tö nhá nhÊt trong c¸c phÇn tö ®ã vµ cho hiÖn trªn mµn h×nh. NÕu trong b−íc võa råi ta ®· chän p[i] th× ta t¨ng p[i] lªn 1. ChØ cã nh÷ng danh s¸ch cã sè phÇn tö ®· xÐt nhá h¬n tæng sè c¸c phÇn tö cña nã míi ®−îc xÐt ®Õn, thÝ dô nÕu ®èi víi danh s¸ch i mµ p[i]>h[i].count-1 th× kh«ng xÐt d·y i n÷a. ViÖc chän phÇn tö nhá nhÊt b¾t ®Çu b»ng viÖc chän mét danh s¸ch ®Çu tiªn ®ang cßn phÇn tö, vµ phÇn tö ®Çu tiªn cña danh s¸ch ®ã ®−îc chän lµ gi¸ trÞ nhá nhÊt t¹m thêi. Sau ®ã ta duyÖt tÊt c¶ danh s¸ch cßn phÇn tö sau ®ã vµ thay thÕ b»ng phÇn tö nhá h¬n nÕu cã. //Duyet bang bam theo thu tu tang dan void HashTab::traverse() {int i,j,k,r,*p,*ConPhanTu;int t; p=new int[max]; ConPhanTu = new int[max]; k=0; for(i=0;i<max;i++) p[i]=0;//p[i] la so phan tu da doc o ds i for(i=0;i<max;i++) if(H[i].count==0) ConPhanTu[i]=0;else ConPhanTu[i]=1; cout<<endl<<endl; while(k<count) {r=0; while(!ConPhanTu[r]) r++; if(r==max) break;//Da duyet het bang bam t=H[r].a[p[r]];j=r; for(i=r+1;i<max;i++) if(p[i]<H[i].count && H[i].a[p[i]]<t) {t=H[i].a[p[i]];j=i;} cout<<H[j].a[p[j]]<<" ";p[j]++;k++; if(p[j]>=H[j].count) ConPhanTu[j]=0; } } http://www.ebook.edu.vn 42 CÊu tróc d÷ liÖu 2 – Ch−¬ng 2. B¶ng b¨m 2.3.3. Cµi ®Æt b¶ng b¨m dïng liªn kÕt trong ƒ Khai b¸o b¶ng b¨m liªn kÕt trong Chóng ta sÏ dïng mét m¶ng ®éng ®Ó cµi ®Æt b¶ng b¨m. Cì cña m¶ng ®−îc ®Æt ngÇm ®Þnh lµ 10, vµ cã thÓ thay ®æi khi khai b¸o mét biÕn cã kiÓu b¶ng b¨m. Mçi phÇn tö cña m¶ng lµ mét nót th«ng tin cã cÊu tróc: struct node {int* pkey; int next; }; trong ®ã pkey lµ con trá chØ ®Õn biÕn nguyªn mang th«ng tin trong bé nhí; next lµ tr−êng cã kiÓu nguyªn chØ ®Õn « tiÕp theo trong tr−êng hîp cã ®ông ®é. BiÕn max lµ cì cña b¶ng b¨m, lµ c¬ së cho phÐp chia d− khi cÇn thªm khãa vµo b¶ng. BiÕn count chØ sè phÇn tö chøa th«ng tin trong b¶ng b¨m, biÕn current chØ vÞ trÝ nót hiÖn thêi. B¶ng b¨m cã mét sè t¸c vô mµ chóng t«i sÏ gi¶i thÝch râ h¬n tõng tr−êng hîp. struct node {int* pkey; int next; }; class Hash {public: node* H; int max; int count; int current; Hash(int); ~Hash(); int empty(); int full(); void display(); void traverse(); int search(int); void insert(int); }; ƒ Khëi t¹o b¶ng b¨m Ban ®Çu tÊt c¶ c¸c « cã tr−êng pkey chØ ®Õn NULL ®Ó chøng tá r»ng b¶ng cßn rçng. Tr−êng next = -1 cã nghÜa lµ « kh«ng cã phÇn tö kÕ tiÕp. Hash::Hash(int size=10) {max=size; H = new node[max]; for(int i=0;i<max;i++) {H[i].pkey=NULL;H[i].next=-1; } count=0; }; http://www.ebook.edu.vn 43 CÊu tróc d÷ liÖu 2 – Ch−¬ng 2. B¶ng b¨m ƒ Hñy khëi t¹o Khi kÕt thóc viÖc sö dông mét biÕn cã kiÓu b¶ng b¨m ta lÇn l−ît gi¶i phãng phÇn bé nhí ®· cÊp cho c¸c « cña b¶ng. Hash::~Hash() {for(int i=0;i<max;i++) delete H[i].pkey; }; ƒ ChÌn phÇn tö vµo b¶ng b¨m Khi cÇn thªm mét phÇn tö x vµo b¶ng b¨m, tr−íc hÕt ta kiÓm tra xem b¶ng b¨m cã ®Çy kh«ng, nÕu ®Çy th× kh«ng thªm nót ®−îc vµ kÕt thóc. NÕu b¶ng kh«ng ®Çy th× ta lÊy k = x%max. NÕu « thø k cßn trèng, tøc lµ tr−êng pkey chØ ®Õn NULL, th× ta cÊp ph¸t bé nhí cho biÕn nµy, g¸n *H[k].pkey = x vµ kÕt thóc; Cßn nÕu « nµy ®· bÞ chiÕm chç th× ta xem néi dung trong « nµy cã cïng hä víi x kh«ng, nghÜa lµ *H[k].pkey%max cã b»ng x%max kh«ng. Ta ph©n biÖt 2 tr−êng hîp nh− sau: a. NÕu « k cïng hä víi x cã th× ta ®Æt i = k lÇn theo ®−êng ®i i = H[i]. next , cho ®Õn khi gÆp H[i].next = -1. TiÕp ®Õn ta b¾t ®Çu xuÊt ph¸t tõ ®¸y cña b¶ng, tøc lµ vÞ trÝ max-1 ®i dÇn lªn phÝa trªn ®Ó t×m mét « j ®Çu tiªn cßn trèng. Ta cÊp ph¸t bé nhí cho tr−êng pkey cña « nµy, g¸n *H[j].pkey = x, H[j].next = -1. Trë l¹i « thø i nãi trªn, ta g¸n H[i].next = j vµ kÕt thóc. b. NÕu « k kh«ng cïng hä víi x th× ta xuÊt ph¸t tõ vÞ trÝ max-1 lÇn ng−îc vÒ phÝa ®Çu b¶ng t×m vÞ trÝ ®Çu tiªn cßn trèng. NÕu vÞ trÝ nµy lµ j th× ta cÊp ph¸t bé nhí cho tr−êng pkey cña « nµy, g¸n *H[j].pkey = x, H[j].next = -1 vµ kÕt thóc. void Hash::insert(int x) {if(full()) {cout<<endl<<"Bang bam day, khong chen duoc";return;} if(search(x)) {cout<<endl<<"Nut da co, khong chen duoc";return;} int k,i,j; k=x%max; if( H[k].pkey==NULL) { H[k].pkey=new int;* H[k].pkey=x;count++; return;} if(* H[k].pkey%max==k) //Cung lop co phan du la d {i=k; while( H[i].next!=-1) i= H[i].next; for(j=max-1; H[j].pkey!=NULL;j--); H[i].next=j; H[j].pkey=new int; * H[j].pkey=x; H[j].next=-1; count++; return; } //Truong hop x khong cung so du voi i, ta tim mot vi tri trong de chen for(j=max-1;j>0 && H[j].pkey!=NULL;j--); H[j].pkey=new int; * H[j].pkey=x; H[j].next=-1; http://www.ebook.edu.vn 44 CÊu tróc d÷ liÖu 2 – Ch−¬ng 2. B¶ng b¨m count++; return; } ƒ T×m th«ng tin x trªn b¶ng b¨m Khi cÇn t×m kiÕm « cã néi dung x trªn b¶ng b¨m, tr−íc hÕt ta ®Æt k = x%max. NÕu *H[k].pkey = x th× t¸c vô tr¶ vÒ gi¸ trÞ true, ®Æt current = k vµ kÕt thóc; Cßn nÕu kh«ng nh− vËy th× ta xem néi dung trong « nµy cã cïng hä víi x kh«ng, nghÜa lµ *H[k].pkey%max cã b»ng x%max kh«ng. NÕu cã th× ta ®Æt k = i vµ lÇn theo ®−êng ®i i = H[i]. next , cho ®Õn khi gÆp *H[i].next = x th× t¸c vô tr¶ vÒ gi¸ trÞ true, ®Æt current = i vµ kÕt thóc ; hoÆc kh«ng t×m thÊy th× ta dõng l¹i khi H[i].next = -1, t¸c vô tr¶ vÒ gi¸ trÞ false. NÕu « thø k kh«ng cïng hä víi x th× ta b¾t ®Çu xuÊt ph¸t tõ ®¸y cña b¶ng, tøc lµ vÞ trÝ max-1 ®i dÇn lªn phÝa trªn ®Ó t×m cho ®Õn « ®Çu tiªn cßn trèng. NÕu gÆp « j mµ *H[j].pkey = x th× ta ®Æt current = j vµ t¸c vô tr¶ vÒ gi¸ trÞ true, nÕu kh«ng th× tr¶ vÒ gi¸ trÞ false. int Hash::search(int x) {int k,i,j; k=x%max; if(* H[k].pkey%max==k) //Cung lop co phan du la d {i=k; while( H[i].pkey!=NULL) {if(* H[i].pkey==x) {current=i;return true;} if( H[i].next==-1) break; else i= H[i].next; } return false; } for(j=max-1; H[j].pkey!=NULL;j--) if(* H[j].pkey==x) {current=j;return true;} return false; }; Thao t¸c xãa nót trong tr−êng hîp nµy kh¸ phøc t¹p. Chóng t«i xin dµnh l¹i vÊn ®Ò nµy nh− mét bµi tËp cho c¸c b¹n sinh viªn häc lùc kh¸ trë lªn. 2.3.4. Vµi nhËn xÐt vÒ b¶ng b¨m Môc ®Ých cña cÊu tróc d÷ liÖu b¶ng b¨m lµ muèn cã thêi gian truy xuÊt tøc thêi. §iÒu nµy cã thÓ thùc hiÖn ®−îc nÕu c¬ së d÷ liÖu cña ta cã sè phÇn tö kh«ng lín h¬n kÝch th−íc b¶ng nhiÒu qu¸, vµ c¸c khãa ®−îc ph©n bè kh¸ ®Òu trªn b¶ng. RÊt khã ®−a ra mét ®¸nh gi¸ chung vÒ ®é phøc t¹p tÝnh to¸n cña c¸c phÐp to¸n trªn b¶ng b¨m, mµ ta chØ cã thÓ tÝnh to¸n ®−îc trong nh÷ng tr−êng hîp cô thÓ. http://www.ebook.edu.vn 45 Ch−¬ng 3 C©y ®á ®en 3.1. Më ®Çu Trong ch−¬ng tr−íc chóng ta ®· nghiªn cøu cÊu tróc b¶ng b¨m. Khi d÷ liÖu kh«ng lín qu¸ so víi kÝch th−íc b¶ng b¨m th× hiÖn t−îng ®ông ®é Ýt x¶y ra vµ sù truy xuÊt vµo c¸c phÇn tö cña b¶ng gÇn nh− tøc thêi. Tuy nhiªn nÕu d÷ liÖu qu¸ lín so víi kÝch th−íc cña b¶ng th× hiÖn t−îng ®ông ®é x¶y ra th−êng xuyªn vµ mçi lÇn nh− vËy ta l¹i ph¶i thùc hiÖn t×m kiÕm hoÆc chÌn phÇn tö trªn danh s¸ch tuyÕn tÝnh. Chóng ta cã thÓ cµi ®Æt danh s¸ch tuyÕn tÝnh trong bé nhí b»ng hai c¸ch th«ng dông: dïng m¶ng ®éng hoÆc dïng danh s¸ch liªn kÕt. C¶ hai c¸ch cµi ®Æt kÒ hay liªn kÕt ®Òu béc lé nh÷ng nh−îc ®iÓm khã kh¾c phôc. Cµi ®Æt theo kiÓu liªn kÕt tuy ®¬n gi¶n trong c¸c thao t¸c chÌn xãa nh−ng l¹i kh«ng thùc hiÖn ®−îc ph−¬ng ph¸p t×m kiÕm nhÞ ph©n. Cµi ®Æt b»ng m¶ng tuy thùc hiÖn ®−îc thao t¸c t×m kiÕm nhÞ ph©n nh−ng mÊt nhiÒu thêi gian cho thao t¸c chÌn. §©y lµ 2 thao t¸c rÊt khã dung hßa. NÕu danh s¸ch kh«ng cÇn s¾p thø tù th× viÖc chÌn phÇn tö míi ®¬n gi¶n, nh−ng viÖc t×m kiÕm mÊt nhiÒu thêi gian v× trong tr−êng hîp xÊu nhÊt ph¶i ®i qua toµn bé danh s¸ch. Ng−îc l¹i nÕu danh s¸ch cã s¾p thø tù th× viÖc t×m kiÕm thùc hiÖn nhanh, nh−ng viÖc chÌn vµo rÊt mÊt c«ng, v× ph¶i duyÖt danh s¸ch ®Ó t×m vÞ trÝ chÌn. Trong thùc tÕ nÕu chóng ta gÆp nh÷ng bµi to¸n mµ thao t¸c chÌn vµo Ýt dïng ®Õn thÝ dô qu¶n lý nh©n sù mét c¬ quan mµ sè c¸n bé gÇn nh− æn ®Þnh th× cµi ®Æt danh s¸ch cã thø tù lµ thÝch hîp. §èi víi ®a sè c¸c bµi to¸n qu¶n lý kh¸c thÝ dô qu¶n lý c«ng v¨n ®Õn c«ng v¨n ®i, qu¶n lý viÖc xuÊt nhËp vËt t−,... th× thao t¸c chÌn vµ t×m kiÕm gÇn nh− ®−îc thùc hiÖn th−êng xuyªn, khã cã thÓ nãi thao t¸c nµo dïng nhiÒu h¬n. CÊu tróc lý t−ëng trong t×nh huèng nµy lµ ®¹t tèc ®é t×m kiÕm trªn danh s¸ch kÒ ®−îc s¾p xÕp vµ tèc ®é chÌn cña danh s¸ch liªn kÕt. Chóng ta h·y xem l¹i qu¸ tr×nh t×m kiÕm nhÞ ph©n trªn danh s¸ch cã thø tù. T¹i mçi b−íc t×m kiÕm chóng ta tr¶ lêi c©u hái "Nöa nµo cña danh s¸ch vÉn cßn chøa phÇn tö cÇn t×m?", vµ ta lo¹i bá nöa kh«ng chøa phÇn tö ®ã. Chóng ta muèn t¹o ra mét cÊu tróc d÷ liÖu sao cho khi chÌn thªm d÷ liÖu míi chóng ta nªu c©u hái "phÇn tö míi nªn chÌn vµo phÇn nµo cña cÊu tróc?" DÜ nhiªn lµ cÊu tróc nµy kh«ng thÓ lµ danh s¸ch v× kh¸c víi thao t¸c t×m kiÕm, thao t¸c chÌn kh«ng thÓ thùc hiÖn ®éc lËp trªn tõng phÇn sè liÖu. Khi chÌn sè liÖu vµo nöa d−íi ta vÉn ph¶i dÞch chuyÓn toµn bé nöa phÝa trªn. CÊu tróc c©y cã thÓ tiÕp cËn ý t−ëng nµy. C©y lµ cÊu tróc d÷ liÖu cã kh¶ n¨ng t×m kiÕm trªn tõng phÇn, do c¸ch tæ chøc cña c¸c nót sè liÖu. Chóng ta ®· cã dÞp nghiªn cøu cÊu tróc nµy. B©y giê chóng t«i xin nh¾c l¹i mét vµi kh¸i niÖm quan träng. §Þnh nghÜa c©y. C©y lµ cÊu tróc d÷ liÖu gåm c¸c nót th«ng tin ®−îc tæ chøc theo c¸ch: - HoÆc lµ c©y rçng, kh«ng chøa nót nµo. - HoÆc gåm mét nót gèc vµ c¸c nót con, trong ®ã c¸c nót con còng lµ c¸c c©y. NÕu mét nót A cã c©y con lµ B th× ta gäi A lµ nót cha cña nót B. NÕu nót B cã con lµ C th× ta gäi A lµ nót «ng cña nót C. Nót kh«ng cã con nµo ®−îc gäi lµ nót l¸. Nót kh«ng ph¶i lµ l¸ th× ®−îc gäi lµ nót trong. Nót cã cha vµ con kh¸c rçng ®−îc gäi lµ nót trung gian. BËc cña mét nót lµ sè c©y con cña nót ®ã. BËc cña mét c©y lµ bËc tèi ®a cña c¸c nót trong c©y. VÝ dô c©y nhÞ ph©n lµ c©y mµ bËc tèi ®a trong c©y kh«ng qu¸ 2. Møc cña nót (level of node): møc cña nót ®−îc ®Þnh nghÜa ®Ö quy nh− sau: + Nót gèc cã møc lµ 0 + Møc cña cha lµ i th× møc cña nót con lµ: i + 1. Møc cao nhÊt cña nót trong c©y lµ chiÒu cao cña c©y. MÆc dï nãi chung c¸c khãa trªn c©y cã thÓ lÆp l¹i, nh−ng ®Ó ®¬n gi¶n trong thao t¸c, chóng ta gi¶ sö r»ng c¸c khãa trªn c©y cã gi¸ trÞ kh¸c nhau. http://www.ebook.edu.vn CÊu tróc d÷ liÖu2 – Ch−¬ng 3. C©y ®á ®en 3.2. C©y nhÞ ph©n t×m kiÕm §Ó cã thÓ thùc hiÖn c¸c thao t¸c t×m kiÕm vµ chÌn theo ph−¬ng ph¸p nhÞ ph©n trªn c©y nh− ý t−ëng thiÕt kÕ chóng ta nªu ra trªn ®©y, chóng ta ph¶i tæ chøc c©y nhÞ ph©n theo mét c¸ch ®Æc biÖt, sao cho khi thùc hiÖn t×m kiÕm hoÆc chÌn ta lu«n cã thÓ quyÕt ®Þnh lµ hµnh ®éng tiÕp theo sÏ thùc hiÖn ë c©y con tr¸i hay c©y con ph¶i. ThÝ dô chóng ta sÏ tæ chøc c¸c nót sao cho t¹i mçi nót bÊt kú c¸c nót ë phÝa tr¸i bao giê còng kh«ng lín h¬n nót ®ã vµ tÊt c¶ c¸c nót phÝa ph¶i ®Òu kh«ng bÐ h¬n nót ®ã. C©y nhÞ ph©n tháa m·n tÝnh chÊt nµy ®−îc gäi lµ c©y nhÞ ph©n t×m kiÕm. §iÒu nµy còng cho ta c¸ch chÌn mét phÇn tö míi: b¾t ®Çu tõ gèc, ta sÏ lÇn t×m vÞ trÝ thÝch hîp ®Ó chÌn phÇn tö ®ã. Chóng ta cã thÓ thÊy râ lµ hai c©y nhÞ ph©n chøa cïng d÷ liÖu cã thÓ ®−îc tæ chøc hoµn toµn kh¸c nhau. Trong h×nh 3.1 nÕu chóng ta chÌn c¸c phÇn tö theo thø tù ®· s¾p s½n A,B,C,D,E ta sÏ ®−îc mét c©y nhÞ ph©n suy biÕn thµnh danh s¸ch. A B C D E H×nh 3.1. C©y nhÞ ph©n suy biÕn Trong tr−êng hîp nµy mÆc dï danh s¸ch cã s¾p thø tù nh−ng viÖc t×m kiÕm hoÆc chÌn ®Òu cÇn thêi gian cã bËc tuyÕn tÝnh. C©y ®−îc tæ chøc kÐm nh− vËy ®−îc gäi lµ kh«ng c©n b»ng (unbalanced). §iÒu kiÖn hiÓn nhiªn ®Ó c©y nhÞ ph©n ®−îc c©n b»ng hoµn h¶o lµ c©y cã sè nót tèi ®a t¹i mçi møc. ThÝ dô c©y trong h×nh 3.3 lµ c©y nhÞ ph©n hoµn h¶o (cßn gäi lµ c©y nhÞ ph©n ®Çy ®ñ - complete binary tree): A B D C E F G H×nh 3.2. C©y nhÞ ph©n ®Çy ®ñ C©y nhÞ ph©n ®Çy ®ñ lu«n lu«n cã sè nót lµ 2d+1 -1, trong ®ã d lµ sè møc cña c©y. VËy ®Ó t¹o cÊu tróc c©y nhÞ ph©n ®Çy ®ñ th× tr−íc hÕt d÷ liÖu ta kh¶o s¸t ph¶i cã ®óng 2d+1 -1 phÇn tö, trong ®ã d lµ sè tù nhiªn. Râ rµng ®iÒu kiÖn nh− vËy lµ qu¸ chÆt trong thùc tÕ. Tuy nhiªn chóng ta cã thÓ thÊy r»ng c©y kh«ng cÇn ph¶i c©n b»ng ®Õn møc hoµn h¶o nh− vËy; cã nh÷ng d¹ng c©n b»ng níi láng h¬n vÉn cho ta cÊu tróc d÷ liÖu h÷u Ých vµ gÇn víi thùc tÕ. Trong c¸c phÇn sau chóng ta sÏ ®Þnh nghÜa mét sè d¹ng ®Æc biÖt cña c©y. http://www.ebook.edu.vn 47 CÊu tróc d÷ liÖu2 – Ch−¬ng 3. C©y ®á ®en DuyÖt c©y nhÞ ph©n Còng gièng víi mét cÊu tróc d÷ liÖu bÊt kú, c¸c nót cña c©y nhÞ ph©n th−êng chøa c¸c th«ng tin vµ nhiÒu khi ta ph¶i liÖt kª tÊt c¶ c¸c th«ng tin ®ã theo mét c¸ch nµo ®ã sao cho th«ng tin mçi nót chØ ®−îc liÖt kª mét lÇn vµ kh«ng cã nót nµo bÞ bá sãt. §Ó lµm ®−îc viÖc nµy râ rµng ta ph¶i lÇn l−ît th¨m c¸c nót cña c©y theo mét thø tù nµo ®ã sao cho mçi nót chØ ®−îc th¨m ®óng mét lÇn. C¸ch lµm nµy gäi lµ phÐp duyÖt c©y. Cã nhiÒu c¸ch duyÖt c©y, thÝ dô ta cã thÓ th¨m c¸c nót theo tõng møc lÇn l−ît tõ tr¸i qua ph¶i. Tuy nhiªn nhiÒu khi phÐp duyÖt c©y kh«ng ®¬n thuÇn lµ liÖt kª th«ng tin c¸c nót mµ cßn nh»m mét môc ®Ých kh¸c. V× vËy 4 phÐp duyÖt c©y sau ®©y lµ ®−îc dïng nhiÒu nhÊt trong thùc tÕ: • Pretrav: duyÖt c©y theo thø tù tr−íc (NLR - Node Left Right) hay cßn ®−îc gäi lµ duyÖt c©y theo ®é s©u. §Çu tiªn chóng ta th¨m (visit) nót gèc. Sau ®ã duyÖt nh¸nh c©y con tr¸i theo phÐp duyÖt pretrav. Cuèi cïng duyÖt nh¸nh c©y con ph¶i theo phÐp duyÖt pretrav. • Intrav: duyÖt c©y theo thø tù gi÷a (LNR - Left Node Right) DuyÖt nh¸nh c©y con tr¸i theo phÐp duyÖt intrav. Th¨m (visit) nót gèc. Cuèi cïng duyÖt nh¸nh c©y con ph¶i theo phÐp duyÖt intrav. • Posttrav: duyÖt c©y theo thø tù sau (LRN - Left Right Node) DuyÖt nh¸nh c©y con tr¸i theo phÐp duyÖt posttrav. DuyÖt nh¸nh c©y con ph¶i theo phÐp duyÖt posttrav. Th¨m (visit) nót gèc. • Breadthtrav: duyÖt c©y theo bÒ réng tøc lµ duyÖt c©y theo møc DuyÖt c¸c nót tõ tr¸i qua ph¶i, b¾t ®Çu tõ møc 0, møc 1, 2, ... Sau ®©y lµ thø tù c¸c nót trong c¸c phÐp duyÖt c©y nhÞ ph©n ë h×nh 3.3. NLR: LNR: LRN: Breadth: ABDEC DBEAC DEBCA ABCDE A B D C E H×nh 3.3. Bèn phÐp duyÖt c©y nhÞ ph©n 3.3. C©y 2-3-4 §Ó khö tr−êng hîp xÊu nhÊt cho c©y nhÞ ph©n t×m kiÕm, ta cÇn cã mét vµi linh ®éng trong ®Þnh nghÜa cÊu tróc c©y míi. Cô thÓ ta cho phÐp mét nót trªn c©y cã thÓ chøa 1, 2 hoÆc 3 khãa; vµ nh− vËy mét nót cã thÓ cã tíi 4 con. Ta sÏ më réng kh¸i niÖm c©y nhÞ ph©n t×m kiÕm thµnh c©y 2-34 nh− sau: 3.3.1. §Þnh nghÜa c©y 2-3-4 C©y 2-3-4 lµ c©y nhiÒu nh¸nh bËc 4 tháa m·n c¸c tÝnh chÊt sau: • Mét nót bÊt kú trªn c©y ph¶i cã 1, 2 hoÆc 3 khãa (nh− vËy kh«ng cã nót l¸ rçng). Trõ nót l¸ http://www.ebook.edu.vn 48 CÊu tróc d÷ liÖu2 – Ch−¬ng 3. C©y ®á ®en • • kh«ng cã con nµo, cßn tÊt c¶ c¸c nót cßn l¹i ®Òu cã ®ñ con, nghÜa lµ nÕu nót cã k (1 ≤ k ≤ 3) khãa th× ph¶i cã k+1 con. TÊt c¶ c¸c l¸ ®Òu cïng n»m trªn mét møc. Ngoµi ra gi¸ trÞ c¸c khãa trªn c©y 2-3-4 cÇn tho¶ m·n c¸c ®iÒu kiÖn sau: C¸c khãa trªn mçi nót ®−îc s¾p xÕp theo thø tù t¨ng dÇn. T¹i mçi nót c¸c khãa trªn c©y con bªn tr¸i mét khãa kh«ng lín h¬n khãa ®ã vµ c¸c khãa trªn c©y con bªn ph¶i kh«ng bÐ h¬n khãa ®ã. H×nh 3.4 sau m« t¶ mét c©y 2-3-4: 50 70 20 40 30 5 10 2 4 7 15 25 45 35 42 47 49 55 65 52 60 63 75 68 72 85 78 95 H×nh 3.4 C©y 2-3-4. 3.3.2. T×m kiÕm trªn c©y 2-3-4 Gi¶ sö chóng ta cÇn t×m nót cã khãa x. Chóng ta xuÊt ph¸t tõ gèc cña c©y, vµ ®i theo nh¸nh c©y thÝch hîp. Gi¶ sö ta ®ang ë ®Ønh B. NÕu ®Ønh B lµ l¸ th× ta ph¶i t×m trong nót B xem cã khãa x hay kh«ng. NÕu B lµ ®Ønh trong chøa c¸c khãa k0, k1,..., kr r ∈ {0, 1, 2} th× ta cÇn x¸c ®Þnh vÞ trÝ cña x trong d·y khãa nµy. ThÝ dô nÕu x < k0 th× ta t×m x trªn c©y con n»m bªn tr¸i k0, nÕu ki-1< x < ki th× ta t×m x trªn c©y con n»m gi÷a ki-1 vµ ki, cßn nÕu kr < x th× ta t×m x trªn c©y con n»m bªn ph¶i kr. 3.3.3. Thªm khãa vµo c©y 2-3-4 Khi thªm mét khãa x vµo c©y th× chóng ta ph¶i ¸p dông thñ tôc t×m kiÕm ®Ó t×m ra nót B cÇn ph¶i xen vµo. NÕu khãa x ®· tån t¹i trªn c©y th× ta kh«ng thªm n÷a, v× c¸c khãa trªn c©y ph¶i duy nhÊt, kh«ng ®−îc lÆp l¹i. Ta cã thÓ thÊy r»ng thñ tôc thªm nót lu«n lu«n cã thÓ ®−îc thùc hiÖn ë nót l¸. ThËt vËy, v× nót x ch−a cã trªn c©y nªn xuÊt ph¸t tõ nót gèc ta sÏ ®i theo con ®−êng ®i qua c¸c nót trong ®Ó ®Õn mét nót l¸ nµo ®ã. T¹i mét nót trung gian ta lu«n cã hoÆc lµ x < k0 trong ®ã k0 lµ khãa nhá nhÊt trong ®Ønh ®ã, khi nµy ta ®i theo nh¸nh c©y con n»m bªn tr¸i khãa k0 . NÕu x > kr trong ®ã kr lµ khãa lín nhÊt trong nót ®ã, khi nµy ta ®i theo nh¸nh c©y con n»m bªn ph¶i khãa kr. NÕu ki-1< x < ki th× ta ®i theo c©y con n»m gi÷a ki-1 vµ ki. VËy thao t¸c thªm nót lu«n ®−îc thùc hiÖn ë mét nót l¸ nµo ®ã ®−îc x¸c ®Þnh bëi x. Gi¶ sö ta ®Õn nót l¸ B. Ta thùc hiÖn viÖc chÌn nót x nh− sau: • NÕu nót l¸ B ch−a ®Çy th× chóng ta chÌn khãa x vµo nót nµy theo thao t¸c chÌn nót vµo danh s¸ch s¾p thø tù. • NÕu nót B ®· ®Çy, tøc lµ cã 3 khãa, nÕu ta thªm khãa x th× nót B bÞ trµn. Gi¶ sö cïng víi x ta cã c¸c khãa míi trong nót B lµ k0’, k1’, k2’, k3’, Ta t¸ch nót B thµnh 2 nót, nót ®Çu cã c¸c khãa k0’, k1’ nót thø 2 B’ chøa 1 kho¸ lµ k3’ cßn khãa k2’ sÏ ®−îc chÌn vµo nót cha cña B cïng víi nót B’ lµ con bªn ph¶i. NÕu nót cha bÞ ®Çy ta l¹i thùc hiÖn t−¬ng http://www.ebook.edu.vn 49 CÊu tróc d÷ liÖu2 – Ch−¬ng 3. C©y ®á ®en tù nh− víi nót B. Nh− vËy viÖc t¸ch nót cã thÓ lan truyÒn tíi gèc vµ nót gèc cã thÓ bÞ t¸ch lµm 2 vµ gèc míi ®−îc t¹o ra. §©y chÝnh lµ c¸ch duy nhÊt ®Ó c©y 2-3-4 cã thÓ t¨ng chiÒu cao: nã lín lªn tõ l¸ ®Õn gèc. VÝ dô: XÐt c©y 2-3-4 sau ®©y: A 7 10 20 26 15 30 35 C B A 7 10 15 B 20 30 22 26 35 C D H×nh 3.5 Thªm khãa 22 vµo c©y 2-3-4 1. Gi¶ sö ta ph¶i thªm khãa 22 vµo c©y. Nót A kh«ng cã khãa 22 vµ ta tiÕp tôc t×m kiÕm trªn nót C. Nót C lµ nót l¸ cuèi cïng trªn ®−êng t×m kiÕm khãa 22, do vËy ta sÏ thùc hiÖn viÖc chÌn khãa 22 ë ®©y. 2. Tuy nhiªn nót C ®· ®Çy, do ®ã ta t¸ch nót C thµnh 2 nót vµ ta cã thªm nót míi lµ D. 3. Khãa 30 ®−îc chuyÓn lªn nót cha. §ång thêi ta ®Æt mèi liªn kÕt tõ nót cha xuèng nót D. 3.3.4. Lo¹i bá khãa trªn c©y 2-3-4 VÒ nguyªn t¾c, viÖc lo¹i bá nót trªn c©y hoµn toµn ®¬n gi¶n nh−ng phøc t¹p trong chi tiÕt thùc hiÖn. §Ó lo¹i bá mét khãa x, tr−íc hÕt ta t×m kiÕm trªn c©y ®Ó x¸c ®Þnh vÞ trÝ cña khãa x. ViÖc tiÕn hµnh lo¹i bá dÜ nhiªn chØ ®−îc thùc hiÖn khi thao t¸c t×m kiÕm cã kÕt qu¶. Cã 2 t×nh huèng sau: (1) PhÇn tö cÇn lo¹i bá ë nót l¸: viÖc lo¹i bá phÇn tö nµy ®−îc thùc hiÖn kh¸ dÔ dµng nh− lo¹i bá phÇn tö trªn danh s¸ch. (2) PhÇn tö cÇn lo¹i bá n»m ë nót trung gian. Lóc nµy ta kh«ng thÓ lo¹i bá trùc tiÕp phÇn tö trªn nót nµy, v× phÇn tö nµy cßn cã c¸c c©y con liªn quan. Ta ph¶i t×m mét phÇn tö kh¸c n»m ë nót l¸ lµm phÇn tö thay thÕ, nghÜa lµ gi¸ trÞ khãa cña phÇn tö thay thÕ sÏ ®−îc g¸n cho gi¸ trÞ khãa cña phÇn tö cÇn xãa, sau ®ã phÇn tö thay thÕ ®−îc lo¹i bá khái nót l¸ chøa nã. Ta thÊy phÇn tö thay thÕ ph¶i lµ phÇn tö cùc ph¶i cña nh¸nh c©y con tr¸i hoÆc nót cùc tr¸i cña nh¸nh c©y con ph¶i cña phÇn tö cÇn xãa. Chóng ta sÏ quy −íc chän phÇn tö cÇn thay thÕ lµ phÇn tö cùc ph¶i trªn nh¸nh c©y con tr¸i. VËy trong mäi tr−êng hîp ta ®Òu ®−a vÒ tr−êng hîp xãa khãa trªn nót l¸. Nh− vËy ta chØ cÇn nghiªn cøu tr−êng hîp nµy: Gi¶ sö nót l¸ cã khãa cÇn xãa lµ nót Z. Ta xÐt 2 tr−êng hîp sau: (a) Nót Z cã nhiÒu h¬n 1 khãa. Lóc nµy ta chØ cÇn xãa khãa x trªn Z vµ kÕt thóc. (b) NÕu Z chØ cã mét khãa x. Gi¶ sö nót cha lµ F vµ nót Z cã nót l¸ng giÒng (cïng møc) bªn tr¸i lµ L. Gi¶ sö khãa f trong nót F lµ khãa cha cña nót L vµ Z. Lóc nµy sau khi xãa x nót Z thµnh rçng vµ do ®ã khãa f kh«ng cã con ph¶i. Ta ®−a khãa f xuèng nót L. ë ®©y ta l¹i gÆp 2 t×nh huèng: http://www.ebook.edu.vn 50 CÊu tróc d÷ liÖu2 – Ch−¬ng 3. C©y ®á ®en - NÕu nót L ch−a ®Çy th× ta ph¶i c©n b»ng l¹i nót F, qu¸ tr×nh c©n b»ng cã thÓ lan truyÒn ®Õn gèc vµ cã thÓ nót gèc bÞ lo¹i bá: c©y ®· thÊp xuèng. §©y chÝnh lµ c¸ch duy nhÊt ®Ó c©y 2-3-4 gi¶m chiÒu cao. - NÕu nót L ®Çy th× sÏ ®−îc t¸ch lµm hai vµ cã mét nót ®−îc chÌn vµo nót F thay thÕ khãa f. Thùc chÊt khãa nµy chÝnh lµ khãa cùc ph¶i cña L khi ch−a ®−a nót cha xuèng, cßn khãa f sÏ lµ khãa cña nót ®−îc t¸ch ra. VÝ dô: Ta xÐt c©y sau ®©y: A 32 B C 38 44 20 26 7 10 15 22 24 D E 30 F 34 36 40 42 I J 46 48 K H×nh 3.6. Xãa khãa 32 trªn c©y 2-3-4 Gi¶ sö ta cÇn xãa khãa 32. Nót chøa khãa 32 kh«ng ph¶i nót l¸, v× vËy ta ph¶i t×m mét khãa thay thÕ. Theo quy −íc, nót cùc ph¶i trªn c©y con tr¸i cña khãa 32 lµ khãa 30. Ta ®−a gi¸ trÞ khãa 30 vÒ vÞ trÝ cña khãa 32 råi xãa khãa 30 trªn nót l¸ chøa nã vµ nhËn ®−îc c©y míi nh− sau: A 30 B C 38 44 20 26 7 10 15 22 24 D E F 34 36 40 42 I J 46 48 K H×nh 3.7. C©y sau khi xãa khãa 32 Ta nhËn thÊy nót F ë trong t×nh tr¹ng c¹n kiÖt. Ta sÏ xãa nót F, ®ång thêi chuyÓn khãa 26 xuèng nót E. Ta ®−îc kÕt qu¶ sau A 30 B C 38 44 20 7 10 D 15 22 24 E 26 F 34 36 40 42 I J 46 48 K H×nh 3.8. C©n b»ng l¹i nót F http://www.ebook.edu.vn 51 CÊu tróc d÷ liÖu2 – Ch−¬ng 3. C©y ®á ®en B©y giê c©y ®· c©n b»ng. 3.3.5. Ph©n tÝch c¸c thuËt to¸n trªn c©y 2-3-4 Còng nh− c©y nhÞ ph©n t×m kiÕm, khi chÌn mét khãa x vµo c©y hay t×m kiÕm mét khãa x trong c©y, ta xuÊt ph¸t tõ gèc vµ lu«n ®i theo ®−êng cha - con (tøc lµ kh«ng cã tr−êng hîp nµo ta duyÖt nhiÒu h¬n mét c©y con cña mét nót nµo ®ã). NÕu lµ thao t¸c chÌn th× ta lu«n lu«n dõng ë mét nót l¸. Trong tr−êng hîp nµy nÕu ®é cao cña c©y lµ h th× ta ph¶i duyÖt qua h+1 nót (v× nót gèc ®−îc quy −íc lµ cã ®é cao 0). Bµi to¸n ®Æt ra lµ: gi¶ sö c©y cã n khãa, khi ®ã ta ph¶i duyÖt qua bao nhiªu nót trong tr−êng hîp xÊu nhÊt? Bµi to¸n nµy còng t−¬ng ®−¬ng víi bµi to¸n sau: cho n khãa, h·y x¸c ®Þnh chiÒu cao lín nhÊt cña cña c©y 2-3-4 t¹o tõ n khãa nµy. Ta thÊy r»ng c©y cao nhÊt lµ c©y cã sè khãa tèi thiÓu trong mçi nót. XÐt tr−êng hîp n nhËn mét gi¸ trÞ thÝch hîp, ta thÊy r»ng sè khãa tèi thiÓu trªn mçi nót lµ mét, do ®ã sè con cña mét nót lµ 2. Nh− vËy ta thÊy r»ng møc 0 cã 1 nót, møc 1 cã 2 = 21, ... møc i cã 2i nót. Vµ nh− vËy c©y cã chiÒu cao h sÏ cã 1+2 + 22 +... +2h = 2h+1 - 1 nót. Tuy nhiªn v× mçi nót chØ chøa mét khãa nªn tæng sè nót còng lµ tæng sè khãa. Nh− vËy ta cã hÖ thøc 2h+1 - 1. KÕt qu¶ nµy thùc ra cã thÓ suy ra dÔ dµng, v× c©y 2-3-4 mµ mçi nót chØ cã mét khãa chÝnh lµ c©y nhÞ ®Çy ®ñ hay lµ c©y nhÞ ph©n c©n b»ng hoµn toµn. Nh− vËy sè nót cÇn duyÖt nhiÒu nhÊt trong qu¸ tr×nh chÌn khãa lµ h+1 = log2(n+1). Ta h·y xÐt tr−êng hîp tèt nhÊt mµ c©y 2-3-4 cã thÓ ®¹t tíi: c©y cã chiÒu cao thÊp nhÊt trong c¸c c©y 2-3-4 cã n nót. Ta thÊy r»ng c©y thÊp nhÊt khi tÊt c¶ c¸c nót chøa tèi ®a sè khãa. Lóc nµy tæng sè nót trong c©y lµ: møc 0 cã 1, møc 1 cã 4, ..., møc i cã 4i nót. Nh− vËy c©y chiÒu cao h cã 1+ 4 + 42 + ... + 4h = 4 h +1 − 1 4 h +1 − 1 = nót 4 −1 3 4 h +1 − 1 * 3 = 4h+1 -1. Tõ ®©y ta cã h+1 = 3 log4(n+1). Tuy nhiªn cã thÓ thÊy r»ng trªn mçi nót ta ph¶i so s¸nh víi 3 khãa, nªn nÕu gäi k lµ sè phÐp so s¸nh trung b×nh cÇn thùc hiÖn trªn mçi nót, vµ gäi tæng sè phÐp so s¸nh lµ p, ta cã k*log4(n+1) ≤ p ≤ log2(n+1). Nãi chung ta lu«n lu«n cã: log4(n+1) ≤ p ≤ log2(n+1). Tõ ®©y ta cã thÓ kÕt luËn lµ phÐp chÌn vµ phÐp t×m kiÕm trªn c©y 2-3-4 chøa n khãa kh«ng bao giê duyÖt nhiÒu h¬n log2(n+1) nót. VËy c¸c phÐp to¸n nµy cã ®é phøc t¹p tÝnh to¸n lµ log2n. Cã thÓ thÊy r»ng viÖc cµi ®Æt c©y 2-3-4 víi c¸c thao t¸c t×m kiÕm hay chÌn, xãa kh«ng khã kh¨n l¾m. Tuy nhiªn nh−îc ®iÓm cña c©y nµy lµ tèn bé nhí. Cho dï c¸c nót trªn c©y cã thÓ chØ l−u tr÷ mét khãa th× ta lu«n ph¶i dµnh s½n vÞ trÝ cho 3 khãa vµ 4 con trá. ChÝnh v× lÏ nµy ng−êi ta ®· x©y dùng mét c©y t−¬ng ®−¬ng vÒ tèc ®é t×m kiÕm vµ chÌn, nh−ng l¹i tèn Ýt bé nhí h¬n, ®ã lµ c©y ®á ®ªn mµ chóng ta sÏ kh¶o s¸t trong môc sau. V× mçi nót chøa 3 khãa nªn tæng sè kho¸ lµ n = 3.4. C©y ®á ®en (Red-black tree) 3.4.1. §Þnh nghÜa Ta cã thÓ chuyÓn mét c©y 2-3-4 thµnh mét c©y nhÞ ph©n b»ng c¸ch biÕn ®æi nh− sau: - §èi víi nót cã 2 con th× gi÷ nguyªn. - Víi nót cã 3 con ta chuyÓn nh− sau: §en 1 2 §á 1 §en 2 HoÆ c http://www.ebook.edu.vn 1 §á 2 52 CÊu tróc d÷ liÖu2 – Ch−¬ng 3. C©y ®á ®en - Víi nót cã 4 con ta chuyÓn nh− sau: §en 1 2 3 §á 1 2 3 §á H×nh 3.9. ChuyÓn ®æi c©y 2-3-4 sang c©y ®á ®en Tõ ®Þnh nghÜa c©y 2-3-4 ta suy ra ®Þnh nghÜa c©y ®á ®en nh− sau: C©y ®á ®en lµ mét c©y nhÞ ph©n t×m kiÕm (BST = Binary Search Tree) tháa m·n c¸c ®iÒu kiÖn sau: - C¸c nót lµ ®á hoÆc ®en. - C¸c nót l¸ rçng ®−îc quy −íc lµ ®en. - Kh«ng cã 2 nót ®á kÒ nhau (nh− vËy nÕu nót cha lµ ®á th× c¸c nót con ph¶i lµ ®en. - Sè l−îng nót ®en trªn mäi ®−êng dÉn tõ gèc ®Õn l¸ ph¶i b»ng nhau. 3.4.2. Sù t−¬ng ®−¬ng gi÷a c©y ®á ®en vµ c©y 2-3-4 Nh− ta ®· thÊy, tõ mét c©y 2-3-4 ta cã thÓ x©y dùng c©y ®á ®en t−¬ng øng. Ng−îc l¹i tõ mét c©y ®á ®en ta còng cã thÓ t¹o ra c©y 2-3-4 t−¬ng ®−¬ng víi nã. C¸c thao t¸c t×m kiÕm, thªm nót, xãa nót trªn c©y 2-3-4 ®−îc thùc hiÖn kh¸ dÔ dµng vµ trùc quan. Ta cã thÓ chuyÓn c¸c thao t¸c nµy thµnh c¸c thao t¸c ®æi mµu mét nót vµ xoay c©y trªn c©y ®á ®en. C¸c thao t¸c nµy khã cµi ®Æt h¬n c¸c thao t¸c trªn c©y 2-3-4. V× c©y 2-3-4 lµ c©n b»ng, do ®ã ta còng suy ra r»ng c©y ®á ®en lµ c©n b»ng. H¬n n÷a ta cã thÓ tÝnh ®−îc giíi h¹n tèi ®a cña chiÒu cao c©y ®á ®en cã n nót nh− sau: V× sè nót ®en tõ gèc ®Õn nót l¸ bÊt kú ®Òu lu«n b»ng nhau, ngoµi ra kh«ng cã hai nót ®á kÒ nhau, do ®ã sè nót ®á trong ®−êng ®i tõ gèc nhiÒu nhÊt lµ b»ng sè nót ®en. Nh− vËy chóng ta cã thÓ thÊy r»ng ®−êng ®i dµi nhÊt tõ gèc ®Õn nót l¸ kh«ng thÓ gÊp qu¸ 2 lÇn so víi ®−êng ®i ng¾n nhÊt. Nh− vËy nÕu c©y cã n nót th× chiÒu cao tèi ®a cña c©y lµ 2log2(n+1). C©y ®á ®en t−¬ng ®−¬ng víi c©y 2-3-4. C©y 2-3-4 nh− ta sÏ thÊy, lµ mét tr−êng hîp riªng cña B-c©y, do ®ã chóng ta sÏ kh«ng nghiªn cøu c¸ch cµi ®Æt c©y ®á ®en tæng qu¸t. Chóng ta sÏ xem xÐt vµ cµi ®Æt mét tr−êng hîp ®Æc biÖt cña c©y ®á ®en lµ c©y c©n b»ng chiÒu cao. C©y nµy c©n b»ng h¬n c©y ®á ®en tæng qu¸t, vµ cã chiÒu cao c©y xÊp xØ lµ log2n. 3.5. C©y c©n b»ng chiÒu cao (Height balanced tree) Mét tr−êng hîp ®Æc biÖt cña c©y ®á ®en lµ c©y c©n b»ng chiÒu cao hay cßn gäi lµ c©y AVL do hai nhµ to¸n häc X« ViÕt lµ Adelson Velsky vµ Landis ph¸t minh ra vµo n¨m 1962. C©y AVL ®−îc xem lµ cÊu tróc d÷ liÖu næi tiÕng nhÊt vµ cæ ®iÓn nhÊt trong c¸c c©y c©n b»ng. ViÖc thªm nót hay xãa nót trªn c©y nhÞ ph©n AVL sÏ ®−îc thùc hiÖn nh− trªn c©y nhÞ ph©n t×m kiÕm. Tuy nhiªn sau mçi lÇn chÌn hoÆc xãa th× c©y cã thÓ mÊt c©n b»ng vµ ta ph¶i thùc hiÖn thao t¸c xoay c©y ®Ó c©n b»ng l¹i. C¸c thao t¸c t×m kiÕm, chÌn vµ xãa nót trªn c©y AVL chØ xÊp xØ O(log2n). Sau ®©y chóng ta t×m hiÓu c¸c thao t¸c c©n b»ng l¹i c©y. 3.5.1. Thao t¸c xoay c©y nhÞ ph©n Sau khi chÌn hoÆc xãa nót trªn c©y nhÞ ph©n AVL, cã thÓ c©y sÏ mÊt tr¹ng th¸i c©n b»ng. Trong tr−êng hîp nµy chóng ta ph¶i thùc hiÖn thao t¸c xoay tr¸i (rotateleft) hoÆc xoay ph¶i http://www.ebook.edu.vn 53 CÊu tróc d÷ liÖu2 – Ch−¬ng 3. C©y ®á ®en (rotateright) ®Ó c©n b»ng l¹i c©y. §Ó xoay tr¸i c©y nhÞ ph©n cã nót gèc lµ P , yªu cÇu lµ nót P ph¶i cã nót con bªn ph¶i Q. Sau khi xoay tr¸i nót P quanh nót con ph¶i Q cña nã, nót Q trë thµnh nót gèc míi cña c©y, nót P trë thµnh nót con bªn tr¸i cña nót Q (cßn nót con tr¸i cña Q sÏ thµnh nót con ph¶i cña P). P Q Xoay tr¸i quanh nót P a Q P b c a c b H×nh 3.10. Xoay tr¸i c©y nhÞ ph©n. Thao t¸c xoay ph¶i còng ®−îc thùc hiÖn t−¬ng tù khi thay nót con ph¶i b»ng nót con tr¸i. NhËn xÐt vÒ phÐp xoay c©y: Cã thÓ thÊy r»ng khi mét c©y bÞ lÖch ph¶i th× ta hy väng b»ng phÐp xoay tr¸i nót gèc quanh con ph¶i cña nã sÏ lµm cho c©y kh«ng cßn lÖch ph¶i n÷a. Tõ h×nh 3.10 ta cã thÓ thÊy r»ng phÐp xoay thùc sù ®¹t ®−îc hiÖu qu¶ nÕu c©y a vµ c©y b ®Òu ng¾n h¬n c©y c, nghÜa lµ P vµ Q cïng lÖch ph¶i. NÕu Q lÖch tr¸i chiÒu víi P th× th−êng ta ph¶i quay ph¶i Q råi sau ®ã míi quay tr¸i P. 3.5.2. ChØ sè c©n b»ng (balance factor) cña mét nót trªn c©y AVL §Ó cã thÓ x¸c ®Þnh vÞ trÝ ®Ó xoay l¹i c©y, t¹i mçi nót ta sÏ l−u tr÷ thªm th«ng tin vÒ tÝnh c©n b»ng cña c©y ®ã. T¹i mét nót P bÊt kú ta sÏ ký hiÖu lh(P) lµ chiÒu cao cña c©y con tr¸i, rh(P) lµ chiÒu cao cña c©y con ph¶i. Ta sÏ ®Þnh nghÜa bal(P) lµ chØ sè c©n b»ng t¹i nót ®ã theo c«ng thøc: bal(P)=rh(P)-lh(P) VËy bal(P) chØ cã thÓ nhËn mét trong 3 gi¸ trÞ 0,-1,+1, trong ®ã bal(P) = 0 nót P c©n b»ng bal(P) = -1 nót P lÖch tr¸i bal(P) = +1 nót P lÖch ph¶i 3.5.3. C©n b»ng l¹i c©y khi thªm nót Chóng ta cã thÓ thÊy r»ng cã nh÷ng vÞ trÝ khi thªm nót c©y vÉn c©n b»ng. Ng−êi ta rót ra ®−îc nh÷ng tr−êng hîp c©y bÞ mÊt c©n b»ng khi thªm nót nh− sau: Tr−êng hîp 1: VÞ trÝ thªm nót lµ phÝa sau bªn tr¸i cña nót bÞ lÖch tr¸i (bal(P)=-1) -1 0 0 0 P 0 U http://www.ebook.edu.vn 54 CÊu tróc d÷ liÖu2 – Ch−¬ng 3. C©y ®á ®en H×nh 3.11.a. Khi thªm nót U c©y con sÏ mÊt c©n b»ng. Tr−êng hîp 2: VÞ trÝ thªm nót lµ phÝa sau bªn ph¶i cña nót bÞ lÖch ph¶i (bal(P)=+1) P 1 0 0 0 0 U H×nh 3.11.b. Khi thªm nót U c©y con sÏ mÊt c©n b»ng. Thùc hiÖn phÐp xoay c©y ®Ó c©n b»ng l¹i c©y: Mét ®iÒu kh¸ lý thó xÈy ra khi thªm nót vµo c©y AVL, lµ mÆc dï viÖc thªm nót x vµo c©y cã thÓ g©y ra mét lo¹t vÞ trÝ mÊt c©n b»ng trªn ®−êng ®i tõ nót gèc ®Õn vÞ trÝ chÌn nót x, nh−ng ta l¹i chØ cÇn c©n b»ng nh¸nh c©y con cã gèc s ë vÞ trÝ cuèi cïng cã thÓ mÊt c©n b»ng trªn ®−êng ®i tõ gèc ®Õn x. Lý do lµ v× nh− ta sÏ thÊy, sau khi thªm nót x vµ thùc hiÖn thao t¸c c©n b»ng ta thÊy nh¸nh c©y con s cã chiÒu cao ®óng b»ng chiÒu cao cña nã tr−íc khi chÌn x. Do ®ã viÖc chÌn x kh«ng lµm ¶nh h−ëng ®Õn ®é cao cña c¸c c©y con trªn ®−êng tõ gèc ®Õn x. http://www.ebook.edu.vn 55 CÊu tróc d÷ liÖu2 – Ch−¬ng 3. C©y ®á ®en Ta gäi s lµ nót tr−íc gÇn nhÊt (cña nót x) bÞ mÊt c©n b»ng do thªm nót x. Cã 2 tr−êng hîp: - Tr−íc khi thªm nót x bal(s)=-1 vµ nót l¸ x thªm vµo lµ nót sau bªn tr¸i cña s. (Xem h×nh 3.12.a) s x -1 s1 0 C A B chiÒu cao n chiÒu cao n chiÒu cao n H×nh 3.12.a. Nh¸nh c©y con nót gèc s tr−íc khi thªm nót. - Tr−íc khi thªm nót x bal(s) = +1 vµ nót l¸ x thªm vµo lµ nót sau bªn ph¶i cña s. (Xem h×nh 3.12.b) s 1 x 0 A chiÒu cao n s1 B C chiÒu cao n chiÒu cao n H×nh 3.12.b. Nh¸nh c©y con gèc s tr−íc khi thªm nót. V× 2 tr−êng hîp trªn lµ t−¬ng tù nªn chóng ta chØ kh¶o s¸t tr−êng hîp 1, tøc lµ c©y s bÞ lÖch tr¸i. Chóng ta cã thÓ thÊy ba c©y A, B vµ C cã chiÒu cao nh− nhau vµ b»ng n. NÕu c©y rçng ta ®Æt n=-1. Gäi s1 lµ con tr¸i cña s, ta xÐt c¸c tr−êng hîp sau: Tr−êng hîp a: C©y gèc s1 lÖch tr¸i, tøc lµ lÖch cïng phÝa víi s. s s1 -2 s1 c -1 b n n s Xoay ph¶i nót s quanh nót s1 0 n a 0 a b c x x H×nh 3.13.a. Xoay tr¸i c©y s. http://www.ebook.edu.vn 56 CÊu tróc d÷ liÖu2 – Ch−¬ng 3. C©y ®á ®en Trong tr−êng hîp nµy ta chØ cÇn xoay ph¶i nót s quanh nót s1, ta ®−îc c©y gèc s1 ®· c©n b»ng. H¬n n÷a ta cã thÓ thÊy chiÒu cao cña c©y s1 lµ n+1, tøc lµ ®óng b»ng chiÒu cao cña c©y s tr−íc khi chÌn nót x. Tõ ®©y ta suy ra r»ng hÖ sè c©n b»ng cña c¸c nót tr−íc nót s ®Òu gi÷ nguyªn nh− tr−íc khi chÌn x. Tr−êng hîp b: C©y gèc s1 lÖch ph¶i, tøc lµ lÖch kh¸c phÝa víi s, nót x lµ nót sau bªn ph¶i cña nót s1. Lóc nµy ta ph¶i thùc hiÖn 2 phÐp quay, hay cßn gäi lµ thùc hiÖn phÐp quay kÐp. Tr−êng hîp b.1: s s1 s -2 -1 A chiÒu cao n -2 C 1 Xoay tr¸i nót s1 chiÒu cao n s2 s1 s2 C 0 B2 chiÒu cao n-1 B1 chiÒu cao n-1 A B2 chiÒu cao n-1 B1 chiÒu cao n-1 -2 chiÒu cao n chiÒu cao n x x 0 Xoay ph¶i nót s s1 0 B1 chiÒu cao n-1 A chiÒu cao n s2 1 B2 chiÒu cao n-1 s C chiÒu cao n x H×nh 3.13.b.1. Xoay kÐp c©y s. Tr−êng hîp b.2: s s -2 s1 1 s2 1 A chiÒu cao n -2 C B1 chiÒu cao n-1 Xoay tr¸i nót s1 chiÒu cao n s1 A B2 chiÒu cao n-1 chiÒu cao n -2 s C 0 B1 chiÒu cao n-1 B2 chiÒu cao n-1 chiÒu cao n x x 0 Xoay ph¶i nót s -1 A chiÒu cao n s1 s2 0 s B2 B1 C chiÒu chiÒu chiÒu cao http://www.ebook.edu.vn cao cao n n-1 n-1 57 CÊu tróc d÷ liÖu2 – Ch−¬ng 3. C©y ®á ®en x H×nh 3.13.b.2. Xoay kÐp c©y s. Còng nh− trong tr−êng hîp a, sau c¸c phÐp xoay c©y, nót s, s1, s2 ®· c©n b»ng. H¬n n÷a ta cã thÓ thÊy chiÒu cao cña c©y s2 lµ n+1, tøc lµ ®óng b»ng chiÒu cao cña c©y s tr−íc khi chÌn nót x. Tõ ®©y ta suy ra r»ng hÖ sè c©n b»ng cña c¸c nót tr−íc nót s ®Òu gi÷ nguyªn nh− tr−íc khi chÌn x. B¶ng sau ®©y ph©n biÖt c¸c tr−êng hîp c©y bÞ mÊt th¨ng b»ng khi thªm nót vµ c¸c phÐp xoay c©y t−¬ng øng ®Ó c©n b»ng l¹i c©y: Tr−êng hîp 1: C©y gèc s vèn lÖch tr¸i. Tr−êng Tr−íc khi Sau khi thªm C¸c phÐp xoay vµ chØ sè c©n b»ng hîp thªm nót x nót x míi a bal(s) = -1 bal(s)=-2 Xoay ph¶i nót s bal(s1)= 0 bal(s1)= -1 bal(s) = 0, bal(s1) = 0 Xoay kÐp: bal(s)= -2 bal(s) = -1 b1 1. Xoay tr¸i nót s1 bal(s1)= +1 bal(s1) = 0 2. Xoay ph¶i nót s bal(s2)=-1 bal(s2)=0 bal(s)=+1,bal(s1) = 0,bal(s2)=0 b2 bal(s) = -1 bal(s)= -2 Xoay kÐp: bal(s1) = 0 bal(s1)= +1 1. Xoay tr¸i nót s1 bal(s2)=0 bal(s2)=+1 2. Xoay ph¶i nót s bal(s)=0,bal(s1) = -1,bal(s2)=0 http://www.ebook.edu.vn 58 CÊu tróc d÷ liÖu2 – Ch−¬ng 3. C©y ®á ®en Tr−êng hîp 2: C©y gèc s vèn lÖch ph¶i. Tr−êng Tr−íc khi Sau khi thªm hîp thªm nót x nót x a bal(s) = +1 bal(s)=+2 bal(s1)= 0 bal(s1)= +1 bal(s)= +2 bal(s) = +1 b1 bal(s1)= -1 bal(s1) = 0 bal(s2)=+1 bal(s2)=0 b2 bal(s) = +1 bal(s1) = 0 bal(s2)=0 bal(s)= +-2 bal(s1)= -1 bal(s2)= -1 C¸c phÐp xoay vµ chØ sè c©n b»ng míi Xoay tr¸i nót s bal(s) = 0, bal(s1) = 0 Xoay kÐp: 1. Xoay ph¶i nót s1 2. Xoay tr¸i nót s bal(s)=-1,bal(s1) = 0,bal(s2)=0 Xoay kÐp: 1. Xoay ph¶i nót s1 2. Xoay tr¸i nót s bal(s)=0,bal(s1) = +1,bal(s2)=0 Nh− vËy khi thªm nót vµo c©y AVL nÕu c©y mÊt c©n b»ng th× ta chØ cÇn c©n b»ng côc bé b»ng c¸ch xoay ®¬n hay xoay kÐp c©y con cã nót gèc s. Ta cã thÓ tãm t¾t l¹i qu¸ tr×nh chÌn vµ c©n b»ng c©y mét c¸ch ®¬n gi¶n nh− sau: XuÊt ph¸t tõ gèc theo ®−êng ®i D, ta t×m ®−îc vÞ trÝ chÌn nót x. Sau khi chÌn x ta lÇn trë l¹i ®−êng ®i tõ x trë vÒ gèc vµ tÝnh l¹i hÖ sè cÇn b»ng vµ dõng l¹i ë nót s ®Çu tiªn cã hÖ sè c©n b»ng -2 (lÖch tr¸i) hoÆc 2 (lÖch ph¶i). Gäi s1 lµ con cña s n»m trªn ®−êng ®i D. DÜ nhiªn lµ hÖ sè c©n b»ng cña s1 kh«ng thÓ lµ 0. NÕu s lÖch cïng phÝa víi s1 th× chØ cÇn xoay c©y s theo nguyªn t¾c: lÖch tr¸i th× xoay ph¶i vµ ng−îc l¹i. Cßn nÕu s1 lÖch kh¸c phÝa th× tr−íc hÕt ph¶i xoay s1, sau ®ã xoay s. 3.5.4. Xo¸ nót trªn c©y AVL §Ó xãa mét nót khái c©y AVL ta ¸p dông thuËt to¸n lo¹i nót khái c©y t×m kiÕm. Tuy nhiªn khi xãa nót, c©y cã thÓ mÊt c©n b»ng vµ ta ph¶i c©n b»ng l¹i c©y b»ng thao t¸c xoay c¸c nh¸nh c©y liªn quan. Còng nh− tr−êng hîp thªm nót, chØ cã mét sè tr−êng hîp viÖc xãa nót lµm cho c©y mÊt th¨ng b»ng vµ ta ph¶i c©n b»ng l¹i. §ã lµ tr−êng hîp c©y vèn lÖch ph¶i vµ ta xãa nót ë nh¸nh c©y bªn tr¸i hoÆc c©y vèn lÖch tr¸i mµ ta xãa nót trªn nh¸nh c©y bªn ph¶i. ViÖc c©n b»ng c©y khi xo¸ nót tr¸i ®−îc thùc hiÖn t−¬ng tù nh− viÖc thªm nót trªn nh¸nh c©y bªn ph¶i vµ thao t¸c c©n b»ng khi xãa nót bªn ph¶i l¹i t−¬ng tù nh− thao t¸c c©n b»ng khi thªm nót trªn nh¸nh c©y bªn tr¸i. Tuy nhiªn nh− chóng ta sÏ thÊy, nÕu trong thao t¸c thªm nót ta chØ cÇn nhiÒu nhÊt lµ mét phÐp xoay ®¬n hoÆc kÐp ®Ó c©n b»ng l¹i c©y th× trong thao t¸c xãa nót, trong tr−êng hîp xÊu nhÊt ta cÇn thùc hiÖn kho¶ng logn thao t¸c xoay c©y däc theo ®−êng t×m kiÕm tõ nót thay thÕ trë vÒ nót gèc ®Ó c©n b»ng l¹i c©y. Thùc hiÖn phÐp xoay c©y ®Ó c©n b»ng l¹i c©y: Sau ®©y ta xÐt tr−êng hîp c©n b»ng l¹i c©y gèc s vèn lÖch tr¸i vµ ta thùc hiÖn xãa nót ë nh¸nh c©y bªn ph¶i, ®ång thêi ta gi¶ sö r»ng viÖc xãa nót ®· lµm cho nh¸nh c©y bªn ph¶i thÊp ®i 1 so víi tr−íc khi xãa. Ta cã c¸c tr−êng hîp sau: Gäi s1 lµ con tr¸i cña s, ta xÐt c¸c tr−êng hîp sau: http://www.ebook.edu.vn 59 CÊu tróc d÷ liÖu2 – Ch−¬ng 3. C©y ®á ®en Tr−êng hîp 1: Tr−íc khi xo¸ nót bal(s) = 1, tøc lµ c©y lÖch vÒ bªn ph¶i. Sau khi xãa nót th× bal(s)=0, c©y c©n b»ng hoµn toµn. Tuy nhiªn chiÒu cao cña c©y bÞ gi¶m ®i 1 so víi tr−íc khi xãa, do ®ã cã thÓ ¶nh h−ëng d©y chuyÒn ®Õn c¸c nót ®øng tr−íc. s 0 a c n n Tr−êng hîp 2: Tr−íc khi xo¸ nót bal(s) = 0, tøc lµ c©y kh«ng bÞ lÖch. Sau khi xãa nót th× bal(s)= -1, c©y vÉn c©n b»ng vµ chiÒu cao cña c©y kh«ng bÞ gi¶m, do ®ã kh«ng ¶nh h−ëng ®Õn c¸c nót ®øng tr−íc, gi¶i thuËt kÕt thóc. s -1 a c n n-1 Tr−êng hîp 3: Tr−íc khi xãa nót trªn nh¸nh c©y bªn ph¶i th× c©y lÖch tr¸i. Xãa nót xong th× c©y bªn ph¶i gi¶m ®i 1, do ®ã chØ sè c©n b»ng cña nót s sÏ b»ng -2. Ta ph¶i c©n b»ng l¹i. Tuy nhiªn kh¸c víi tr−êng hîp thªm nót, trong tr−êng hîp nµy chiÒu cao cña c©y bÞ gi¶m nªn cã thÓ ¶nh h−ëng d©y chuyÒn ®Õn c¸c nót ®øng tr−íc. Tr−êng hîp a: bal(s1)=0. s -2 s1 s1 Xoay ph¶i nót s quanh nót s1 +1 s c 0 -1 n-1 a b n n a n b c n n-1 H×nh 3.14.a. Bal(s1)=0, xoay ph¶i s, ®é cao c©y kh«ng ®æi (=n+1). Tr−êng hîp b: bal(s1)=-1. s -2 s1 s1 Xoay ph¶i nót s quanh nót s1 0 s c -1 0 n-1 a b n n-1 a n b n-1 http://www.ebook.edu.vn c n-1 60 CÊu tróc d÷ liÖu2 – Ch−¬ng 3. C©y ®á ®en H×nh 3.14.b. Bal(s1)=-1, xoay ph¶i s, c©y thÊp h¬n (n<n+1). Trong c¸c tr−êng hîp trªn sau khi thùc hiÖn phÐp quay ®¬n ta ®¹t ®−îc sù c©n b»ng, ®ång thêi ta thÊy r»ng ®é cao cña c©y s kh«ng thay ®æi so víi tr−íc khi xãa nót. Nh− vËy víi phÐp quay nµy ta ®· v« hiÖu hãa ¶nh h−ëng d©y chuyÒn cña viÖc xãa nót x: hÖ sè c©n b»ng cña c¸c nót ®øng tr−íc s kh«ng bÞ ¶nh h−ëng bëi viÖc chÌn nót. Tr−êng hîp c: bal(s1) =+1 Tr−êng hîp c.1: s2 = s1->right, bal(s2)=0 s s1 s -2 0 A chiÒu cao n-1 -1 C 1 B1 chiÒu cao n-1 Xoay tr¸i nót s1 chiÒu cao n-1 s2 s1 0 0 B1 chiÒu cao n-1 A chiÒu cao n-1 chiÒu cao n-1 s2 s1 0 C B2 chiÒu cao n-1 B1 chiÒu cao n-1 chiÒu cao n-1 Xoay ph¶i nót s s2 0 A B2 chiÒu cao n-1 -2 B2 chiÒu cao n-1 s C n-1 H×nh 3.14.c.1. Bal(s1)=+1, bal(s2)=0,xoay kÐp, c©y thÊp h¬n (n<n+1). Tr−êng hîp c.2: bal(s2)=-1 s s -2 s1 1 -1 A chiÒu cao n-1 -2 C B1 chiÒu cao n-1 Xoay tr¸i nót s1 chiÒu cao n-1 s2 A B2 chiÒu cao n-2 chiÒu cao n-1 Xoay ph¶i nót s 0 0 A chiÒu cao n-1 s1 s1 -2 s2 0 B1 chiÒu cao n-1 B2 chiÒu cao n-2 C chiÒu cao n-1 s2 1 s B1 B2 C chiÒu chiÒu cao cao n-1 n-1 n-2 http://www.ebook.edu.vn 61 CÊu tróc d÷ liÖu2 – Ch−¬ng 3. C©y ®á ®en H×nh 3.16.c.2. Bal(s1)=+1, bal(s2)=-1,xoay kÐp, c©y thÊp h¬n (n<n+1). Tr−êng hîp c.3: bal(s2)=+1 s s -2 1 A chiÒu cao n-1 -1 C s1 1 B1 chiÒu cao n-2 Xoay tr¸i nót s1 chiÒu cao n-1 s2 chiÒu cao n-1 Xoay ph¶i nót s 0 chiÒu cao n-1 B1 chiÒu cao n-2 B1 chiÒu cao n-2 B2 chiÒu cao n-1 C chiÒu cao n-1 s2 s1 -1 s2 -1 A B2 chiÒu cao n-1 A s1 -2 0 B2 chiÒu cao n-1 s C n-1 H×nh 3.14.c.3. Bal(s1)=+1, bal(s2)=1,xoay kÐp, c©y thÊp h¬n (n<n+1). Nh− ta cã thÓ thÊy ë trªn, cã kh¸ nhiÒu tr−êng hîp sau khi ®¹t ®−îc sù c©n b»ng th«ng qua phÐp xoay, th× ®é cao cña c©y bÞ thay ®æi, tøc lµ bÞ thÊp h¬n tr−íc. Sù thÊp h¬n nµy sÏ ¶nh h−ëng ®Õn c¸c nót ®øng tr−íc, v× vËy sau khi c©n b»ng xong c©y con ta l¹i ph¶i xÐt ®Õn c©y cha vµ c©n b»ng c©y cha. Qu¸ tr×nh sÏ dõng l¹i khi ta gÆp mét tr−êng hîp sau khi c©n b»ng th× c©y kh«ng bÞ thÊp ®i. 3.5.5. Vµi nhËn xÐt vÒ c©y AVL - Trung b×nh 2 lÇn thªm nót th× cÇn mét lÇn c©n b»ng l¹i c©y. - Trung b×nh 5 lÇn xãa nót th× cÇn mét lÇn c©n b»ng l¹i c©y. - Chóng ta sÏ chØ ra r»ng, trªn c©y AVL, trong tr−êng hîp xÊu nhÊt, thêi gian thùc hiÖn c¸c phÐp to¸n lµ O(logn). Tr−íc hÕt ta sÏ x¸c ®Þnh ®é cao cña c©y trong tr−êng hîp xÊu nhÊt. Thay cho viÖc x¸c ®Þnh ®é cao trong tr−êng hîp xÊu nhÊt, tøc lµ cho tr−íc n ta cÇn ph¶i x¸c ®Þnh ®é cao h trong tr−êng hîp xÊu nhÊt lµ bao nhiªu, ta sÏ x¸c ®Þnh sè nhá nhÊt c¸c ®Ønh mµ c©y AVL cã ®é cao h ph¶i cã. Gäi Th lµ c©y cã ®é cao h víi sè ®Ønh nhá nhÊt, vµ ta gäi Dh lµ sè ®Ønh t−¬ng øng. Nh− vËy víi h cè ®Þnh cã thÓ cã nhiÒu c¸ch tæ chøc c©y nh−ng Dh lµ mét sè kh«ng ®æi. Khi ®ã mét trong 2 c©y con cña nã ph¶i cã ®é cao h-1, cßn c©y con kia cã ®é cao h-1 hoÆc h-2. Nh−ng v× Th lµ c©y cã ®é cao h víi sè ®Ønh nhá nhÊt, nªn ta suy ra r»ng 2 c©y con kia cã ®é cao lµ h-1 vµ h-2, v× nÕu c¶ 2 cã ®é cao h-1 th× ta cã thÓ thay mét trong 2 c©y b»ng c©y cã ®é cao h-2, vÉn ®¶m b¶o yªu cÇu AVL mµ l¹i cã sè ®Ønh nhá h¬n. B¶n th©n 2 c©y con l¹i lµ nh÷ng c©y cã sè ®Ønh nhá nhÊt. Ta cã Dh = Dh-1 + Dh-2 +1 tõ ®©y ta cã Dh +1 = Dh-1 +1 + Dh-2 +1 http://www.ebook.edu.vn 62 CÊu tróc d÷ liÖu2 – Ch−¬ng 3. C©y ®á ®en §Æt Gh = Dh +1, ta cã G0 = 2, G1 = 3, Gh = Gh-1 + Gh-2 , h=2,3,... D·y Gh chÝnh lµ thµnh phÇn h+2 cña d·y Fibonacci, tøc lµ Gh = Fh+2. §Æt n = Dh vµ ¸p dông c¸c c«ng thøc ®· biÕt ta cã: h~ 1.44logn Nh− vËy, ®é cao cña c©y AVL trong tr−êng hîp xÊu nhÊt lµ O(logn). Tõ ®©y ta suy ra r»ng, thêi gian thùc hiÖn c¸c phÐp to¸n trªn c©y AVL trong tr−êng hîp xÊu nhÊt lµ O(logn). 3.5.6. Cµi ®Æt c©y AVL Sau ®©y lµ ch−¬ng tr×nh cµi ®Æt c©y AVL theo kiÓu liªn kÕt dïng biÕn ®éng. Mét sè t¸c vô nh− t¹o nót l¸ cã néi dung x, t×m kiÕm nót cã th«ng tin x b»ng ®Ö quy hay kh«ng dïng ®Ö quy... hoµn toµn t−¬ng tù nh− tr−êng hîp c©y nhÞ ph©n t×m kiÕm. ë ®©y chóng t«i gi¶i thÝch mét sè t¸c vô chÝnh kh¸c cña c©y AVL. • Khai b¸o c©y AVL CÊu tróc c¸c nót th«ng tin trªn c©y AVL còng gÇn gièng víi tr−êng hîp c©y nhÞ ph©n t×m kiÕm. Ta còng dïng ph−¬ng ph¸p liªn kÕt ®Ó cµi ®Æt c©y. Tuy nhiªn mçi nót cña c©y sÏ gåm 4 tr−êng: tr−êng info mang th«ng tin, tr−êng left cã kiÓu con trá node ®Ó chØ ®Õn con tr¸i, tr−êng right chØ ®Õn con ph¶i, vµ tr−êng bal lµ chØ sè c©n b»ng cña nót. Con trá proot chØ gèc cña c©y. Nh− ta ®· thÊy, ®Ó phôc vô cho viÖc c©n b»ng c©y tõ vÞ trÝ xãa nót cho ®Õn gèc khi cÇn thiÕt, ta ph¶i dïng mét Stack ®Ó l−u l¹i ®Þa chØ c¸c nót tõ gèc cho ®Õn nót cha cña nót cÇn lo¹i bá. Ta khai b¸o thªm mét cÊu tróc Snode gåm 2 tr−êng: tr−êng pnode chøa ®Þa chØ cña nót trªn c©y, tr−êng sè nguyªn d cã thÓ nhËn 2 gi¸ trÞ: -1 nÕu t¹i nót ®ã ®−êng ®i rÏ sang tr¸i, +1 nÕu ®−êng ®i rÏ sang ph¶i. struct Node {int key;int bal;Node *left,*right;}; //bal=-1 lech trai, bal=0 can bang, bal =+1 lech phai struct Snode {Node *pnode;int d;}; #include "stack_h.cpp" class AVLTree {public: Node* proot; //A pointer to the root of the AVLTree. long count; AVLTree(); ~AVLTree(); int Empty(); void Clear(Node*); //Xoa cay Node* MakeNode(int); //Tao nut la Node* SearchDQ(Node*,int); //Tim de quy va tra ve nut tim duoc Node* Search(Node*&,int);//Tim nut x , ghi lai nut cha void InTrav(Node*); //Duyet cay theo thu tu giua (de quy) Node* RotateLeft(Node*); Node* RotateRight(Node*); Node* LeftBal(Node*); //Can bang lai cay khi cay con trai cao len http://www.ebook.edu.vn 63 CÊu tróc d÷ liÖu2 – Ch−¬ng 3. C©y ®á ®en Node* RightBal(Node*); //Can bang lai cay khi cay con phai cao len Node* LeftBal2(Node *,int &); //Can bang cay khi cay con trai thap hon Node* RightBal2(Node *,int &);//Can bang cay khi cay con phai thap hon void Insert(int); //Chen nut moi khong de quy void Remove(int); //Xoa nut co noi dung x }; • T¸c vô xoay tr¸i gèc c©y P quanh nót con ph¶i cña nã T¸c vô nµy ®−îc dïng ®Ó c©n b»ng l¹i c©y khi c©y bÞ lÖch qu¸ møc cho phÐp. Gi¶ sö c©y gèc P cã nót ph¶i lµ Q, c¸c nh¸nh c©y a, b, c cã chiÒu cao nh− nhau. Trªn h×nh vÏ ta thÊy c©y ®ang bÞ lÖch ph¶i, do ®ã nÕu ta thªm nót x vµo nh¸nh c©y c th× nót P cã hÖ sè c©n b»ng lµ 2, tøc lµ qu¸ møc cho phÐp. NÕu ta thùc hiÖn phÐp xoay nót P quanh con ph¶i cña nã, tøc lµ ®Æt con tr¸i cña nót Q b©y giê thµnh con ph¶i cña nót P, cßn nót P thµnh con tr¸i cña nót Q, th× ta ®−îc mét c©y míi cã gèc lµ Q vµ hÖ sè c©n b»ng cña Q b©y giê b»ng 0. Input: C©y gèc P, sao cho P cã con ph¶i kh¸c rçng. Output: Tr¶ vÒ nót gèc míi Q, vèn lµ con ph¶i cña P, cßn P th× nay trë thµnh con tr¸i cña Q. P Q Xoay tr¸i nót P quanh nót Q a Q b P c a c b x x H×nh 3.15.Xoay tr¸i c©y nhÞ ph©n. node* AVLTree::rotateleft(node* &p) {if(p == NULL || p->right==NULL) {cout<<endl<<"Khong the xoay trai.";return NULL;} node* pr = p->right; p->right = pr->left; pr->left = p; return pr; } • T¸c vô xoay ph¶i gèc c©y P quanh nót con tr¸i cña nã T¸c vô nµy t−¬ng tù nh− t¸c vô xoay tr¸i. B¹n ®äc cã thÓ xem h×nh vÏ ®Ó hiÓu râ c¸ch ho¹t ®éng cña t¸c vô. Input: C©y gèc P, sao cho P cã con tr¸i kh¸c rçng. Output: Tr¶ vÒ nót gèc míi Q, vèn lµ con tr¸i cña P, cßn P th× nay trë thµnh con ph¶i cña Q. Q P http://www.ebook.edu.vn 64 CÊu tróc d÷ liÖu2 – Ch−¬ng 3. C©y ®á ®en Xoay ph¶i nót P quanh nót Q c Q P a b a c b x x H×nh 3.16. Xoay ph¶i c©y nhÞ ph©n. node* AVLTree::rotateright(node* &p) {if(p == NULL || p->left==NULL) {cout<<endl<<"Khong the xoay trai.";return NULL;} node* pl = p->left; p->left = pl->right; pl->right = p; return pl; } • T¸c vô c©n b»ng c©y s khi thªm nót vµo nh¸nh c©y tr¸i vµ c©y s bÞ lÖch tr¸i T¸c vô nµy c©n b»ng l¹i c©y gèc s khi c©y bÞ lÖch tr¸i. Input: C©y gèc s. Output: Tr¶ vÒ nót gèc míi thay thÕ vÞ trÝ cña s trong c©y sao cho c©y trë thµnh c©n b»ng (Xem c¸c h×nh 3.15 trªn ®©y). //Neu cay goc p bi lech trai thi phai can bang lai Node* AVLTree::LeftBal(Node* p) {if(p->bal!=-2) {cout<<endl<<"Cay khong lech trai, khong phai quay";} Node *p1,*p2; p1=p->left; switch(p1->bal) {case -1:/*Cay goc p1 lech trai, nghia la lech cung phia voi p chi can quay phai nut p*/ p->bal=0;p1->bal=0;return RotateRight(p); case +1:/*Cay goc p1 lech phai, nghia la lech khac phia voi p phai quay kep: quay trai p1, roi quay phai p*/ p2=p1->right; switch(p2->bal) {case 0:p->bal= 0; p1->bal= 0;break;//p2 can bang case -1:p->bal=+1; p1->bal= 0;break;//p2 lech trai case +1:p->bal= 0; p1->bal=-1;break;//p2 lech phai } //Xoay trai p1, roi xoay phai p p2->bal=0; http://www.ebook.edu.vn 65 CÊu tróc d÷ liÖu2 – Ch−¬ng 3. C©y ®á ®en p->right=RotateLeft(p1); return RotateRight(p);//Chinh la nut p2 } return p;//Neu trong truong hop khac thi khong lam gi } • T¸c vô thªm nót cã néi dung x vµo c©y gèc proot T¸c vô nµy thªm mét nót cã néi dung x vµo c©y AVL vµ thùc hiÖn c¸c thao t¸c c©n b»ng l¹i c©y sao cho c©y vÉn lµ c©y AVL. Input: Néi dung cÇn chÌn vµo c©y. Output: C©y AVL trong ®ã ®· cã nót x. Qu¸ tr×nh thªm nót vµo c©y ®−îc tiÕn hµnh qua c¸c b−íc sau: B−íc 1: KiÓm tra nÕu c©y rçng th× t¹o nót gèc cã néi dung x vµ kÕt thóc. B−íc 2: KiÓm tra xem nót x ®· cã trªn c©y ch−a, nÕu cã råi th× th«ng b¸o vµ kÕt thóc. B−íc 3: So s¸nh gi¸ trÞ x víi khãa trªn nót gèc vµ c¸c nót trªn ®−êng ®i ®Ó xuÊt ph¸t tõ gèc ®i ®Õn nót fp lµ n¬i cã thÓ thªm nót x. Trong qu¸ tr×nh nµy con trá s ghi l¹i vÞ trÝ cuèi cïng cña nót cã hÖ sè c©n b»ng kh¸c kh«ng, lµ n¬i cã thÓ x¶y ra sù mÊt c©n b»ng. Trong khi ®ã con trá fs trá tíi nót cha cña s. V× s xuÊt ph¸t tõ nót gèc proot, fs xuÊt ph¸t lµ NULL, vµ cã thÓ kh«ng cã tr−êng hîp kh¸c kh«ng xÈy ra. Do ®ã hÖ sè c©n b»ng cña s cã thÓ lµ -1 (lÖch tr¸i), 0 (c©n b»ng) hoÆc +1 (lÖch ph¶i). B−íc 4: Thªm nót cã néi dung x vµo nót fp. NÕu x nhá h¬n khãa cña fp th× thªm nót tr¸i, ng−îc l¹i thªm nót ph¶i. B−íc 5: ChØnh l¹i hÖ sè c©n b»ng cña c¸c nót n»m tõ nót s ®Õn nót fp, lµ nót cha cña q. NÕu nót q ë phÝa tr¸i th× chØ sè c©n b»ng cña nót ®ã tõ 0 chuyÓn thµnh - 1, nÕu bÞ lÖch vÒ phÝa ph¶i th× chØ sè c©n b»ng lµ +1. B−íc 6: B©y giê ta xÐt c¸c tr−êng hîp t−¬ng øng víi hÖ sè c©n b»ng cña nót s, nÕu chØ sè c©n b»ng cña s lµ 2 hoÆc -2 th× c©n b»ng l¹i c©y s vµ kÕt thóc. Trong ch−¬ng tr×nh, dßng lÖnh if(x < s->info) pp=leftbal(s); else pp=rightbal(s); sÏ tr¶ vÒ nót gèc míi pp cña c©y s. NÕu s lµ nót gèc th× nay nót gèc míi lµ nót pp. Trong tr−êng hîp kh¸c ta g¸n nót pp cho nót fs, vèn lµ cha cña nót s. /* Tac vu Insert: them nut co noi dung x vao cay AVL: - Them nut theo giai thuat binh thuong, nut them vao la nut la duoc bo tri o vi tri phu hop tren cay - Can bang lai cay bang cach xoay don hay xoay kep */ void AVLTree::Insert(int x) http://www.ebook.edu.vn 66 CÊu tróc d÷ liÖu2 – Ch−¬ng 3. C©y ®á ®en {if(proot==NULL) {proot=MakeNode(x);return;} if(SearchDQ(proot,x)) {cout<<endl<<"Nut da co, khong them duoc!";return;} Node *fp, *p, *q, // fp la nut cha cua p, q la nut them vao *fs, *s, /* s la nut truoc gan nhat co the mat can bang fs la nut cha cua s */ *pp; /* s la nut con cua s theo huong mat can bang pp la nut tam thoi*/ // Khoi dong cac gia tri fp = NULL; p = proot; fs=NULL; s=p; //tim nut fp, s va fs, nut moi them vao la nut la con cua nut fp while(p!=NULL) {if(x<p->key) {fp=p;p=p->left;} else {fp=p;p=p->right;} if(p!=NULL && p->bal!=0){fs=fp;s=p;}/*Danh dau diem co the bi mat can bang*/ } //end of while(p!=NULL) /*Sau vong lap tren day thi s la nut truoc gan nhat co chi so can bang khac 0.(La nut truoc gan nhat co the bi mat can bang) fs la nut cha cua s. Nut p bi rong, con nut fp la nut can them nut co noi dung x. Nut s co the cach xa nut fp*/ //Them nut q co noi dung x la con cua fp. q = MakeNode(x); if(x < fp->key) fp->left = q; else fp->right = q; //Tao nut la moi co noi dung x /* Hieu chinh chi so can bang cua tat ca cac nut tu s den nut cha cua q. Neu nut q o phia trai thi chi so can bang cua nut do tang 1, neu bi lech ve phia phai thi giam 1 */ p=s; while(p != q) //Cac nut tu s den cha nut q {if(x < p->key) {p->bal--;p = p->left;} else {p->bal++;p = p->right;} }//end of while(p != q) if(abs(s->bal)!=2) return;//Cay goc s khong lech if(s->bal==-2) pp=LeftBal(s); else pp=RightBal(s); if(fs == NULL) {proot = pp; return; http://www.ebook.edu.vn 67 CÊu tróc d÷ liÖu2 – Ch−¬ng 3. C©y ®á ®en } if(s == fs->right) /*Neu s von la con phai cua fs thi gio day pp la con phai*/ fs->right = pp; else fs->left = pp; /*Neu s von la con trai cua fs thi gio day pp la con trai*/ } • T¸c vô c©n b»ng c©y p khi xãa nót trªn nh¸nh c©y ph¶i. Gi¶ sö khi ta xãa nót trªn nh¸nh c©y bªn ph¶i cña c©y p vµ lµm cho c©y con ph¶i nµy bÞ thÊp ®i 1. T¸c vô sau thùc hiÖn c¸c thao t¸c trªn c©y p nh»m môc ®Ých c©n b»ng l¹i c©y nÕu cÇn thiÕt vµ tÝnh l¹i biÕn shorter , nÕu shorter = true th× cã nghÜa lµ viÖc c©y bªn ph¶i bÞ thÊp xuèng ®· lµm cho ®é cao cña c©y p còng bÞ gi¶m vµ ¶nh h−ëng ®Õn ®é cao cña c¸c c©y bao nã. Input: C©y gèc p vµ tham sè shorter (=true). Output: Tr¶ vÒ nót gèc míi thay thÕ vÞ trÝ cña p trong c©y sao cho c©y trë thµnh c©n b»ng, tr¶ vÒ gi¸ trÞ shorter sau khi ®· tÝnh to¸n l¹i. NÕu shorter = false th× kÕt thóc qu¸ tr×nh lÇn ng−îc vÒ nót gèc. (Xem c¸c h×nh 3.14 trªn ®©y). /*Input: Cay goc p co nut bi xoa nam tren cay con phai va chieu cao cua cay con phai bi giam, tuc la shorter = true. Tuy nhien chi so can bang cua p chua duoc tinh lai. Xu ly: Viec chieu cao cay con phai giam anh huong nhu the nao den cay p? neu cay p mat can bang thi can bang lai, tinh lai shorter. Output: Cay p da can bang, tham so shorter cho biet cay co bi giam chieu cao so voi truoc khi xoa nut tren nhanh cay phai khong*/ Node* AVLTree::RightBal2(Node *p,int &shorter) {Node *p1,*p2,*pp; if(!shorter) return(p); switch(p->bal) {case +1:/*Cay bi lech phai, chieu cao cay con phai giam 1 thi tro thanh can bang, nhung chieu cao cay p van giam, khong phai can bang cay, nhung tham so shorter tra ve la true, nen qua trinh van tiep tuc*/ p->bal=0;pp=p;break; case 0:/*Cay von can bang, chieu cao cay con phai giam 1 thi tro thanh lech trai, nhung chieu cao khong giam*/ p->bal=-1;shorter=false;pp=p;break; case -1:/*can bang lai. Cay von lech trai, chieu cao cay con phai giam 1 thi dan den he so can bang nut p la -2*/ p1=p->left; switch(p1->bal) {case 0://Quay phai nut P //chieu cao cua cay goc p khong bi giam http://www.ebook.edu.vn 68 CÊu tróc d÷ liÖu2 – Ch−¬ng 3. C©y ®á ®en p->bal=-1; p1->bal=+1; shorter=false; pp=RotateRight(p); break; case -1://Xoay phai nut P //chieu cao cua cay goc p van bi giam p->bal=0; p1->bal=0; pp=RotateRight(p); break; case +1://Phep xoay kep: xoay trai P1, roi xoay phai P p2=p1->right; switch(p2->bal) {case 0: p->bal= 0;p1->bal= 0;break; case -1: p->bal= 1;p1->bal= 0;break; case +1: p->bal= 0;p1->bal=-1;break; } p2->bal=0; p->left=RotateLeft(p1); pp=RotateRight(p); };//End of switch(p1->bal) }; return(pp); };//RightBal2 http://www.ebook.edu.vn 69 CÊu tróc d÷ liÖu2 – Ch−¬ng 3. C©y ®á ®en • T¸c vô xãa nót cã khãa x trªn c©y gèc proot T¸c vô nµy xãa nót cã khãa x trªn c©y AVL vµ thùc hiÖn c¸c thao t¸c c©n b»ng l¹i c©y sao c©y vÉn lµ c©y AVL. Input: Khãa cÇn xãa trªn c©y. Output: C©y AVL trong ®ã ®· xãa nót x. Qu¸ tr×nh xãa nót trªn c©y ®−îc tiÕn hµnh qua c¸c b−íc sau: Tr−íc khi thùc hiÖn c¸c thao t¸c, ta t¹o mét Stack, trong ®ã c¸c phÇn tö cña Stack cã kiÓu struct Snode gåm 2 thµnh phÇn: biÕn con trá pnode chØ ®Þa chØ c¸c nót trªn c©y vµ biÕn nguyªn d chØ c¸c h−íng ®i tõ gèc cho ®Õn nót x. NÕu t¹i mét nót nµo ®ã ta rÏ sang c©y con tr¸i th× d=-1, cßn nÕu rÏ sang c©y con ph¶i th× d=+1. B−íc 1: Cho con trá p xuÊt ph¸t tõ gèc, ®i qua c¸c nót thÝch hîp ®Ó ®Õn nót x. Thùc chÊt ®©y lµ gi¶i thuËt t×m kiÕm kh«ng dïng ®Ö quy trªn c©y nhÞ ph©n t×m kiÕm. Trong qu¸ tr×nh ®Õn x ta ®−a vµo Stack c¸c cÆp (p,d), trong ®ã p chØ nót gèc ®i qua, cßn d chØ h−íng ®i xuÊt ph¸t tõ p. Khi gÆp x th× ta kh«ng ®−a nót cã khãa x vµo Stack. B−íc 2: NÕu ®i ®Õn cïng mµ vÉn kh«ng gÆp x, tøc lµ p==NULL th× th«ng b¸o kh«ng t×m thÊy vµ kÕt thóc. B−íc 3: NÕu x lµ nót l¸ hoÆc chØ cã mét con th× ta ®Æt l¹i mèi liªn kÕt cÇn thiÕt, råi xãa x, chuyÓn sang b−íc 5, nÕu x cã 2 con kh¸c rçng th× chuyÓn sang b−íc 4. B−íc 4: XuÊt ph¸t tõ nót cã khãa x, ta ®i tíi nót ph¶i nhÊt trªn c©y con tr¸i, trong qu¸ tr×nh ®i ta ®−a vµo Stack cÆp (p,d) t−¬ng tù nh− trªn. Khi gÆp nót thay thÕ, ta ®æi néi dung cña nót x víi nót thay thÕ, ®Æt l¹i mèi liªn kÕt råi xãa nót thay thÕ. B−íc 5: NÕu Stack rçng th× ta kÕt thóc gi¶i thuËt. NÕu Stack kh¸c rçng th× phÇn tö trªn cïng chÝnh lµ nót P ®øng tr−íc nót x hoÆc nót thay thÕ, do ®ã ta biÕt ch¾c lµ nót nµy cã con ph¶i hoÆc con tr¸i bÞ thÊp h¬n (con tr¸i hay con ph¶i phô thuéc vµo d). Ta b¾t ®Çu lÊy phÇn tö tõ Stack vµ tiÕn hµnh thao t¸c LeftBal2 hoÆc RightBal2 víi biÕn shorter=true. TiÕp theo nÕu shorter=true vµ Stack kh¸c rçng ta l¹i lÊy tiÕp phÇn tö trong Stack vµ thùc hiÖn c¸c thao t¸c trªn. Cø nh− vËy cho ®Õn khi Stack rçng vµ kÕt thóc gi¶i thuËt. Thao t¸c c©n b»ng vµ tÝnh l¹i chiÒu cao c©y gèc P khi c©y cã con tr¸i hoÆc con ph¶i bÞ ng¾n ®i: Gi¶ sö c©y gèc P cã con ph¶i bÞ ng¾n ®i. Lóc nµy chØ sè c©n b»ng cña P sÏ gi¶m ®i 1. V× c©y con ph¶i cña P bÞ ng¾n ®i, ta dïng t¸c vô RightBal2 ®Ó c©n b»ng l¹i vµ tÝnh l¹i ®é cao. ChØ sè c©n b»ng cña P chØ cã thÓ nhËn c¸c gi¸ trÞ -1, 0, hoÆc 1, do ®ã sau khi c©y bªn ph¶i bÞ ng¾n ®i th× sÏ lµ -2, -1 hoÆc 0. NÕu chØ sè c©n b»ng míi cña P lµ -2 th× ta ph¶i xoay ph¶i c©y gèc P: nÕu chØ sè c©n b»ng con bªn tr¸i cña P lµ 0 hoÆc -1 th× ta chØ cÇn xoay ®¬n, nÕu =1 th× ph¶i xoay kÐp. ChØ cã tr−êng hîp chØ sè míi cña P lµ -1 (tøc lµ tr−íc ®ã = 0) th× c©y kh«ng bÞ ng¾n ®i vµ kh«ng ph¶i c©n b»ng nót cha cña P vµ kÕt thóc thuËt to¸n. Trong hai tr−êng hîp cßn l¹i ph¶i c©n b»ng nót cha cña P vµ qu¸ tr×nh c©n b»ng cã thÓ ph¶i thùc hiÖn trªn tÊt c¶ c¸c nót tõ P cho ®Õn ®Õn tËn gèc cña c©y ban ®Çu. /*Khi xoa mot nut P trong cay nhi phan tk ta tim mot nut de thay the nut do. Neu P la nut la thi nut thay the la nut NULL. Neu P chi co mot cay con thi nut thay the la nut con cua no. Neu P co 2 cay con thi nut thay the la nut trai nhat cua cay con ben phai hoac nut phai nhat cua http://www.ebook.edu.vn 70 CÊu tróc d÷ liÖu2 – Ch−¬ng 3. C©y ®á ®en cay con ben trai.Ta quy uoc chon nut phai nhat cua cay con ben trai*/ void AVLTree::Remove(int x) {Node *fp,*p,*f,*lp,*rp,*p1; /*lp la goc cay con trai cua nut p, rp la nut thay the cho nut p co khoa x, f la nut cha cua nut thay the rp*/ Snode tmp; Stack<Snode> s(20); //s.initialize(); /*Xuat phat tu goc, tim nut co khoa x, dung lai khi gap x. Dua vao stack cac nut di qua(khong dua nut x vao Stack)*/ p=proot;fp=NULL; while(p!=NULL) {if(p->key==x) break; if(x < p->key) {fp=p; tmp.pnode=fp;tmp.d=-1;s.push(tmp); p = p->left; } else {fp=p; tmp.pnode=fp;tmp.d=+1;s.push(tmp); p = p->right; } } if(p==NULL) {cout<<"Khong tim thay nut x";return;} //Loai bo nut x, dat lai moi lien ket //Nut la if(p->right==NULL && p->left==NULL) {if(p==proot) {delete proot;proot=NULL;return;} if(fp->left==p) {fp->left=NULL;delete p;} if(fp->right==p) {fp->right=NULL;delete p;} }; //Nut chi co mot cay con trai if(p->left!=NULL && p->right==NULL) {if(fp==NULL) {proot=p->left;delete p;return;} if(fp->left==p) {fp->left=p->left;delete p;} if(fp->right==p) {fp->right=p->left;delete p;} } //Nut chi co mot cay con phai if(p->left==NULL && p->right!=NULL) {if(fp==NULL) {proot=p->right;delete p;return;} if(fp->left==p) {fp->left=p->right;delete p;} if(fp->right==p) {fp->right=p->right;delete p;} }; http://www.ebook.edu.vn 71 CÊu tróc d÷ liÖu2 – Ch−¬ng 3. C©y ®á ®en if(p->left!=NULL && p->right!=NULL) {//Nut p co 2 nut con //Tim nut thay the, la nut phai nhat cua cay con trai tmp.pnode=p; tmp.d=-1; s.push(tmp); f=p; rp=p->left;//Khoi dau chon rp la nut goc cay trai, sau do se //di ve phai de tim nut phai nhat while(rp->right!=NULL) {tmp.pnode=rp; tmp.d=1; s.push(tmp); f=rp;rp=rp->right; } if(f==p) f->left=rp->left; else f->right=rp->left;/*rp la phai nhat, do do khong co con phai vi khong con rp nen nut cha phai chi den nut sau do*/ p->key=rp->key; //doi noi dung cua p va rp, roi xoa rp delete rp; } //Bat dau can bang cac cay tu dinh Stack, tuc la lan nguoc ve goc if(s.empty()) return; int shorter=true; tmp=s.pop(); p=tmp.pnode; if(tmp.d==-1) p1=LeftBal2(p,shorter); else p1=RightBal2(p,shorter); while(!s.empty()) {tmp=s.pop(); p=tmp.pnode; if(tmp.d==-1) p->left=p1; else p->right=p1; if(!shorter) break; else http://www.ebook.edu.vn 72 CÊu tróc d÷ liÖu2 – Ch−¬ng 3. C©y ®á ®en {if(tmp.d==-1) p1=LeftBal2(p,shorter); else p1=RightBal2(p,shorter); } if(s.empty()) {proot=p1;break; //Da o nut cuoi cung la nut goc } } } 3.5.7. Cµi ®Æt c©y AVL trªn bé nhí ngoµi Cã thÓ sö ®æi ch−¬ng tr×nh trªn ®©y thµnh ch−¬ng tr×nh cµi ®Æt c©y AVL trªn bé nhí ngoµi. Ch−¬ng tr×nh 32CAYAVF.CPP trong phÇn phô lôc lµ ch−¬ng tr×nh cµi ®Æt c©y AVL trªn bé nhí ngoµi. Cã mét vµi hµm ®−îc thªm vµo. PhÇn lín c¸c hµm kh¸c ®Òu t−¬ng tù nh− tr−êng hîp c©y AVL cµi ®Æt trong bé nhí, v× vËy chóng t«i kh«ng giíi thiÖu chi tiÕt ë ®©y. http://www.ebook.edu.vn 73 Ch−¬ng 4 B - c©y vµ bé nhí ngoµi 4.1. Më ®Çu Trong ch−¬ng 3 chóng ta ®· nghiªn cøu c©y nhÞ ph©n ®á ®en. Víi c©y cã bËc n > 2 ta cã thÓ biÕn ®æi thµnh c©y nhÞ ph©n. Tuy nhiªn c¸ch lµm nµy chØ cã ý nghÜa lý thuyÕt, c©y t¹o thµnh theo kiÓu nµy kh«ng cã ý nghÜa l¾m trong thùc hµnh. T×m kiÕm lµ mét trong nh÷ng thao t¸c th−êng xuyªn dïng ®Õn trong xö lý sè liÖu. Chóng ta ®· thÊy c©y c©n b»ng AVL lµ cÊu tróc tèt cho thao t¸c t×m kiÕm. Tuy nhiªn c¸c thao t¸c thªm vµo vµ xãa nót trªn c©y AVL kh¸ phøc t¹p do ta th−êng ph¶i thùc hiÖn c¸c thao t¸c c©n b»ng l¹i c©y sau mçi lÇn xãa hoÆc thªm nót. N¨m 1970 R. Bayer vµ McCreight ®· ®−a ra mét cÊu tróc c©y nhiÒu nh¸nh víi ý t−ëng lµ mçi nót trªn c©y cã thÓ chøa mét sè l−îng lín khãa sao cho mçi nót cã hÖ sè nh¸nh lín. Trong thùc hµnh mçi nót sÏ lµ mét trang th«ng tin trªn ®Üa, vµ nh− vËy sè lÇn truy xuÊt ®Üa sÏ gi¶m ®i ®¸ng kÓ. C©y do Bayer ®Ò xuÊt ®−îc gäi lµ B - c©y. Trong ch−¬ng nµy chóng ta sÏ ngiªn cøu c¸ch cµi ®Æt B-c©y vµ øng dông. 4.2. B - c©y 4.2.1. C©y t×m kiÕm nhiÒu nh¸nh (Multiway Search Tree) C©y t×m kiÕm bËc n lµ tæng qu¸t hãa cña c©y t×m kiÕm nhÞ ph©n. §Æc ®iÓm cña c©y nµy lµ t¹i mçi nót trªn c©y cã nhiÒu khãa vµ nhiÒu nh¸nh c©y con, sè khãa Ýt h¬n sè nh¸nh c©y con lµ 1. §iÒu kiÖn vÒ c¸c khãa vµ nh¸nh c©y con nh− sau: - NÕu ®Ønh a cã r-1 khãa k0, k1,..., kr-2 (r<=n), c¸c khãa ph¶i ®−îc s¾p thø tù k0<k1<...<kr-2 vµ ®Ønh cã tèi ®a lµ r con. C¸c nh¸nh con s0, s1,..., sr-2 , sr-1 hoÆc lµ rçng, hoÆc ph¶i tho¶ m·n ®iÒu kiÖn sau: c¸c khãa trong nh¸nh s0 ph¶i nhá h¬n hay b»ng khãa k0, c¸c khãa trong nh¸nh si ph¶i lín h¬n hay b»ng khãa ki-1 vµ nhá h¬n hay b»ng khãa ki, i =1,2,...,r-2, c¸c khãa trong nh¸nh sr-1 ph¶i lín h¬n hay b»ng khãa kr-2. H×nh 5.1 sau m« t¶ nh¸nh c©y cã r-2 khãa: 50 20 40 30 5 10 2 4 70 15 25 45 35 42 47 49 55 65 52 60 63 80 85 68 75 95 H×nh 4.1 C©y t×m kiÕm bËc 3. Theo ®Þnh nghÜa trªn ®©y ta cã thÓ thÊy r»ng c©y nhÞ ph©n t×m kiÕm chÝnh lµ c©y nhiÒu nh¸nh t×m kiÕm bËc 2. http://www.ebook.edu.vn CÊu tróc d÷ liÖu2 – Ch−¬ng 4. B - c©y vµ bé nhí ngoµi 4.2.2. §Þnh nghÜa B - c©y a. §Þnh nghÜa 1: B - c©y bËc n+1 lµ c©y t×m kiÕm bËc n+1 (tøc lµ cã nhiÒu nhÊt n+1 nh¸nh c©y con vµ nh− vËy cã nhiÒu nhÊt lµ n khãa) tháa m·n c¸c ®iÒu kiÖn sau ®©y: (1) TÊt c¶ c¸c nót trªn c©y trõ nót gèc, cã Ýt nhÊt m = ⎡n/2⎤ khãa, tøc lµ tÊt c¶ c¸c nót trõ nót gèc ®Òu ®Çy h¬n mét nöa. (2) NÕu nót cã r khãa th× hoÆc lµ nót l¸ (kh«ng cã con), hoÆc lµ ph¶i cã r+1 con kh¸c rçng. (3) TÊt c¶ c¸c nót l¸ cã cïng mét møc. §Ó ®¬n gi¶n trong qu¸ tr×nh tÝnh to¸n vµ kh«ng lµm mÊt tÝnh chÊt tæng qu¸t, ta sÏ gi¶ thiÕt n lµ mét sè ch½n, vµ m = n/2 ®−îc gäi lµ cÊp cña c©y. Ta cã ®Þnh nghÜa sau ®©y t−¬ng ®−¬ng víi ®Þnh nghÜa trªn: b. §Þnh nghÜa 2: B - c©y cÊp m (hay lµ c©y bËc 2*m+1) lµ c©y t×m kiÕm bËc n1 = 2*m+1 tháa m·n c¸c ®iÒu kiÖn sau ®©y: (4) TÊt c¶ c¸c nót trªn c©y trõ nót gèc, cã Ýt nhÊt m khãa, vµ cã tèi ®a lµ 2*m khãa (tøc lµ c¸c nót ph¶i ®Çy h¬n mét nöa). (5) NÕu nót B cã r khãa th× hoÆc B lµ nót l¸ (kh«ng cã con), hoÆc lµ ph¶i cã r+1 con kh¸c rçng. (6) TÊt c¶ c¸c nót l¸ cã cïng mét møc. Tõ nay vÒ sau chóng ta sÏ sö dông ®Þnh nghÜa thø 2. 50 20 40 17 18 19 70 80 30 31 32 35 43 45 53 57 62 71 72 90 91 92 H×nh 4.2 B- c©y cÊp 2, tÊt c¶ c¸c nót ®Òu cã tõ 2 ®Õn 4 kho¸ (trõ gèc) 4.2.3. T×m kiÕm trªn B - c©y Gi¶ sö chóng ta cÇn t×m b¶n ghi h cã khãa x. Chóng ta xuÊt ph¸t tõ gèc cña B - c©y, vµ ®i theo nh¸nh c©y thÝch hîp. Gi¶ sö ta ®ang ë ®Ønh B. NÕu ®Ønh B lµ l¸ th× ta ph¶i t×m trong khèi B xem cã chøa b¶n ghi h hay kh«ng. V× c¸c khãa trong B ®−îc s¾p theo thø tù t¨ng dÇn nªn ta cã thÓ ¸p dông kü thuËt t×m kiÕm nhÞ ph©n hoÆc tuÇn tù. NÕu B lµ ®Ønh trong chøa c¸c khãa k0, k1,..., kr-2 th× ta cÇn x¸c ®Þnh vÞ trÝ cña x trong d·y khãa nµy. ThÝ dô nÕu ki-1< x < ki th× ta t×m x trªn c©y con n»m gi÷a ki-1 vµ ki. 4.2.4. Thªm khãa vµo B - c©y Khi thªm mét khãa x vµo B- c©y th× chóng ta ph¶i ¸p dông thñ tôc t×m kiÕm ®Ó t×m ra khèi B cÇn ph¶i xen vµo. NÕu khãa x ®· tån t¹i trªn c©y th× ta kh«ng thªm n÷a, v× c¸c khãa trªn c©y ph¶i duy nhÊt, kh«ng ®−îc lÆp l¹i. Ta cã thÓ thÊy r»ng thñ tôc thªm nót lu«n lu«n cã thÓ ®−îc thùc hiÖn ë nót l¸. ThËt vËy, v× nót x ch−a cã trªn c©y nªn xuÊt ph¸t tõ nót gèc ta sÏ ®i theo con ®−êng ®i qua c¸c nót trong ®Ó ®Õn mét nót l¸ nµo ®ã. T¹i mét nót trung gian ta lu«n cã hoÆc lµ x http://www.ebook.edu.vn 75 CÊu tróc d÷ liÖu2 – Ch−¬ng 4. B - c©y vµ bé nhí ngoµi < k0 trong ®ã k0 lµ khãa nhá nhÊt trong ®Ønh ®ã, khi nµy ta ®i theo nh¸nh c©y con n»m bªn tr¸i khãa k0 . NÕu x > kr-2 trong ®ã kr-2 lµ khãa lín nhÊt trong ®Ønh ®ã, khi nµy ta ®i theo nh¸nh c©y con n»m bªn ph¶i khãa kr-2. NÕu ki-1< x < ki th× ta ®i theo c©y con n»m gi÷a ki-1 vµ ki. VËy thao t¸c thªm nót lu«n ®−îc thùc hiÖn ë mét nót l¸ nµo ®ã ®−îc x¸c ®Þnh bëi x. Gi¶ sö ta ®Õn nót l¸ B. Ta ®Æt n= 2*m lµ sè khãa tèi ®a vµ n1=n+1 lµ sè con tèi ®a trong mét nót. Ta thùc hiÖn viÖc chÌn nót x nh− sau: • NÕu nót B ch−a ®Çy th× chóng ta chÌn khãa x vµo nót nµy theo thao t¸c chÌn nót vµo danh s¸ch s¾p thø tù. • NÕu nót B ®· ®Çy, tøc lµ cã n khãa, nÕu ta thªm khãa x th× nót B bÞ trµn. Ta gäi midkey lµ khãa ë gi÷a. Ta t¸ch nót B thµnh 2 nót, mçi nót gåm m nót. Nót nöa tr¸i gåm c¸c khãa tõ 0 ®Õn midkey-1, ta gäi lµ nót nd. Nót nöa ph¶i (gäi lµ nót nd2) gåm c¸c nót cã khãa tõ midkey+1 ®Õn n1. Khãa midkey vµ nót con nd2 ®−îc chuyÓn lªn chÌn vµo nót cha. NÕu nót cha bÞ ®Çy ta l¹i thùc hiÖn t−¬ng tù nh− víi nót B. Nh− vËy viÖc t¸ch nót cã thÓ lan truyÒn tíi gèc vµ nót gèc cã thÓ bÞ t¸ch lµm 2. §©y chÝnh lµ c¸ch duy nhÊt ®Ó B-c©y cã thÓ t¨ng chiÒu cao: nã lín lªn tõ l¸ ®Õn gèc. VÝ dô: XÐt B-c©y sau ®©y: A 20 7 10 15 18 26 30 35 40 C B A 7 10 15 18 B 20 30 22 26 35 40 C D H×nh 4.3 Thªm khãa 22 vµo B-c©y 1. Gi¶ sö ta ph¶i thªm khãa 22 vµo c©y. Nót A kh«ng cã khãa 22 vµ ta tiÕp tôc t×m kiÕm trªn nót C. Nót C lµ nót l¸ cuèi cïng trªn ®−êng t×m kiÕm khãa 22, do vËy ta sÏ thùc hiÖn viÖc chÌn khãa 22 ë ®©y. 2. Tuy nhiªn nót C ®· ®Çy, do ®ã ta t¸ch nót C thµnh 2 nót vµ ta cã thªm nót míi lµ D. 3. 2*m+1 kho¸ ®−îc ph©n phèi ®Òu vµo 2 nót C vµ D, khãa ë gi÷a lµ khãa 30 ®−îc chuyÓn lªn nót cha. §ång thêi ta ®Æt mèi liªn kÕt tõ nót cha xuèng nót D. 4.2.5. Lo¹i bá khãa trªn B - c©y VÒ nguyªn t¾c, viÖc lo¹i bá nót trªn B-c©y hoµn toµn ®¬n gi¶n nh−ng phøc t¹p trong chi tiÕt thùc hiÖn. §Ó lo¹i bá mét khãa x, tr−íc hÕt ta t×m kiÕm trªn c©y ®Ó x¸c ®Þnh vÞ trÝ cña khãa x. ViÖc tiÕn hµnh lo¹i bá dÜ nhiªn chØ ®−îc thùc hiÖn khi thao t¸c t×m kiÕm cã kÕt qu¶. Cã 2 t×nh huèng sau: (1) PhÇn tö cÇn lo¹i bá ë nót l¸: viÖc lo¹i bá phÇn tö nµy ®−îc thùc hiÖn kh¸ dÔ dµng nh− lo¹i bá phÇn tö trªn danh s¸ch. (2) PhÇn tö cÇn lo¹i bá n»m ë nót trung gian. Lóc nµy ta kh«ng thÓ lo¹i bá trùc tiÕp phÇn tö trªn nót nµy, v× phÇn tö nµy cßn cã c¸c c©y con liªn quan. Ta ph¶i t×m mét phÇn tö kh¸c n»m ë nót l¸ lµm phÇn tö thay thÕ, nghÜa lµ gi¸ trÞ khãa cña phÇn tö thay thÕ sÏ ®−îc g¸n cho gi¸ trÞ khãa http://www.ebook.edu.vn 76 CÊu tróc d÷ liÖu2 – Ch−¬ng 4. B - c©y vµ bé nhí ngoµi cña phÇn tö cÇn xãa, sau ®ã phÇn tö thay thÕ ®−îc lo¹i bá khái nót l¸ chøa nã. Còng nh− trong tr−êng hîp c©y c©n b»ng, ta thÊy phÇn tö thay thÕ ph¶i lµ phÇn tö cùc ph¶i cña nh¸nh c©y con tr¸i hoÆc nót cùc tr¸i cña nh¸nh c©y con ph¶i cña phÇn tö cÇn xãa. Chóng ta sÏ quy −íc chän phÇn tö cÇn thay thÕ lµ phÇn tö cùc ph¶i trªn nh¸nh c©y con tr¸i. Gäi nót chøa khãa cÇn xãa lµ Z. Ta sÏ gÆp t×nh huèng ng−îc víi tr−êng hîp thªm khãa: khi xãa khãa ta cã thÓ lµm cho nót l¸ bÞ c¹n kiÖt (underflow), nghÜa lµ cã sè khãa Ýt h¬n møc tèi thiÓu. Lóc nµy ta chØ cã c¸ch gi¶i quyÕt lµ m−în mét khãa tõ nót l©n cËn. NÕu nót l©n cËn còng ®ang ë tr¹ng th¸i s¾p c¹n kiÖt, nghÜa lµ cã ®óng m khãa th× ta ph¶i ®−a c¸c khãa vµ c©y con cña nót Z vµo nót l©n cËn, sau ®ã xãa nót Z. DÜ nhiªn ®Ó xãa nót Z, ta ph¶i ®−a c¶ khãa t−¬ng øng cña nã trong nót cha vµo nót l©n cËn. Trong tr−êng hîp nµy nÕu nót cha s¾p c¹n kiÖt th× sÏ trë nªn c¹n kiÖt vµ cã thÓ ta ph¶i c©n b»ng l¹i nót cha b»ng c¸ch vay khãa cña nót l©n cËn nót cha hoÆc l¹i tiÕn hµnh ghÐp nèi. Qu¸ tr×nh nµy cã thÓ lan truyÒn tíi gèc vµ cã thÓ nót gèc cò bÞ lo¹i bá: c©y ®· thÊp xuèng. §©y chÝnh lµ c¸ch duy nhÊt ®Ó B-c©y gi¶m chiÒu cao. VÝ dô: Ta xÐt B c©y sau ®©y: A 32 B C 38 44 20 26 7 10 15 18 22 24 28 30 34 36 40 42 E F I J D 46 48 K H×nh 4.4. Xãa khãa 32 trªn B-c©y Gi¶ sö ta cÇn xãa khãa 32. Nót chøa khãa 32 kh«ng ph¶i nót l¸, v× vËy ta ph¶i t×m mét khãa thay thÕ. Theo quy −íc, nót cùc ph¶i trªn c©y con tr¸i cña khãa 32 lµ khãa 30. Ta ®−a gi¸ trÞ khãa 30 vÒ vÞ trÝ cña khãa 32 råi xãa khãa 30 trªn nót l¸ chøa nã vµ nhËn ®−îc c©y míi nh− sau: A 30 B C 38 44 20 26 7 10 15 18 22 24 D E 28 F 34 36 40 42 I J 46 48 K H×nh 4.5. B - c©y sau khi xãa khãa 32 Ta nhËn thÊy nót F ë trong t×nh tr¹ng c¹n kiÖt. Ta sÏ nèi nót F vµo nót E, ®ång thêi chuyÓn khãa 26 xuèng nót E råi xãa nót F. Ta ®−îc kÕt qu¶ sau A 30 B C 38 44 20 7 10 15 18 D 22 24 26 28 E F 34 36 40 42 I J http://www.ebook.edu.vn 46 48 K 77 CÊu tróc d÷ liÖu2 – Ch−¬ng 4. B - c©y vµ bé nhí ngoµi H×nh 4.6. C©n b»ng l¹i nót F B©y giê nót B l¹i trë thµnh c¹n kiÖt vµ ta ph¶i c©n b»ng l¹i b»ng c¸ch ghÐp víi nót C , ®ång thêi lÊy khãa cña nót gèc xuèng. Nót gèc vèn chØ cã mét khãa, sau khi lÊy khãa nµy ®i th× thµnh rçng. ta xãa nót gèc nµy vµ lÊy nót B lµm gèc míi. B 7 10 15 18 D 20 30 38 44 22 24 26 28 E F 34 36 40 42 I J 46 48 K H×nh 4.7. C©n b»ng l¹i nót B Nh− vËy viÖc xãa nót 32 ®· t¹o ra mét "ph¶n øng d©y chuyÒn". Ta ph¶i c©n b»ng l¹i tÊt c¶ c¸c nót tõ nót cã khãa thay thÕ cho ®Õn tËn nót gèc vµ kÕt qu¶ lµ c©y ®· bÞ thÊp xuèng. Tuy nhiªn trong thùc tÕ kh«ng ph¶i lóc nµo ta còng ph¶i c©n b»ng l¹i tÊt c¶ c¸c nót tõ nót l¸ (chøa khãa cÇn xo¸ hoÆc khãa thay thÕ) cho ®Õn nót gèc. Qu¸ tr×nh c©n b»ng ®−îc thùc hiÖn tõ nót l¸ trë vÒ gèc vµ dõng l¹i khi gÆp mét nót c©n b»ng. Tr−êng hîp ®¬n gi¶n nhÊt lµ nót l¸ cã nhiÒu h¬n M khãa. Khi ®ã sau khi xãa khãa trªn nót nµy th× nót vÉn c©n b»ng vµ ta kh«ng ph¶i c©n b»ng l¹i. 4.2.6. Ph©n tÝch c¸c thuËt to¸n trªn B - c©y C¸c thao t¸c t×m kiÕm hay chÌn trªn B-c©y cÊp M, tøc lµ sè khãa trªn mét nót trong kho¶ng tõ M ®Õn 2*M cã ®é phøc t¹p tÝnh to¸n kho¶ng O(logM n) trong ®ã n lµ sè nót cña c©y. 4.3. Cµi ®Æt B - c©y Chóng ta sÏ cµi ®Æt c©y B - c©y theo kiÓu liªn kÕt dïng biÕn ®éng. Sau ®©y chóng t«i gi¶i thÝch mét sè t¸c vô chÝnh cña ch−¬ng tr×nh. C¸c t¸c vô nµy kh«ng ®−îc liÖt kª l¹i trong ch−¬ng tr×nh mµ chØ cã dßng chó thÝch. Khi gâ ch−¬ng tr×nh ®Ó ch¹y thö b¹n ®äc cÇn gâ l¹i chi tiÕt. • Khai b¸o B - c©y Sau c¸c lÖnh #include ®Ó ®−a vµo c¸c tÖp header, c¸c lÖnh #define M 2 #define N 2*M #define N1 2*M+1 sÏ ®Þnh nghÜa cÊp vµ bËc cña c©y. M lµ cÊp cña c©y vµ lµ sè khãa tèi thiÓu mµ mét nót trªn c©y cÇn cã (trõ nót gèc). M ph¶i lµ h»ng sè v× ta sÏ dïng m¶ng tÜnh ®Ó khai b¸o c¸c khãa vµ c¸c nót trªn c©y. Trong ch−¬ng tr×nh ta ®Æt M = 2, tøc lµ c©y cÊp 2 hay c©y bËc 5, sè khãa tèi ®a cã thÓ cã trªn c©y lµ 4. B¹n ®äc cã thÓ ®Æt l¹i gi¸ trÞ M nÕu muèn ®Þnh nghÜa c©y cÊp cao h¬n. TiÕp theo lµ khai b¸o cÊu tróc cña mét nót th«ng tin trªn c©y. Mçi nót trªn c©y lµ mét cÊu tróc chøa c¸c tr−êng sau: - Tr−êng keynum : lµ sè khãa hiÖn cã trªn nót - Tr−êng key: lµ m¶ng chøa c¸c khãa cña nót. Thùc ra sè khãa tèi ®a lµ N = 2*M, nh− vËy chØ cÇn mét m¶ng cã N phÇn tö nguyªn lµ cã thÓ chøa ®−îc sè khãa cÇn thiÕt. Tuy nhiªn, nh− ta sÏ http://www.ebook.edu.vn 78 CÊu tróc d÷ liÖu2 – Ch−¬ng 4. B - c©y vµ bé nhí ngoµi thÊy trong phÇn sau cña ch−¬ng tr×nh, viÖc thªm mét vÞ trÝ cho m¶ng ®Ó chøa phÇn tö thªm vµo trong tr−êng hîp nót bÞ ®Çy sÏ lµm cho viÖc lËp tr×nh ®¬n gi¶n h¬n. Trong thùc tÕ øng dông b¹n ®äc cÇn c©n nh¾c xem viÖc thªm mét vÞ trÝ cho mçi nót cã ¶nh h−ëng ®Õn viÖc khai th¸c tµi nguyªn bé nhí kh«ng, vµ sÏ quyÕt ®Þnh chÊp nhËn thªm mét nót ®Ó viÖc lËp tr×nh ®¬n gi¶n h¬n hay triÖt ®Ó tiÕt kiÖm nguån tµi nguyªn vµ lËp tr×nh cã phøc t¹p h¬n chót Ýt. - Tr−êng son: lµ m¶ng c¸c con trá trá tíi ®Þa chØ c¸c c©y con cña nót. M¶ng nµy còng ®−îc thªm mét vÞ trÝ ®Ó viÖc lËp tr×nh ®¬n gi¶n h¬n. Nh− chóng t«i ®· m« t¶ trong phÇn tr−íc, viÖc c©n b»ng l¹i c©y cã thÓ ph¶i thùc hiÖn tõ vÞ trÝ thªm hoÆc xãa nót cho ®Õn gèc. Nh− vËy ta cÇn mét Stack ®Ó l−u l¹i ®Þa chØ c¸c nót tõ gèc cho ®Õn nót cã phÇn tö ®−îc thªm hoÆc lo¹i bá. C¸c phÇn tö cña Stack sÏ lµ mét cÊu tróc Snode gåm 2 thµnh phÇn: con trá chØ ®Õn c¸c nót trªn c©y vµ biÕn nguyªn k chØ nh¸nh c©y con cÇn ®i tiÕp trªn ®−êng tíi nót cã khãa cÇn thªm hoÆc lo¹i bá. #define M 2 // cap cua cay, tuc la so khoa it nhat cua mot nut #define N 2*M // So khoa toi da trong mot nut #define N1 2*M+1 // So con toi da trong mot nut, tuc la bac cua cay // Khai bao cau truc cua mot nut struct Node {int keynum; // so khoa cua mot nut int key[N+1]; //moi nut co nhieu nhat N khoa Node *son[N1+1]; //cac con tro chi cac nut con cua mot nut }; //Them 1 vi tri vao key[] va son[] de tien thao tac struct Snode {Node *pnode;int k;};//k la di tiep tren son[k]; #include "stack_h.cpp" class Btree {public: Node* proot; //A pointer to the root of the tree. long count; BTree(); ~BTree(); void Initialize(); int Empty(); void Clear(Node*&); Node* NewNode(); void Traverse(Node*); int NodeSearch(Node*&,int); Node* Search(Node*,int &,int); void Split(Node*&,Node*&,int); void Insert(int); void Merge(Node*&,Node*&,int); void Remove(int); }; http://www.ebook.edu.vn 79 CÊu tróc d÷ liÖu2 – Ch−¬ng 4. B - c©y vµ bé nhí ngoµi • T¸c vô t¸ch nót khi nót bÞ trµn T¸c vô nµy ®−îc gäi bëi t¸c vô insert. Khi mét nót p bÞ trµn, tøc lµ cã 2*M+1 khãa th× nã ®−îc t¸ch lµm 2 nót. C¸c khãa vµ c©y con kÌm theo tõ vÞ trÝ 0 ®Õn vÞ trÝ M-1 ®−îc gi÷ l¹i trong nót p. C¸c nót vµ c©y con kÌm theo tõ vÞ trÝ M+1 ®Õn 2*M ®−îc chuyÓn vµo nót míi p2. Sau ®ã nót míi p2 cïng víi khãa ë vÞ trÝ M ®−îc ®−a lªn nót cha ë vÞ trÝ thÝch hîp. VÞ trÝ nµy chÝnh lµ vÞ trÝ k nhËn ®−îc tõ Stack. void BTree::Split(Node* &p,Node* &fp, int k) {if(p->keynum<=N) return; int i; Node *p2=NewNode(); /*Tach nut p lam 2 phan: Tu vi tri 0->M-1 giu lai trong p, tu M+1 -> N chuyen sang p2 khoa p->key[M] chuyen len vi tri fp->key[k]; nut p2 duoc gan vao fp->son[k] Dich chuyen cac nhanh cay con va cac khoa ben phai vi tri k sang phai mot vi tri trong nut fp de lay vi tri fp->key[k] va fp->son[k] chen khoa va con moi*/ for(i=fp->keynum;i>k;i--) {fp->son[i+1]=fp->son[i]; fp->key[i] = fp->key[i-1]; } fp->keynum++; //Bat dau tach nut p; int newkey=p->key[M]; //copy tu vi tri khoa M+1 sang p2 for(i=0;i<M;i++) {p2->key[i]=p->key[M+i+1]; p2->son[i]=p->son[M+i+1]; } p2->son[M]=p->son[N1];//con cuoi cung p->keynum=p2->keynum=M; fp->key[k]=newkey; fp->son[k]=p; fp->son[k+1]=p2; } • T¸c vô t×m khãa x trªn nót p vµ tr¶ vÒ vÞ trÝ cña khãa x. NÕu kh«ng t×m thÊy th× tr¶ vÒ gi¸ trÞ k, vµ ta cã thÓ t×m khãa x trªn nh¸nh c©y p->son[k] /* Tac vu Nodesearch: tim trong nut vi tri cua khoa bat dau >= x. Truong hop x lon hon tat ca cac khoa trong nut thi tra ve vi tri p->keynum, tuc la vi tri sau khoa cuoi cung Input: Khoa x va con tro toi nut p Output: Vi tri i, sao cho son[i] se la nhanh cay tiep theo de tim x*/ http://www.ebook.edu.vn 80 CÊu tróc d÷ liÖu2 – Ch−¬ng 4. B - c©y vµ bé nhí ngoµi int BTree::NodeSearch(Node* &p, int x) {int i; for(i=0;i<p->keynum && p->key[i]<x; i++); return(i); //Neu co khoa key[i] thi ta co key[i-1] < x <= key[i] } • T¸c vô thªm khãa x vµo c©y T¸c vô nµy thªm mét nót cã khãa x vµo B - c©y vµ thùc hiÖn c¸c thao t¸c c©n b»ng l¹i c©y sao c©y vÉn lµ B - c©y. Input: B - c©y vµ khãa cÇn chÌn vµo c©y. Output: B - c©y trong ®ã ®· cã nót x. Qu¸ tr×nh thªm nót vµo c©y ®−îc tiÕn hµnh qua c¸c b−íc sau: B−íc 1: KiÓm tra nÕu c©y rçng th× t¹o nót gèc cã khãa x vµ kÕt thóc. B−íc 2: T¹o mét Stack ®Ó l−u l¹i c¸c nót ®i qua. §Æt fp = NULL, p = proot. B−íc 3: Dïng t¸c vô NodeSearch ®Ó x¸c ®Þnh xem khãa x cã trªn nót p kh«ng, nÕu cã th× th«ng b¸o lµ nót ®· cã, kh«ng thªm n÷a vµ kÕt thóc. C¨n cø vµo gi¸ trÞ k tr¶ vÒ cña hµm NodeSearch ta ®Æt fp = p ,p = p->son[k]. L−u fp vµ k vµo Stack råi chuyÓn sang b−íc 4. B−íc 4: NÕu p kh¸c NULL ta trë l¹i b−íc 3. NÕu nót p = NULL, ta lÊy phÇn tö tõ ®Ønh Stack ra. Thµnh phÇn con trá cña phÇn tö nµy chÝnh lµ nót fp cuèi cïng vµ gi¸ trÞ k lµ vÞ trÝ ta cã thÓ chÌn khãa x vµo. Sau khi chÌn khãa x vµo nót fp nÕu nót fp ch−a bÞ trµn (overflow) th× kÕt thóc. Ng−îc l¹i ta chuyÓn sang buíc 5. B−íc 5: NÕu fp bÞ trµn th× ta xÐt 2 tr−êng hîp: (a) NÕu Stack rçng, tøc lµ nót fp chÝnh lµ nót gèc th× ta t¸ch nót p thµnh 2 nót, mçi nót cã ®óng M khãa. T¹o nót gèc míi, ®−a khãa fp->key[M] lªn nót gèc míi nµy vµ kÕt thóc. (b) NÕu Stack kh«ng rçng, ta g¸n p = fp, råi thùc hiÖn t¸c vô Pop cña Stack ®Ó lÊy phÇn tö tõ trªn ®Ønh Stack, g¸n phÇn con trá cho fp. T¸ch nót p lµm 2 nót p vµ p2, chÌn khãa ë gi÷a p->key[M] vµo vÞ trÝ khãa thø k cña fp, vµ chÌn c©y p2 vµo vÞ trÝ fp>son[k+1]. ChuyÓn sang b−íc 6. B−íc 6: NÕu fp kh«ng bÞ trµn thi kÕt thóc. Ng−îc l¹i chuyÓn vÒ b−íc 5. DÔ thÊy r»ng thuËt to¸n trªn ®©y sÏ dõng sau h÷u h¹n b−íc /*Them khoa x vao cay: xuat phat tu goc di theo hanh trinh thich hop den nut la co the them x. Trong qua trinh den nut la dua vao Stack tu tao cac nut di qua de dung cho viec can doi lai sau nay. http://www.ebook.edu.vn 81 CÊu tróc d÷ liÖu2 – Ch−¬ng 4. B - c©y vµ bé nhí ngoµi */ void BTree::Insert(int x) {Node *p,*p1,*fp; int i,j,k; if(Empty()) {int i; proot = NewNode(); proot->keynum=1; proot->key[0]=x;//Nut goc co 1 khoa return; } //Bat dau tu goc, tim vi tri de chen x, tren duong di dua cac nut vao Stack Snode tmp; Stack<Snode> st(20); //Bat dau tu nut goc fp = NULL; p = proot; while(p != NULL) {k=NodeSearch(p,x); if(k<p->keynum && x==p->key[k]) // tim thay {cout<<endl<<"Nut da co khong them duoc";delay(100);return;} tmp.pnode=p;tmp.k=k; st.push(tmp); fp = p; p = p->son[k]; } //fp chinh la nut la co the chen x vao. tmp=st.pop(); fp=tmp.pnode;k=tmp.k; /*dich chuyen cac nhanh cay con va cac khoa ben phai vi tri k sang phai mot vi tri */ for(i=fp->keynum;i>k;i--) fp->key[i] = fp->key[i-1]; fp->key[k]=x; fp->keynum++; //Neu nut chua tran thi ket thuc if(fp->keynum<=N) return; if(st.empty()) //Nut p la nut goc {proot=NewNode(); Split(fp,proot,0); return; } http://www.ebook.edu.vn 82 CÊu tróc d÷ liÖu2 – Ch−¬ng 4. B - c©y vµ bé nhí ngoµi while(!st.empty()) {p=fp; tmp=st.pop(); fp=tmp.pnode;k=tmp.k; Split(p,fp,k);//Tach p1 lam 2 roi chen vao p if(fp->keynum<=N) return;//Nut p chua tran if(st.empty()) //Nut p la nut goc {proot=NewNode(); Split(fp,proot,0); return; } } } • T¸c vô c©n b»ng B - c©y khi xãa khãa. Khi ta xãa mét khãa trªn nót nµo ®ã th× cã thÓ nót ®ã trë thµnh c¹n kiÖt, ta ph¶i m−în khãa ë nót l©n cËn hoÆc nót cha, hoÆc hîp nhÊt víi nót kh¸c ®Ó nót trë nªn c©n b»ng (kh«ng c¹n kiÖt n÷a). T¸c vô sau ®©y thùc hiÖn viÖc c©n b»ng mét nót. Nh− vËy khi xãa mét khãa cã thÓ ta ph¶i gäi nhiÒu lÇn t¸c vô nµy ®Ó c©n b»ng l¹i c¸c nót tõ vÞ trÝ khãa bÞ xãa vÒ ®Õn nót gèc. Input: Nót con p, nót cha fp mµ fp->son[k]=p. Nót p bÞ c¹n kiÖt. Output: Nót p ®· trë nªn c©n b»ng, nh−ng nót fp cã thÓ bÞ c¹n kiÖt. /*Gia su nut p bi thieu 1 phan tu, tuc la keynum=M-1 tac vu nay duoc goi boi tac vu Remove. Neu nut anh em lan can cua p co so nut nhieu hon M ta se muon 1 nut sang p, di nhien la ta phai so sanh voi khoa tren nut cha sao cho hop ly */ void BTree::Merge(Node* &p,Node* &fp, int k) {if(p->keynum>=M) return; /*De don gian, neu anh em trai pl cua p khac rong thi ta xet pl, fp->key[k-1] va p. */ Node *pl,*pr;int i,j; if(k>0) {pl= fp->son[k-1]; if(pl->keynum>M) //pl co nhieu hon M khoa {for(i=p->keynum;i>0;i--) {p->son[i+1]=p->son[i]; p->key[i] = p->key[i-1]; }; //Don cac phan tu key[0],son[1],key[1],son[2],... ra phia sau p->son[1]=p->son[0];//Don son[0] sang son[1] p->key[0]=fp->key[k-1]; p->son[0]=pl->son[pl->keynum]; fp->key[k-1]=pl->key[pl->keynum-1]; http://www.ebook.edu.vn 83 CÊu tróc d÷ liÖu2 – Ch−¬ng 4. B - c©y vµ bé nhí ngoµi pl->keynum--; p->keynum++; return; }; //pl->keynum<=M, tron pl, fp->key[k-1] va p, xoa p roi don dep fp pl->key[pl->keynum]=fp->key[k-1]; for(i=0;i<p->keynum;i++) {pl->key[pl->keynum+i+1]=p->key[i]; pl->son[pl->keynum+i+1]=p->son[i]; }; pl->son[pl->keynum+p->keynum+1]=p->son[p->keynum]; for(i=k-1;i<fp->keynum-1;i++) {fp->key[i]=fp->key[i+1]; fp->son[i+1]=fp->son[i+2]; }; fp->keynum--; pl->keynum=pl->keynum+p->keynum+1; delete p; return; };//if(k>0) //if(k==0) Ta tron fp->son[k] voi fp->son[k+1] pr= fp->son[k+1]; if(pr->keynum>M) //pr co nhieu hon M khoa {p->key[M-1]=fp->key[k]; p->son[M]=pr->son[0]; fp->key[k]=pr->key[0]; for(i=0;i<pr->keynum-1;i++) {pr->son[i]=pr->son[i+1]; pr->key[i] = pr->key[i+1]; } pr->son[pr->keynum-1]=pr->son[pr->keynum]; p->keynum++; pr->keynum--; return; }; //pr->keynum<=M, tron p, fp->key[k] va pr, xoa pr roi don dep fp p->key[p->keynum]=fp->key[k]; for(i=0;i<pr->keynum;i++) {p->key[p->keynum+i+1]=pr->key[i]; p->son[p->keynum+i+1]=pr->son[i]; } p->son[p->keynum+pr->keynum+1]=pr->son[pr->keynum]; for(i=k;i<fp->keynum-1;i++) http://www.ebook.edu.vn 84 CÊu tróc d÷ liÖu2 – Ch−¬ng 4. B - c©y vµ bé nhí ngoµi {fp->key[i]=fp->key[i+1]; fp->son[i+1]=fp->son[i+2]; } fp->keynum--; p->keynum=p->keynum+pr->keynum+1; delete pr; return; //end of if(k==0) } • T¸c vô xãa khãa x trªn B - c©y T¸c vô nµy xãa nót cã khãa x trªn B - c©y vµ thùc hiÖn c¸c thao t¸c c©n b»ng l¹i c©y sao cho c©y vÉn lµ B - c©y. Input: B - c©y vµ khãa x cÇn xãa. Output: B - c©y trong ®ã ®· lo¹i bá khãa x. Qu¸ tr×nh xãa nót trªn c©y ®−îc tiÕn hµnh qua c¸c b−íc sau: B−íc 1: T¹o mét Stack ®Ó l−u l¹i c¸c nót ®i qua. §Æt fp = NULL, p = proot. B−íc 2: NÕu nót p = NULL th× th«ng b¸o kh«ng cã khãa x vµ kÕt thóc. NÕu p kh¸c NULL th× dïng t¸c vô NodeSearch ®Ó x¸c ®Þnh xem khãa x cã trªn nót p kh«ng. Dï t×m thÊy hay kh«ng t×m thÊy khãa x th× vÉn ®−a vµo Stack nót p cïng gi¸ trÞ k. B−íc 3: NÕu kh«ng t×m thÊy khãa x trªn p th× ®Æt fp = p; p = p->son[k] vµ quay l¹i b−íc 2. NÕu t×m thÊy khãa x chuyÓn sang b−íc 4. B−íc 4: NÕu nót p lµ nót l¸, ta lo¹i bá khãa x trªn nã råi chuyÓn sang b−íc 5. NÕu p kh«ng ph¶i lµ nót l¸ th× ta ®Æt fp = p. p = p->son[k], råi t×m vÞ trÝ khãa cùc ph¶i trªn c©y p. Trªn ®−êng ®i ta tiÕp tôc ®−a vµo Stack fp vµ gi¸ trÞ k. Khi t×m ®−îc khãa cùc ph¶i, ta ®−a gi¸ trÞ khãa nµy vÒ vÞ trÝ khãa x, råi lo¹i bá khãa cùc ph¶i. B−íc 5: B¾t ®Çu c©n b»ng l¹i c¸c nót tõ nót cã khãa bÞ lo¹i bá trë vÒ gèc. Qu¸ tr×nh c©n b»ng sÏ dõng l¹i khi ta gÆp nót c©n b»ng. B¾t ®Çu lÊy ®Þa chØ c¸c nót tõ ®Ønh Stack, nÕu ta thÊy nót võa lÊy ra c©n b»ng th× kÕt thóc thuËt to¸n. NÕu nót nµy bÞ c¹n kiÖt th× ta cÇn c©n b»ng l¹i. Ta ph©n biÖt 2 tr−êng hîp sau: (a) NÕu Stack rçng, tøc lµ nót fp chÝnh lµ nót gèc th× ta l¹i xÐt 2 tr−êng hîp: NÕu fp ch−a bÞ rçng th× kÕt thóc, v× nót gèc cã thÓ chøa Ýt h¬n M khãa. NÕu fp rçng tøc lµ kh«ng cã khãa nµo th× ta lo¹i bá nót nµy vµ ®Æt proot = p, trong ®ã p lµ con cña fp (b) NÕu Stack kh«ng rçng, ta g¸n p = fp, råi thùc hiÖn t¸c vô Pop cña Stack ®Ó lÊy phÇn tö tõ trªn ®Ønh Stack, g¸n phÇn con trá cho fp. Thùc hiÖn t¸c vô Merge(p,fp,k) ®Ó c©n b»ng l¹i nót p nhê vµo c¸c nót l©n cËn vµ nót cha fp. Sau t¸c vô nµy p trë nªn c©n b»ng nh−ng fp l¹i cã thÓ bÞ c¹n kiÖt vµ ta l¹i ph¶i c©n b»ng l¹i fp. Qu¸ tr×nh nµy ®−îc lÆp l¹i cho ®Õn khi gÆp nót c©n b»ng hoÆc Stack rçng. http://www.ebook.edu.vn 85 CÊu tróc d÷ liÖu2 – Ch−¬ng 4. B - c©y vµ bé nhí ngoµi DÔ thÊy r»ng thuËt to¸n trªn ®©y sÏ dõng sau h÷u h¹n b−íc /*Xoa khoa x tren cay*/ void BTree::Remove(int x) {Node *p,*fp; int i,j,k; /*Bat dau tu goc, tim vi tri co khoa x, tren duong di dua cac nut vao Stack*/ Snode tmp; Stack<Snode> st(20); //Bat dau tu nut goc fp = NULL; p = proot; while(p != NULL) {k=NodeSearch(p,x); tmp.pnode=p;tmp.k=k; st.push(tmp); if(k<p->keynum && x==p->key[k]) break; // tim thay fp = p; p = p->son[k]; } if(p==NULL) {cout<<endl<<"Khong tim thay nut "<<x;delay(500);return;} int IsLeaf; if(p->son[0]==NULL) IsLeaf=true; else IsLeaf=false; if(IsLeaf)//La nut la, xoa khoa thu k {for(i=k;i<p->keynum-1;i++) p->key[i]=p->key[i+1]; p->keynum--; } if(!IsLeaf) //Tim nut cuc phai tren nhanh cay con trai {Node *pp=p; fp=p; p=p->son[k]; while(p!=NULL) {tmp.pnode=p;tmp.k=p->keynum; st.push(tmp); fp=p; p=p->son[p->keynum]; } //fp la nut la, nut cuc phai se thay x pp->key[k]=fp->key[fp->keynum-1]; http://www.ebook.edu.vn 86 CÊu tróc d÷ liÖu2 – Ch−¬ng 4. B - c©y vµ bé nhí ngoµi fp->keynum--; } //Bat dau qua trinh hieu chinh lai cay. tmp=st.pop(); fp=tmp.pnode;k=tmp.k; if(fp->keynum>=M) return;//Nut chua tran if(fp==proot) //Cay chi co mot nut goc {if(fp->keynum==0) {delete proot;proot=NULL;}; return; }; while(!st.empty()) {p=fp; tmp=st.pop(); fp=tmp.pnode;k=tmp.k; Merge(p,fp,k);//Dieu chinh p de noi vao fp if(fp->keynum>=M) return;//Nut chua tran if(fp==proot)//Neu nut goc tro thanh rong thi xoa nut goc {if(fp->keynum==0) {delete proot;proot=p;return;}; return; }; }; }; 4.4. B - c©y vµ bé nhí ngoµi Do mçi nót trªn B-c©y chøa ®−îc nhiÒu khãa nªn cÊu tróc d÷ liÖu nµy rÊt thÝch hîp cho viÖc cµi ®Æt trªn bé nhí ngoµi. Chóng ta cã thÓ cµi ®Æt trùc tiÕp B-c©y trªn bé nhí ngoµi b»ng mét sè c¸ch nh− sau: C¸ch 1: - Dïng mét sè byte ®Çu tiªn trªn tÖp ®Ó chøa vÞ trÝ cña nót gèc. - C¸c nót cña c©y sÏ cã cÊu tróc lµ: struct Node {int keynum; // so khoa cua mot nut int key[N+1]; //moi nut co nhieu nhat N khoa long son[N1+1]; //cac so nguyen chi vi tri cac nut con cua mot nut }; M¶ng son[N1+1] sÏ chøa vÞ trÝ trªn tÖp cña c¸c nót con cña mét nót. Cã thÓ söa ®æi ch−¬ng tr×nh 41BCAY.CPP cho tr−êng hîp nµy b»ng c¸ch khai b¸o thªm hµm Node GetNode(int n) ®Ó truy xuÊt ®Õn mét nót ë vÞ trÝ n trªn tÖp. Chóng t«i dµnh c«ng viÖc nµy cho nh÷ng sinh viªn häc lùc kh¸. C¸ch 2: C¸c nót chøa th«ng tin lu«n ®−îc l−u tr÷ trªn tÖp, mçi lÇn nhËp mét nót míi ta l¹i nhËp vµo cuèi tÖp. Trong bé nhí ta t¹o ra mét cÊu tróc d÷ liÖu B-c©y. Tuy nhiªn c¸c nót trong cÊu tróc d÷ liÖu kh«ng chøa th«ng tin vÒ d÷ liÖu hoÆc c¸c khãa mµ chØ chøa vÞ trÝ cña c¸c nót trªn tÖp. Mçi lÇn nhËp míi mét nót ta nhËp vµo cuèi tÖp, ®ång thêi cËp nhËt th«ng tin vµo cÊu tróc d÷ liÖu trong http://www.ebook.edu.vn 87 CÊu tróc d÷ liÖu2 – Ch−¬ng 4. B - c©y vµ bé nhí ngoµi bé nhí, tøc lµ chÌn nót míi, nót míi nµy cã mét tr−êng chØ vÞ trÝ cña b¶n ghi míi trªn tÖp. Khi xãa mét b¶n ghi nµo ®ã ta xãa trªn cÊu tróc trong bé nhí, tuy nhiªn b¶n ghi t−¬ng øng trªn tÖp th× vÉn cßn. Ch−¬ng tr×nh sÏ cã mét chøc n¨ng dän dÑp: khi ch¹y chøc n¨ng nµy ta ®äc vµ ghi sang tÖp míi c¸c b¶n ghi trªn tÖp mµ cã nót t−¬ng øng trªn cÊu tróc d÷ liÖu, sau ®ã xãa tªn tÖp cò vµ ®æi l¹i tªn tÖp míi thµnh tªn tÖp cò. http://www.ebook.edu.vn 88 C©u hái vµ bµi tËp Ch−¬ng 1. S¾p xÕp ngo¹i 1.1. Cho tÖp A chøa c¸c phÇn tö lµ c¸c sè thùc nh− sau: 2 5 22 20 18 16 6 7 15 14 13 4 a) H·y m« t¶ qu¸ tr×nh s¾p xÕp trén ®é dµi cè ®Þnh (trén trùc tiÕp). b) H·y m« t¶ qu¸ tr×nh s¾p xÕp trén run tù nhiªn. c) H·y m« t¶ qu¸ tr×nh s¾p xÕp trén ®a lèi c©n b»ng víi sè ®−êng c©n b»ng m = 3. d) So s¸nh c¸c ph−¬ng ph¸p s¾p xÕp trªn. 1.2. Cho tÖp A chøa c¸c phÇn tö lµ c¸c sè thùc nh− sau: 2 4 6 1 60 55 50 45 40 35 30 38 34 32 30 20 H·y thùc hiÖn c¸c c©u hái a, b, c, d trong c©u 1.1. ®èi víi tÖp A nµy. 1.3. Cµi ®Æt vµ ch¹y c¸c ch−¬ng tr×nh thùc hiÖn c¸c ph−¬ng ph¸p s¾p xÕp trén: trùc tiÕp, tù nhiªn vµ ®a lèi c©n b»ng. 1.4. Copy ch−¬ng tr×nh mÉu vµo m¸y (hoÆc ch−¬ng tr×nh b¹n tù viÕt). Sau ®ã xãa hµm SplitFile() vµ viÕt l¹i mµ kh«ng dïng tµi liÖu (c¸c ch−¬ng tr×nh trén trùc tiÕp, trén tù nhiªn vµ trén ®a lèi c©n b»ng). 1.5. Copy ch−¬ng tr×nh mÉu vµo m¸y (hoÆc ch−¬ng tr×nh b¹n tù viÕt). Sau ®ã xãa hµm MergeFile() vµ viÕt l¹i mµ kh«ng dïng tµi liÖu (c¸c ch−¬ng tr×nh trén trùc tiÕp, trén tù nhiªn vµ trén ®a lèi c©n b»ng). 1.6. Copy ch−¬ng tr×nh mÉu vµo m¸y (hoÆc ch−¬ng tr×nh b¹n tù viÕt). Sau ®ã xãa hµm SortFile() vµ viÕt l¹i mµ kh«ng dïng tµi liÖu (c¸c ch−¬ng tr×nh trén trùc tiÕp, trén tù nhiªn vµ trén ®a lèi c©n b»ng). 1.7.* Thö cµi ®Æt ch−¬ng tr×nh b»ng c¸ch kh¸c víi tµi liÖu, vÝ dô kh«ng dïng hµm EoR() vµ khi ®äc c¸c phÇn tö trªn tÖp chØ tiÕn lªn chø kh«ng lïi l¹i. 1.8.* H·y sö dông ch−¬ng tr×nh cµi ®Æt cho tr−êng hîp c¸c phÇn tö trªn tÖp lµ c¸c cÊu tróc, vÝ dô struct node {Char HoTen[20], int Tuoi;}; Ch−¬ng 2. B¶ng b¨m 2.1. Tr×nh bµy cÊu tróc d÷ liÖu b¶ng b¨m. V× sao vµ trong tr−êng hîp nµo ng−êi ta cÇn ®Õn cÊu tróc b¶ng b¨m? 2.2. Hµm b¨m lµ g×? H·y nªu nh÷ng ®Æc ®iÓm cña hµm b¨m chia d− %. 2.3. Cã nh÷ng biÖn ph¸p nµo ®Ó tr¸nh ®ông ®é khi sö dông b¶ng b¨m? 2.4. H·y x©y dùng mét vµi hµm b¨m khi tËp khãa lµ chuçi ký tù, b¶ng b¨m cã m thµnh phÇn T = (a0, a1,... am-1). 2.5. Ch¹y thö ch−¬ng tr×nh cµi ®Æt b¶ng b¨m dïng liªn kÕt ngoµi trong tµi liÖu ®Ó hiÓu râ c¸c t¸c vô. 2.6. Cµi ®Æt b¶ng b¨m dïng liªn kÕt trong. 2.7. H·y xãa c¸c t¸c vô search() vµ insert() trong ch−¬ng tr×nh mÉu hoÆc ch−¬ng tr×nh tù viÕt råi viÕt l¹i mµ kh«ng dïng tµi liÖu. 2.8. Cho d·y A chøa c¸c khãa (key) lµ c¸c sè thùc nh− sau: 2 5 22 20 18 16 6 7 15 14 13 4 Gi¶ sö hµm b¨m lµ h(key) = key % m víi m = 7, vµ ph−¬ng ph¸p tr¸nh ®ông ®é lµ dïng danh s¸ch liªn kÕt. H·y m« t¶ qu¸ tr×nh lÇn l−ît chÌn c¸c phÇn tö trªn b»ng h×nh vÏ (c¸c h×nh ch÷ nhËt cã c¸c khãa bªn trong biÓu diÔn c¸c phÇn tö, ký hiÖu → chØ mèi liªn kÕt (xem h×nh 2.1). http://www.ebook.edu.vn CÊu tróc d÷ liÖu2 – C©u hái vµ bµi tËp 2.9. Cho d·y A chøa c¸c khãa (key) lµ c¸c sè thùc nh− sau: 2 5 220 205 18 16 6 7 15 14 13 4 Gi¶ sö b¶ng b¨m H cã 20 « ®−îc ®¸nh sè tõ 0 - 19. H·y m« t¶ c¸ch ®−a c¸c khãa trong d·y A vµo b¶ng b¨m b»ng ph−¬ng ph¸p dß tuyÕn tÝnh. 2.10. Cµi ®Æt b¶ng b¨m víi ph−¬ng ph¸p dß tuyÕn tÝnh. 2.11.*Cµi ®Æt b¶ng b¨m víi ph−¬ng ph¸p dß bËc 2. Ch−¬ng 3. C©y ®á ®en 3.1. Cho d·y A chøa c¸c khãa (key) lµ c¸c sè thùc nh− sau: 2 5 22 20 18 16 6 7 H·y t¹o vµ vÏ c©y 2-3-4 chøa c¸c nót trªn sau ®ã t¹o c©y ®á ®en t−¬ng øng. 3.2. Gi¶ sö ®· t¹o ®−îc c©y 2-3-4 nh− ë bµi 3.1. H·y m« t¶ th«ng qua h×nh vÏ vµ lêi gi¶i thÝch thao t¸c thªm vµo c¸c nót 15, 27, 31. 3.3. Gi¶ sö ®· t¹o ®−îc c©y 2-3-4 nh− ë bµi 3.1 vµ ®· thªm vµo c¸c nót 15, 27, 31 H·y m« t¶ th«ng qua h×nh vÏ vµ lêi gi¶i thÝch thao t¸c xãa c¸c nót 18, 15. 3.4. Gi¶ sö sè khãa lµ n. H·y lËp luËn ®Ó ®−a ra −íc l−îng cña c©y 2-3-4 thÊp nhÊt vµ c©y cao nhÊt chøa n khãa. 3.5. Gi¶ sö sè khãa lµ n. H·y lËp luËn ®Ó ®−a ra −íc l−îng cña c©y AVL cao nhÊt chøa n khãa. 3.6. Ch¹y thö ch−¬ng tr×nh mÉu cµi ®Æt c©y nhÞ ph©n AVL. 3.8. Gi¶i thÝch c¸c chøc n¨ng quay nót, t×m kiÕm, thªm nót, xãa nót trong ch−¬ng tr×nh cµi ®Æt c©y nhÞ ph©n AVL. 3.9. Thö xãa mét vµi chøc n¨ng vµ viÕt l¹i mµ kh«ng cÇn xem tµi liÖu. 3.10.*Thö cµi ®Æt c©y AVL víi cÊu tróc cña nót phøc t¹p h¬n vÝ dô ®ã lµ cÊu tróc chøa th«ng tin vÒ nh©n sù nh− hä tªn, ngµy sinh, l−¬ng. Khãa lµ l−¬ng ch¼ng h¹n. Ch−¬ng 4. B-c©y 4.1. Cho d·y A chøa c¸c khãa (key) lµ c¸c sè thùc nh− sau: 2 5 22 20 18 16 6 7 H·y t¹o vµ vÏ B-c©y cÊp 2 chøa c¸c nót trªn. 4.2. Gi¶ sö ®· t¹o ®−îc B-c©y nh− ë bµi 4.1. H·y m« t¶ th«ng qua h×nh vÏ vµ lêi gi¶i thÝch thao t¸c thªm vµo c¸c nót 15, 27, 31. 4.3. Gi¶ sö ®· t¹o ®−îc B-c©y nh− ë bµi 3.1 vµ ®· thªm vµo c¸c nót 15, 27, 31 H·y m« t¶ th«ng qua h×nh vÏ vµ lêi gi¶i thÝch thao t¸c xãa c¸c nót 18, 15. 4.4. H·y lËp luËn ®Ó ®−a ra −íc l−îng cña B-c©y thÊp nhÊt vµ cao nhÊt chøa n khãa. 4.5. Ch¹y thö ch−¬ng tr×nh mÉu cµi ®Æt B-c©y cÊp M. 4.6. Gi¶i thÝch c¸c chøc n¨ng t×m kiÕm, thªm nót, xãa nót trong ch−¬ng tr×nh cµi ®Æt B-c©y cÊp M. 4.7. Thö xãa mét vµi chøc n¨ng vµ viÕt l¹i mµ kh«ng cÇn xem tµi liÖu. 4.8.*Thö cµi ®Æt B-c©y víi cÊu tróc cña nót phøc t¹p h¬n vÝ dô ®ã lµ cÊu tróc chøa th«ng tin vÒ nh©n sù nh− hä tªn, ngµy sinh, l−¬ng. Khãa lµ l−¬ng ch¼ng h¹n. C¸c bµi tËp lín dµnh cho sinh viªn kh¸ giái Sau khi ®· thùc hµnh c¸c bµi tËp nhá, sinh viªn cã thÓ thùc hiÖn bµi tËp lín sau ®©y ®Ó rÌn luyªn thªm kü n¨ng. PhÇn nµy kh«ng b¾t buéc, nh−ng nÕu sinh viªn nµo lµm ®−îc chóng t«i sÏ cã hÖ sè ®iÓm −u tiªn, vÝ dô ®iÓm thi ®−îc cäng thªm ®iÓm ch¼ng h¹n (nÕu quy chÕ cho phÐp) http://www.ebook.edu.vn 90 CÊu tróc d÷ liÖu2 – C©u hái vµ bµi tËp Môc ®Ých cña c¸c bµi tËp lµ rÌn luyÖn kü n¨ng ¸p dông bµi häc vµo thùc tÕ b»ng c¸ch vËn dông c¸c cÊu tróc d÷ liÖu ®· häc ®Ó viÕt ch−¬ng tr×nh thùc hiÖn c¸c thao t¸c trªn c¸c cÊu tróc d÷ liÖu nh− b¶ng b¨m, c©y AVL, B - c©y. Bµi tËp 1. ViÕt ch−¬ng tr×nh tudien.cpp, ch−¬ng tr×nh cã cµi ®Æt b¶ng b¨m T = (a0, a1,... ,a25), trong ®ã c¸c thµnh phÇn cña ai chøa ®Þa chØ ®Çu cña c¸c danh s¸ch liªn kÕt. Mçi nót cña danh s¸ch chøa c¸c tr−êng sau: ƒ Tr−êng word lµ khãa chøa mét tõ tiÕng Anh. ƒ Tr−êng mean lµ nghÜa tiÕng ViÖt. ƒ Tr−êng next lµ con trá chØ nót kÕ cã cïng gi¸ trÞ hµm b¨m bÞ xung ®ét. TËp khãa lµ c¸c tõ tiÕng Anh. Hµm b¨m ®−îc chän lµ thø tù cña ký tù ®Çu tiªn trong b¶ng ch÷ c¸i. Nh− vËy ký tù a ®−îc b¨m vµo 0, b b¨m vµo 1,..., z b¨m vµo 25. Ch−¬ng tr×nh cã c¸c chøc n¨ng sau: ƒ NhËp mét tõ míi. ƒ Xem tõ ®iÓn theo ký tù ®Çu. ƒ Tra tõ ®iÓn. ƒ Xãa mét tõ. Bµi tËp 2. Bµi to¸n qu¶n lý nh©n sù: (ë ®©y chóng t«i h¹n chÕ sè tr−êng tèi thiÓu ®Ó rÌn luyÖn kü n¨ng, trong thùc tÕ cÊu tróc c¸c tr−êng phøc t¹p h¬n nhiÒu) Chóng ta dïng cÊu tróc sau ®Ó qu¶n lý c¸c th«ng tin vÒ mçi nh©n viªn: struct fnode {long manv; char ten[25]; int luong;int phucap, int thunhap;} H·y sö dông c¸c cÊu tróc d÷ liÖu ®· häc nh− b¶ng b¨m, c©y AVL, B-c©y ®Ó viÕt ch−¬ng tr×nh qu¶n lý nh©n sù víi c¸c chøc n¨ng sau: 1. Khëi t¹o hÖ thèng 2. NhËp c¸c nh©n viªn míi. 3. T×m vµ cho hiÖn nh©n viªn biÕt m· nh©n viªn. 4. T×m vµ cho hiÖn nh©n viªn biÕt tªn vµ thu nhËp. 5. Xãa nh©n viªn biÕt m· sè. 6. HiÖn danh s¸ch nh©n viªn theo ®iÖn tho¹i m· sè. 7. HiÖn danh s¸ch nh©n viªn theo l−¬ng t¨ng dÇn. 8. Dän dÑp sè liÖu. 9. CÊt sè liÖu vµ tho¸t. NÕu d÷ liÖu l−u trªn ®Üa th× chó ý c¸c ®iÓm sau: Khi ch¹y môc khëi t¹o hÖ thèng nÕu tÖp sè liÖu ®· tån t¹i trªn ®Üa, m¸y sÏ hái xem cã t¹o míi kh«ng. NÕu tr¶ lêi cã, th× tÖp míi ®−îc t¹o ra. http://www.ebook.edu.vn 91 CÊu tróc d÷ liÖu2 – Phô lôc. C¸c ch−¬ng tr×nh C++ cµi ®Æt c¸c thuËt to¸n CTDL 2 Tµi liÖu tham kh¶o 1. Alistair Mc Monnies & W. Stewart Mc. Sporran, Gi¸o tr×nh cÊu tróc d÷ liÖu b»ng ng«n ng÷ C, Nhµ xuÊt b¶n thèng kª, 1999 2. Donald E.Knuth, The Art of Computer Programming - Volume 1, Volume 3, Addison Wesley Longman, Inc. Second printing, May 1998. 3. §inh M¹nh T−êng, CÊu tróc d÷ liÖu vµ gi¶i thuËt, NXB KH&KT, 2000 4. §ç Xu©n L«i, CÊu tróc d÷ liÖu vµ Gi¶i thuËt, NXB KH&KT, 1998 5. §ç §øc Gi¸o, C¬ së to¸n trong lËp tr×nh, NXB KH&KT, 1998 6. Hoµng KiÕm, Gi¶i mét bµi to¸n trªn m¸y tÝnh nh− thÕ nµo, tËp mét, NXB GD, 2000 7. Kenneth H. Rosen, To¸n häc rêi r¹c øng dông trong tin häc, NXB KH&KT, 2000 8. NguyÔn §øc NghÜa, NguyÔn T« Thµnh, To¸n rêi r¹c, NXB GD, 1999 9. NguyÔn Hång Ch−¬ng, CÊu tróc d÷ liÖu, øng dông vµ cµi ®Æt b»ng C, NXB TPHCM, 2000 10. NguyÔn Trung Trùc, CÊu tróc d÷ liÖu, §¹i häc B¸ch khoa TPHCM, 1997 11. NguyÔn Xu©n Huy, ThuËt to¸n, Nhµ xuÊt b¶n Thèng kª, 1988 12. Robert Sedgewick, CÈm nang thuËt to¸n, NXB KH&KT,1998 http://www.ebook.edu.vn 92 C¸c c©u hái lý thuyÕt vµ c¸c bµi thùc hµnh chuÈn bÞ cho thi hÕt m«n A. PhÇn lý thuyÕt Ch−¬ng 1. S¾p xÕp ngo¹i 1.1. S¾p xÕp ngo¹i lµ g×? H·y nªu sù kh¸c biÖt gi÷a s¾p xÕp néi vµ s¾p xÕp ngo¹i? 1.2. VÒ nguyªn t¾c, cã ph¶i tÊt c¶ c¸c ph−¬ng ph¸p s¾p xÕp néi ®Òu cã thÓ ¸p dông cho s¾p xÕp ngo¹i ®−îc kh«ng? 1.3. Trong c¸c ph−¬ng ph¸p s¾p xÕp néi mµ b¹n ®· biÕt, ph−¬ng ph¸p nµo tá ra thÝch hîp cho viÖc s¾p xÕp ngo¹i, ®Æc biÖt lµ ®èi víi c¸c ph−¬ng tiÖn l−u tr÷ tuÇn tù nh− b¨ng tõ? 1.4. a. H·y m« t¶ thuËt to¸n s¾p xÕp mét tÖp A cã n phÇn tö b»ng ph−¬ng ph¸p trén trùc tiÕp (®é dµi run cè ®Þnh) sö dông hai tÖp trung gian lµ B vµ C. b. Gi¶ sö tÖp A chøa d·y gåm 9 sè nguyªn cã gi¸ trÞ trong kho¶ng tõ 1 ®Õn 100 (c¸c sè nµy do b¹n tù nhËp vµo). H·y m« t¶ qu¸ tr×nh s¾p xÕp tÖp A theo thuËt to¸n trªn. 1.5. a. H·y m« t¶ thuËt to¸n s¾p xÕp mét tÖp A b»ng ph−¬ng ph¸p trén tù nhiªn sö dông hai tÖp trung gian lµ B vµ C. b. Gi¶ sö tÖp A chøa d·y gåm 11 sè nguyªn cã gi¸ trÞ trong kho¶ng tõ 1 ®Õn 100, trong ®ã c¸c run trªn A cã ®é dµi kh«ng qu¸ 3 (c¸c sè nµy do b¹n tù nhËp vµo). H·y m« t¶ qu¸ tr×nh s¾p xÕp tÖp A theo thuËt to¸n trªn. 1.6. a. H·y m« t¶ thuËt to¸n s¾p xÕp mét tÖp A b»ng ph−¬ng ph¸p trén ®a lèi c©n b»ng trong tr−êng hîp sè ®−êng c©n b»ng lµ m, c¸c tÖp nguån ban ®Çu lµ F0, F1, ..., Fm-1 vµ c¸c tÖp ®Ých ban ®Çu lµ G0, G1, ..., Gm-1. b. Gi¶ sö tÖp A chøa d·y gåm 11 sè nguyªn cã gi¸ trÞ trong kho¶ng tõ 1 ®Õn 100, trong ®ã c¸c run trªn A cã ®é dµi kh«ng qu¸ 3 (c¸c sè nµy do b¹n tù nhËp vµo). H·y m« t¶ qu¸ tr×nh s¾p xÕp tÖp A theo thuËt to¸n trªn cho tr−êng hîp sè ®−êng c©n b»ng m = 2. 1.7. H·y so s¸nh c¸c ph−¬ng ph¸p s¾p xÕp trªn ®©y. 1.8.* H·y m« t¶ v¾n t¾t ph−¬ng ph¸p trén ®a pha vµ nªu lªn nh÷ng −u ®iÓm vµ nh−îc ®iÓm cña ph−¬ng ph¸p nµy so víi c¸c ph−¬ng ph¸p trªn. Ch−¬ng 2. B¶ng b¨m 2.1. H·y nªu ra nh÷ng lËp luËn mµ ng−êi ta sö dông khi ®−a ra cÊu tróc d÷ liÖu b¶ng b¨m. 2.2. B¶ng b¨m (hash table) lµ g×? 2.2. Hµm b¨m (hash funcion) lµ g×? 2.3. VÊn ®Ò ®ông ®é trong b¶ng b¨m lµ g× vµ ng−êi ta ®· gi¶i quyÕt nh− thÕ nµo? 2.4. a. H·y m« t¶ ph−¬ng ph¸p tr¸nh ®ông ®é b»ng c¸ch dïng danh s¸ch liªn kÕt ngoµi: B¶ng b¨m lµ mét m¶ng gåm m thµnh phÇn H = (a0, a1,... am-1), trong ®ã ai i = 0,1,...,m-1, lµ ®Þa chØ phÇn tö ®Çu cña danh s¸ch liªn kÕt t−¬ng øng víi vÞ trÝ i. C¸c khãa lµ c¸c sè nguyªn k vµ hµm b¨m lµ hµm lÊy gi¸ trÞ phÇn d− khi chia k cho m, tøc lµ h(k)=k%m. (Ta sÏ gäi b¶ng b¨m sö dông hµm b¨m nh− thÕ nµy lµ b¶ng b¨m chia d−). b. Cho b¶ng b¨m chia d− víi m = 5 vµ ph−¬ng ph¸p tr¸nh ®ông ®é lµ dïng danh s¸ch liªn kÕt ngoµi. H·y nhËp 7 sè nguyªn kh¸c nhau cã gi¸ trÞ tõ 0 ®Õn 100 trong ®ã cã 3 sè ®ång d− víi nhau mod m vµ vÏ s¬ ®å minh häa qu¸ tr×nh chÌn c¸c phÇn tö nµy vµo. VÝ dô víi m = 3 vµ c¸c sè chÌn vµo lµ 5, 6, 7, 15, 16, 23 ta cã s¬ ®å sau: http://www.ebook.edu.vn CÊu tróc d÷ liÖu 2 - C©u hái lý thuyÕt vµ c¸c bµi thùc hµnh chuÈn bÞ cho thi hÕt m«n 0 6 1 7 2 5 15 18 23 H×nh 2.1. B¶ng b¨m dïng danh s¸ch liªn kÕt ngoµi c. H·y m« t¶ qu¸ tr×nh t×m khãa k = 22 trªn s¬ ®å b¶ng b¨m do b¹n vÏ. 2.5. a. H·y m« t¶ ph−¬ng ph¸p tr¸nh ®ông ®é b»ng c¸ch dïng danh s¸ch liªn kÕt trong: B¶ng b¨m lµ mét m¶ng gåm m thµnh phÇn H = (a0, a1,... am-1), trong ®ã mçi phÇn tö ai lµ mét cÊu tróc chøa 2 thµnh phÇn: thµnh phÇn thø nhÊt chøa ®Þa chØ cña môc d÷ liÖu, thµnh phÇn thø 2 lµ gi¸ trÞ nguyªn chØ ®Õn « tiÕp theo khi cã hiÖn t−îng ®ông ®é x¶y ra. C¸c khãa lµ c¸c sè nguyªn k vµ hµm b¨m lµ hµm lÊy gi¸ trÞ phÇn d− khi chia k cho m, tøc lµ h(k)=k%m. b. H·y nhËp 3 sè nguyªn kh¸c nhau cã gi¸ trÞ tõ 0 ®Õn 100 vµ lµ béi sè cña 3 vµ minh häa qu¸ tr×nh chÌn c¸c phÇn tö nµy vµo b¶ng b¨m theo c¸ch ë c©u a víi m = 7. H×nh sau biÓu diÔn c¸ch thªm c¸c nót 35, 15,45 vµo b¶ng chia d− cã m=10. i 0 1 2 3 4 5 6 7 8 9 pkey 35 45 15 next -1 -1 -1 -1 -1 9 -1 -1 -1 8 H×nh 2.2 B¶ng b¨m liªn kÕt trong. ë ®©y ta ghi gi¸ trÞ khãa thay cho ®Þa chØ cña c¸c nót th«ng tin chøa khãa. Nh− vËy sè 35 sÏ ®−îc hiÓu lµ ®Þa chØ cña khãa 35. http://www.ebook.edu.vn 94 CÊu tróc d÷ liÖu 2 - C©u hái lý thuyÕt vµ c¸c bµi thùc hµnh chuÈn bÞ cho thi hÕt m«n 2.6. Cho b¶ng b¨m chia d− H víi cì cña b¶ng m = 11. H·y t¹o 5 sè nguyªn trong kho¶ng tõ 0 ®Õn 100 trong ®ã cã 3 sè ®ång d− víi nhau mod m (tøc lµ khi chia cho m th× cã cïng mét sè d−), sau ®ã m« t¶ c¸ch chÌn c¸c sè nµy vµo b¶ng H sö dông c¸ch tr¸nh ®ông ®é b»ng ph−¬ng ph¸p dß tuyÕn tÝnh. 2.7.* Cho b¶ng b¨m chia d− H víi cì cña b¶ng m = 11. H·y t¹o 5 sè nguyªn trong kho¶ng tõ 0 ®Õn 100 trong ®ã cã 3 sè ®ång d− víi nhau mod m (tøc lµ khi chia cho m th× cã cïng mét sè d−), sau ®ã m« t¶ c¸ch chÌn c¸c sè nµy vµo b¶ng H sö dông c¸ch tr¸nh ®ông ®é b»ng ph−¬ng ph¸p dß bËc 2. Ch−¬ng 3. C©y ®á ®en 3.1. H·y nªu ra nh÷ng lËp luËn mµ ng−êi ta sö dông khi ®−a ra cÊu tróc c©y. 3.2. H·y nªu vÝ dô khi c©y suy biÕn thµnh danh s¸ch. Lóc nµy cã thÓ nãi g× vÒ thêi gian t×m kiÕm trªn c©y? 3.3. H·y nªu ®Þnh nghÜa c©y 2-3-4. 3.4. H·y nªu ®Þnh nghÜa c©y ®á ®en vµ c¸ch chuyÓn ®æi mét c©y 2-3-4 thµnh c©y ®á ®en. 3.5. H·y ®−a ra ®¸nh gi¸ vÒ chiÒu cao cña c©y 2-3-4 cã n nót d÷ liÖu, tõ ®ã suy ra ®¸nh gi¸ vÒ thêi gian t×m kiÕm c¸c khãa trªn c©y 2-3-4 cã n nót. 3.6. H·y ®−a ra ®¸nh gi¸ vÒ chiÒu cao cña c©y ®á ®en cã n nót. 3.7. H·y t¹o 7 sè nguyªn kh¸c nhau cã gi¸ trÞ tõ 0 ®Õn 100 vµ kh«ng c¸ch ®Òu nhau. Sau ®ã trÝnh bµy c¸c b−íc t¹o c©y 2-3-4 cã c¸c khãa lµ 7 sè nguyªn võa t¹o ra; sau ®ã x©y dùng c©y ®á ®en tõ c©y 2-3-4 nµy. 3.8. Nªu ®Þnh nghÜa c©y c©n b»ng chiÒu cao (c©y AVL). 3.9. H·y t¹o 5 sè nguyªn kh¸c nhau cã gi¸ trÞ tõ 0 ®Õn 100 cã gi¸ trÞ t¨ng dÇn vµ kh«ng c¸ch ®Òu nhau. Sau ®ã trÝnh bµy c¸c b−íc t¹o c©y AVL cã c¸c khãa lµ 5 sè nguyªn võa t¹o ra. Nãi râ phÐp quay ®Ó c©n b»ng c©y. Ch−¬ng 4. B - c©y 4.1. H·y nªu ®Þnh nghÜa B - c©y. 4.2. H·y ®−a ra ®¸nh gi¸ vÒ chiÒu cao cña B - c©y cÊp m. 4.3. a. H·y t¹o 7 sè nguyªn kh¸c nhau cã gi¸ trÞ tõ 0 ®Õn 100 cã gi¸ trÞ t¨ng dÇn vµ kh«ng c¸ch ®Òu nhau, trong sè 7 sè nµy cã sè 17. Sau ®ã tr×nh bµy c¸c b−íc t¹o B - c©y cã c¸c khãa lµ 7 sè nguyªn võa t¹o ra. b. H·y m« t¶ thuËt to¸n t×m khãa x = 22 trªn c©y võa t¹o ra. c. H·y m« t¶ thuËt to¸n t×m khãa x = 17. d. H·y m« t¶ thuËt to¸n xãa khãa 17. B. PhÇn thùc hµnh Ghi chó. §Ó tr¸nh sù nhÇm lÉn mµ kh«ng ph¶i gi¶i thÝch qu¸ dµi, chóng t«i quy −íc c¸ch viÕt nh− sau: - Tªn tÖp d÷ liÖu sÏ ®−îc viÕt b»ng 2 c¸ch: c¸ch thø nhÊt lµ ®−îc ®ãng trong nh¸y kÐp, vÝ dô "ZZ.DAT", "VUTB.DAT",... khi ®ã ta hiÓu ®©y lµ c¸c tªn tÖp mµ khi dïng c¸c c«ng cô thao t¸c tÖp nh− My Computer hay NC ta sÏ nh×n thÊy trªn ®Üa cøng. C¸ch thø 2 lµ kh«ng ®ãng trong nh¸y kÐp, vÝ dô tÖp tepA. Lóc nµy ta hiÓu lµ tªn tÖp chÝnh lµ gi¸ trÞ cña biÕn chuçi. VÝ dô nÕu biÕn chuçi tepA cã gi¸ trÞ lµ "THU.TXT" ch¼ng h¹n th× khi viÕt tÖp tepA ta sÏ hiÓu lµ tÖp "THU.TXT". Tuy nhiªn ®èi víi tÖp ch−¬ng tr×nh vÝ dô 11SXF.CPP chóng t«i kh«ng dïng quy −íc nµy v× kh«ng cã sù nhËp nh»ng. - V× hµm th−êng cã nhiÒu tham sè, nÕu viÕt ®Çy ®ñ sÏ qu¸ dµi, nÕu chØ viÕt hai dÊu () sau tªn hµm th× cã thÓ hiÓu nhÇm lµ hµm kh«ng cã tham sè. Do ®ã chóng t«i quy −íc khi viÕt http://www.ebook.edu.vn 95 CÊu tróc d÷ liÖu 2 - C©u hái lý thuyÕt vµ c¸c bµi thùc hµnh chuÈn bÞ cho thi hÕt m«n tªn hµm mµ kh«ng cã g× phÝa sau, vÝ dô SplitFile th× cã nghÜa ta chØ nãi ®Õn tªn hµm, cßn phÇn tham sè th× ph¶i tham kh¶o ch−¬ng tr×nh míi biÕt ®−îc. - NÕu b¹n ®−îc yªu cÇu viÕt l¹i mét ®o¹n ch−¬ng tr×nh nµo ®ã th× b¹n ph¶i hiÓu râ ch−¬ng tr×nh m×nh viÕt. NÕu chØ viÕt mµ kh«ng hiÓu g× th× coi nh− kh«ng ®−îc tÝnh ®iÓm. - NÕu viÖc viÕt l¹i ch−¬ng tr×nh lµ qu¸ khã ®èi víi b¹n th× b¹n cÇn ph¶i hiÓu ®−îc nh÷ng phÇn ch−¬ng tr×nh mµ bµi ra yªu cÇu. NÕu hiÓu ®−îc th× b¹n cã thÓ ®¹t ®iÓm trung b×nh. Ch−¬ng 1. S¾p xÕp ngo¹i 1.1. Ch−¬ng tr×nh 11SXF.CPP cµi ®Æt thuËt to¸n trén trùc tiÕp ®Ó s¾p xÕp tÖp nhÞ ph©n chøa c¸c sè thùc. Ch−¬ng tr×nh nµy cã mét sè hµm, trong ®ã 3 hµm quan träng nhÊt lµ SplitFile, MergeFile vµ SortFile. Trong hµm main cã thÓ thÊy lµ tÖp cÇn ®−îc s¾p xÕp cã tªn lµ "ZZ.DAT". TÖp nµy ®−îc t¹o ra khi gäi hµm CreateFile. Cã thÓ dïng hµm ViewFile ®Ó liÖt kª c¸c sè thùc ®−îc l−u tr÷ trong tÖp bÊt kú. Khi ch¹y hµm CreateFile ta cã 2 kh¶ n¨ng lùa chän: hoÆc nhËp trùc tiÕp trªn bµn phÝm hoÆc chØ cÇn nhËp sè phÇn tö råi m¸y sÏ dïng hµm t¹o sè ngÉu nhiªn cã s½n trong C ®Ó t¹o ra c¸c sè thùc vµ ®−a vµo tÖp. Hµm SortFile sÏ lÊy ®Çu vµo lµ tÖp "ZZ.DAT", sau ®ã t¹o ra 2 tÖp trung gian lµ "VUTB.DAT" vµ "VUTC.DAT" ®Ó chøa c¸c run ®−îc ph©n bæ tõ "ZZ.DAT". T¹i b−íc khëi ®Çu p ®−îc g¸n gi¸ trÞ 1, sau ®ã vßng lÆp sau ®−îc thùc hiÖn chõng nµo p cßn nhá h¬n n: B1. Hµm SplitFile ®−îc gäi ®Ó ph©n bæ c¸c run ®é dµi p tõ "ZZ.DAT" sang "VUTB.DAT" vµ "VUTC.DAT", ph−¬ng ph¸p trén trùc tiÕp coi tÖp ban ®Çu cã n phÇn tö gåm n run ®é dµi 1. §iÒu nµy lu«n lu«n ®óng. B2. Hµm MergeFile ®−îc gäi ®Ó trén c¸c run ®é dµi p tõ "VUTB.DAT" vµ "VUTC.DAT" thµnh c¸c run ®é dµi 2p trong "ZZ.DAT". Mçi lÇn trén ta thÊy ®é dµi run t¨ng gÊp ®«i (trõ run cuèi cïng), do ®ã ta ®Æt p = 2*p. NÕu p ≥ n th× kÕt thóc, nÕu kh«ng th× quay l¹i B1. B¹n h·y thùc hiÖn c¸c c«ng viÖc sau (ë nhµ vµ ë giê thùc hµnh): a. §äc toµn bé ch−¬ng tr×nh ®Ó hiÓu ®−îc chøc n¨ng, input vµ output cña c¸c hµm, ý nghÜa c¸c lÖnh. B¹n h·y dïng chøc n¨ng "Save as..." ®Ó l−u tÖp 11SXF.CPP thµnh tÖp BAI11.CPP vµ thö söa ®æi ch−¬ng tr×nh nµy theo gîi ý sau: b. Hµm void SplitFile(char *tepA,char *tepB, char *tepC, int p) cã ®Çu vµo (input) lµ tÖp tepA chøa c¸c run ®é dµi p (trõ run cuèi cïng cã thÓ cã Ýt h¬n). Hµm nµy sÏ t¹o ra c¸c tÖp nhÞ ph©n cã tªn lµ tepB vµ tepC, sau ®ã lÇn l−ît ph©n bæ c¸c run ®é dµi p trªn tepA sang c¸c tÖp tepB vµ tepC cho ®Õn khi hÕt run trªn A. B¹n h·y xãa hµm SplitFile råi viÕt l¹i mµ kh«ng sö dông tµi liÖu hoÆc ch−¬ng tr×nh mÉu, sao cho ch−¬ng tr×nh nµy ch¹y ®−îc vµ cho kÕt qu¶ ®óng. c. Hµm void MergeFile(char *tepB,char *tepC, char *tepA, int p) cã ®Çu vµo lµ c¸c tÖp tepB vµ tepC chøa c¸c run ®é dµi p (trõ run cuèi ). Hµm nµy sÏ t¹o míi tÖp nhÞ ph©n tepA, sau ®ã lÇn l−ît trén tõng cÆp run ®é dµi p trªn tepB vµ tepC thµnh c¸c run cã ®é dµi 2p vµ ®−a sang tÖp tepA cho ®Õn khi hÕt run trªn tepB vµ tepC. B¹n h·y xãa hµm MergeFile råi viÕt l¹i mµ kh«ng sö dông tµi liÖu hoÆc ch−¬ng tr×nh mÉu, sao cho ch−¬ng tr×nh nµy ch¹y ®−îc vµ cho kÕt qu¶ ®óng. d. Hµm void SortFile(char *TenTep) http://www.ebook.edu.vn 96 CÊu tróc d÷ liÖu 2 - C©u hái lý thuyÕt vµ c¸c bµi thùc hµnh chuÈn bÞ cho thi hÕt m«n cã ®Çu vµo lµ tÖp TenTep th−êng ch−a ®−îc s¾p xÕp. Trong th©n hµm hai tÖp trung gian lµ "VUTB.DAT" vµ "VUTC.DAT" ®−îc t¹o ra vµ sö dông nh− c¸c tÖp trung gian. ThuËt to¸n trén run trùc tiÕp ®−îc ¸p dông vµ cho kÕt qu¶ lµ tÖp TenTep ®−îc s¾p xÕp. B¹n h·y xãa hµm SortFile råi viÕt l¹i mµ kh«ng sö dông tµi liÖu hoÆc ch−¬ng tr×nh mÉu, sao cho ch−¬ng tr×nh nµy ch¹y ®−îc vµ cho kÕt qu¶ ®óng. 1.2. Ch−¬ng tr×nh 12SXF.CPP cµi ®Æt thuËt to¸n trén run tù nhiªn ®Ó s¾p xÕp tÖp nhÞ ph©n chøa c¸c sè thùc. Ch−¬ng tr×nh nµy cã mét sè hµm, trong ®ã 3 hµm quan träng nhÊt lµ SplitFile, MergeFile vµ SortFile. Ngoµi ra hµm EoR còng ®−îc khai b¸o. Hµm nµy cho kÕt qu¶ true nÕu con trá tÖp ®ang kh¶o s¸t ®· ë cuèi tÖp hoÆc ë sau phÇn tö cuèi cïng cña run. NÕu con trá tÖp ë vÞ trÝ ®Çu tÖp hoÆc ch−a ë phÝa sau phÇn tö cuèi cña run th× hµm nµy nhËn gi¸ trÞ false. Trong hµm main cã thÓ thÊy lµ tÖp cÇn ®−îc s¾p xÕp cã tªn lµ "ZZ.DAT". Hµm SortFile sÏ lÊy ®Çu vµo lµ tÖp "ZZ.DAT", sau ®ã t¹o ra 2 tÖp trung gian lµ "VUTB.DAT" vµ "VUTC.DAT" ®Ó chøa c¸c run ®−îc ph©n bæ tõ "ZZ.DAT". C¸c b−íc lÆp sau ®−îc thùc hiÖn ®Ó trén tÖp "ZZ.DAT". B1. Hµm SplitFile ®−îc gäi ®Ó ph©n bæ c¸c run tù hiªn tõ "ZZ.DAT" sang "VUTB.DAT" vµ "VUTC.DAT". B2. Hµm MergeFile ®−îc gäi ®Ó trén c¸c run tù nhiªn tõ "VUTB.DAT" vµ "VUTC.DAT" thµnh c¸c run ®é dµi lín h¬n trong "ZZ.DAT". Mçi lÇn trén ta thÊy sè c¸c run gi¶m ®i kho¶ng mét nöa. NÕu sau khi trén tepA chØ chøa mét run (cã nghÜa lµ tÖp ®· ®−îc s¾p xÕp), th× ta kÕt thóc thuËt to¸n, nÕu kh«ng th× quay l¹i B1. B¹n h·y thùc hiÖn c¸c c«ng viÖc sau (ë nhµ vµ ë giê thùc hµnh): a. §äc toµn bé ch−¬ng tr×nh ®Ó hiÓu ®−îc chøc n¨ng, input vµ output cña c¸c hµm, ý nghÜa c¸c lÖnh. B¹n h·y dïng chøc n¨ng "Save as..." ®Ó l−u tÖp 12SXF.CPP thµnh tÖp BAI12.CPP vµ thö söa ®æi ch−¬ng tr×nh nµy theo gîi ý sau: b. Hµm void SplitFile(char *tepA,char *tepB, char *tepC) cã ®Çu vµo (input) lµ tÖp tepA chøa c¸c run tù nhiªn. Hµm nµy sÏ t¹o ra c¸c tÖp nhÞ ph©n cã tªn lµ tepB vµ tepC, sau ®ã lÇn l−ît ph©n bæ c¸c run trªn tepA sang c¸c tÖp tepB vµ tepC cho ®Õn khi hÕt run trªn A. B¹n h·y xãa hµm SplitFile råi viÕt l¹i mµ kh«ng sö dông tµi liÖu hoÆc ch−¬ng tr×nh mÉu, sao cho ch−¬ng tr×nh nµy ch¹y ®−îc vµ cho kÕt qu¶ ®óng. c. Hµm void MergeFile(char *tepB,char *tepC, char *tepA) cã ®Çu vµo lµ c¸c tÖp tepB vµ tepC chøa c¸c run tù nhiªn. Hµm nµy sÏ t¹o míi tÖp nhÞ ph©n tepA, sau ®ã lÇn l−ît trén tõng cÆp run trªn tepB vµ tepC thµnh c¸c run dµi h¬n vµ ®−a sang tÖp tepA cho ®Õn khi hÕt run trªn tepB vµ tepC. B¹n h·y xãa hµm MergeFile råi viÕt l¹i mµ kh«ng sö dông tµi liÖu hoÆc ch−¬ng tr×nh mÉu, sao cho ch−¬ng tr×nh nµy ch¹y ®−îc vµ cho kÕt qu¶ ®óng. d. Hµm void SortFile(char *TenTep) cã ®Çu vµo lµ tÖp TenTep th−êng ch−a ®−îc s¾p xÕp. Trong th©n hµm hai tÖp trung gian lµ "VUTB.DAT" vµ "VUTC.DAT" ®−îc t¹o ra vµ sö dông nh− c¸c tÖp trung gian. ThuËt to¸n trén run tù nhiªn ®−îc ¸p dông vµ cho kÕt qu¶ lµ tÖp TenTep ®−îc s¾p xÕp. B¹n h·y xãa hµm SortFile råi viÕt l¹i mµ kh«ng sö dông tµi liÖu hoÆc ch−¬ng tr×nh mÉu, sao cho ch−¬ng tr×nh nµy ch¹y ®−îc vµ cho kÕt qu¶ ®óng. http://www.ebook.edu.vn 97 CÊu tróc d÷ liÖu 2 - C©u hái lý thuyÕt vµ c¸c bµi thùc hµnh chuÈn bÞ cho thi hÕt m«n 1.3. Ch−¬ng tr×nh 13SXF.CPP cµi ®Æt thuËt to¸n trén ®a lèi c©n b»ng ®Ó s¾p xÕp tÖp nhÞ ph©n chøa c¸c sè thùc. Ch−¬ng tr×nh nµy cã mét sè hµm, trong ®ã 3 hµm quan träng nhÊt lµ SplitFile, MergeFile vµ SortFile. Trong hµm main cã thÓ thÊy lµ tÖp cÇn ®−îc s¾p xÕp cã tªn lµ "ZZ.DAT". Hµm SortFile sÏ lÊy ®Çu vµo lµ tÖp "ZZ.DAT", sau ®ã yªu cÇu ng−êi sö dông nhËp vµo sè ®−êng trén. NÕu sè ®−êng trén lµ n th× n tÖp nguån vµ n tÖp ®Ých ®−îc t¹o ra. VÝ dô nÕu n = 4 th× c¸c tÖp nguån cã tªn lµ: ZZN0.DAT, ZZN1.DAT, ZZN2.DAT, ZZN3.DAT vµ c¸c tÖp ®Ých cã tªn lµ ZZD0.DAT, ZZD1.DAT, ZZD2.DAT, ZZD3.DAT. (Chóng t«i ®Æt tªn tÖp b¾t ®Çu b»ng ZZ ®Ó c¸c tÖp nµy khi hiÓn thÞ sÏ n»m ë cuèi th− môc; N lµ nguån, cßn D cã nghÜa lµ ®Ých). C¸c b−íc lÆp sau ®−îc thùc hiÖn ®Ó trén tÖp "ZZ.DAT". B1. Hµm SplitFile ®−îc gäi ®Ó ph©n bæ c¸c run tù hiªn tõ "ZZ.DAT" sang n tÖp nguån. B2. Hµm MergeFile ®−îc gäi ®Ó trén tõng bé n run tõ c¸c tÖp nguån thµnh tõng run ®é dµi lín h¬n (b»ng tæng ®é dµi cña n run tõ c¸c tÖp nguån thµnh phÇn), sau ®ã lÇn l−ît ph©n bæ cho c¸c tÖp ®Ých. Run trén ®−îc ®Çu tiªn sÏ ®−îc ghi vµo tÖp ®Ých TepDich[0], run thø hai trén ®−îc sÏ ®−îc ghi vµo TepDich[2],... có nh− vËy cho ®Õn khi hÕt c¸c run trªn tÖp nguån. Mçi lÇn trén ta thÊy sè c¸c run gi¶m ®i kho¶ng n lÇn. B3. NÕu sau khi trén chØ cã mét tÖp ®Ých (cã nghÜa lµ tÖp TepDich[0] chØ chøa mét run), th× ta kÕt thóc thuËt to¸n, nÕu kh«ng th× quay l¹i B2. B¹n h·y thùc hiÖn c¸c c«ng viÖc sau (ë nhµ vµ ë giê thùc hµnh): a. §äc toµn bé ch−¬ng tr×nh ®Ó hiÓu ®−îc chøc n¨ng, input vµ output cña c¸c hµm, ý nghÜa c¸c lÖnh. B¹n h·y dïng chøc n¨ng "Save as..." ®Ó l−u tÖp 13SXF.CPP thµnh tÖp BAI13.CPP vµ thö söa ®æi ch−¬ng tr×nh nµy theo gîi ý sau: b. Hµm void SplitFile(char *tepA,char *TepNguon[], int &nWay) cã ®Çu vµo (input) lµ tÖp tepA chøa c¸c run tù nhiªn. Hµm nµy sÏ t¹o ra c¸c tÖp nhÞ ph©n cã tªn lµ TepNguon[0], TepNguon[1], ... ,TepNguon[nWay-1], sau ®ã lÇn l−ît ph©n bæ c¸c run trªn tepA sang c¸c tÖp nguån cho ®Õn khi hÕt run trªn A. Sau khi ph©n bæ run th× rÊt cã thÓ mét sè tÖp nguån cßn trèng do sè run Ýt h¬n sè ®−êng trén. Ch−¬ng tr×nh sÏ tÝnh to¸n l¹i sè ®−êng trén nWay dùa trªn sè tÖp nguån thùc tÕ. B¹n h·y xãa hµm SplitFile råi viÕt l¹i mµ kh«ng sö dông tµi liÖu hoÆc ch−¬ng tr×nh mÉu, sao cho ch−¬ng tr×nh nµy ch¹y ®−îc vµ cho kÕt qu¶ ®óng. c. Hµm void MergeFile(char *TepNguon[],char *TepDich[], int &nWay) cã ®Çu vµo lµ c¸c tÖp TepNguon[i], i = 0, 1, ..., nWay-1 chøa c¸c run tù nhiªn. Hµm nµy sÏ t¹o c¸c tÖp ®Ých TepDich[i], i = 0, 1, ..., nWay-1, sau ®ã lÇn l−ît trén tõng bé n run trªn c¸c tÖp ®Ých (lÇn trén cuèi cïng cã thÓ kh«ng ®ñ n run) thµnh c¸c run dµi h¬n vµ ®−a sang c¸c tÖp ®Ých cho ®Õn khi hÕt run trªn c¸c tÖp nguån. B¹n h·y xãa hµm MergeFile råi viÕt l¹i mµ kh«ng sö dông tµi liÖu hoÆc ch−¬ng tr×nh mÉu, sao cho ch−¬ng tr×nh nµy ch¹y ®−îc vµ cho kÕt qu¶ ®óng. d. Hµm void SortFile(char *TenTep) cã ®Çu vµo lµ tÖp TenTep th−êng ch−a ®−îc s¾p xÕp. Trong th©n hµm, ch−¬ng tr×nh yªu cÇu ng−êi sö dông nhËp sè ®−êng trén, sau ®ã t¹o ra c¸c tÖp nguån vµ c¸c tÖp ®Ých nh− ®· nãi ë trªn. TiÕp theo c¸c run tù nhiªn trong tÖp TenTep ®−îc ph©n bæ cho c¸c tÖp nguån. ThuËt to¸n trén ®a lèi c©n b»ng ®−îc ¸p dông b»ng c¸ch sau mçi lÇn trén l¹i ho¸n ®æi vai http://www.ebook.edu.vn 98 CÊu tróc d÷ liÖu 2 - C©u hái lý thuyÕt vµ c¸c bµi thùc hµnh chuÈn bÞ cho thi hÕt m«n trß cña c¸c tÖp nguån vµ c¸c tÖp ®Ých cho ®Õn khi chØ cßn mét tÖp ®Ých duy nhÊt th× kÕt thóc. ë b−íc cuèi cïng tÖp ®Ých TepDich[0] chøa mét run duy nhÊt gåm tÊt c¶ c¸c phÇn tö trong tÖp ban ®Çu. Ch−¬ng tr×nh copy d÷ liÖu ®· s¾p xÕp vµo tÖp TenTep, xãa c¸c tÖp trung gian vµ kÕt thóc. B¹n h·y xãa hµm SortFile råi viÕt l¹i mµ kh«ng sö dông tµi liÖu hoÆc ch−¬ng tr×nh mÉu, sao cho ch−¬ng tr×nh nµy ch¹y ®−îc vµ cho kÕt qu¶ ®óng. Ch−¬ng 2. B¶ng b¨m 2.1. Ch−¬ng tr×nh 21HASHLK.CPP cµi ®Æt b¶ng b¨m dïng danh s¸ch liªn kÕt ngoµi b»ng ng«n ng÷ lËp tr×nh C++. Víi môc ®Ých cµi ®Æt b¶ng b¨m ®Ó cã thÓ dïng cho nhiÒu môc ®Ých, chóng t«i cµi ®Æt b¶ng b¨m nh− mét líp (class) trong ®ã thµnh phÇn chÝnh cña líp lµ mét m¶ng ®éng H mµ mçi phÇn tö cña m¶ng H lµ mét danh s¸ch liªn kÕt. B¶n th©n danh s¸ch liªn kÕt l¹i lµ mét kiÓu líp cã tªn lµ List ®−îc khai b¸o trong tÖp LIST_H.CPP. Thµnh phÇn chÝnh cña danh s¸ch lµ mét m¶ng ®éng mµ c¸c phÇn tö lµ c¸c sè nguyªn. §Ó cã thÓ hiÓu ®−îc ch−¬ng tr×nh 21HASHLK.CPP, b¹n cÇn t×m hiÓu tÖp LIST_H.CPP mµ c¸c chøc n¨ng cña nã cã thÓ hiÓu ®−îc khi ®äc ch−¬ng tr×nh. Sau khi hiÓu tÖp nµy, b¹n ch¹y thö ch−¬ng tr×nh DS-LK.CPP. Ch−¬ng tr×nh nµy chÌn (include) tÖp LIST_H.CPP vµo, sau ®ã ch¹y c¸c chøc n¨ng nh− nhËp d÷ liÖu vµo danh s¸ch, t×m kiÕm trªn danh s¸ch... 2.2. Ch−¬ng tr×nh 21HASHLK.CPP cµi ®Æt b¶ng b¨m víi mét sè chøc n¨ng (theo ng«n ng÷ C++ th× ®ã lµ c¸c ph−¬ng thøc), trong ®ã quan träng nhÊt lµ c¸c chøc n¨ng insert, search vµ traverse. B¹n h·y t×m hiÓu ch−¬ng tr×nh, sau ®ã dïng chøc n¨ng "Save as..." ®Ó l−u tÖp nµy thµnh tÖp BAI21.CPP, råi thö söa ®æi tÖp nµy theo c¸ch sau: a. Hµm void HashTab::insert(int x) thùc hiÖn viÖc chÌn mét khãa x vµo b¶ng b¨m B¹n h·y xãa phÇn th©n hµm vµ viÕt l¹i sao cho ch−¬ng tr×nh vÉn ch¹y ®óng. b. Hµm int HashTab::search(int x) thùc hiÖn viÖc t×m khãa x trªn b¶ng b¨m. NÕu t×m thÊy th× tr¶ vÒ gi¸ trÞ true, ®ång thêi ®Æt con trá pcurent trá vµo ®Þa chØ nót t×m thÊy. NÕu kh«ng t×m thÊy th× tr¶ vÒ gi¸ trÞ false. B¹n h·y xãa phÇn th©n hµm vµ viÕt l¹i sao cho ch−¬ng tr×nh vÉn ch¹y ®óng. c. Hµm void HashTab::traverse() thùc hiÖn viÖc liÖt kª tÊt c¶ c¸c khãa trong b¶ng b¨m B¹n h·y xãa phÇn th©n hµm vµ viÕt l¹i sao cho ch−¬ng tr×nh vÉn ch¹y ®óng. 2.3. Ch−¬ng tr×nh 23HASHTR.CPP cµi ®Æt b¶ng b¨m víi mét sè chøc n¨ng (theo ng«n ng÷ C++ th× ®ã lµ c¸c ph−¬ng thøc), trong ®ã quan träng nhÊt lµ c¸c chøc n¨ng insert, search vµ traverse. B¹n h·y t×m hiÓu ch−¬ng tr×nh, sau ®ã dïng chøc n¨ng "Save as..." ®Ó l−u tÖp nµy thµnh tÖp BAI23.CPP, råi thö söa ®æi tÖp nµy theo c¸ch sau: a. Hµm void HashTab::insert(int x) thùc hiÖn viÖc chÌn mét khãa x vµo b¶ng b¨m B¹n h·y xãa phÇn th©n hµm vµ viÕt l¹i sao cho ch−¬ng tr×nh vÉn ch¹y ®óng. b. Hµm http://www.ebook.edu.vn 99 CÊu tróc d÷ liÖu 2 - C©u hái lý thuyÕt vµ c¸c bµi thùc hµnh chuÈn bÞ cho thi hÕt m«n int HashTab::search(int x) thùc hiÖn viÖc t×m khãa x trªn b¶ng b¨m. NÕu t×m thÊy th× tr¶ vÒ gi¸ trÞ true, ®ång thêi ®Æt con trá pcurent trá vµo ®Þa chØ nót t×m thÊy. NÕu kh«ng t×m thÊy th× tr¶ vÒ gi¸ trÞ false. B¹n h·y xãa phÇn th©n hµm vµ viÕt l¹i sao cho ch−¬ng tr×nh vÉn ch¹y ®óng. c. Hµm void HashTab::traverse() thùc hiÖn viÖc liÖt kª tÊt c¶ c¸c khãa trong b¶ng b¨m B¹n h·y xãa phÇn th©n hµm vµ viÕt l¹i sao cho ch−¬ng tr×nh vÉn ch¹y ®óng. Ch−¬ng 3. C©y ®á ®en Ch−¬ng tr×nh 31CAYAVL.CPP cµi ®Æt c©y nhÞ ph©n t×m kiÕm c©n b»ng chiÒu cao. Ch−¬ng tr×nh nµy rÊt khã, nªn chóng t«i chØ yªu cÇu b¹n ®äc vµ hiÓu c¸c chøc n¨ng cña ch−¬ng tr×nh. Tuy nhiªn ®Ó sù t×m hiÓu hiÖu qu¶ h¬n b¹n cã thÓ l−u thµnh mét tÖp kh¸c råi thö viÕt l¹i tõng ®o¹n nhá. Ch−¬ng 4. B - c©y Ch−¬ng tr×nh 41BTREE.CPP cµi ®Æt B - c©y. Ch−¬ng tr×nh nµy rÊt khã, nªn chóng t«i chØ yªu cÇu b¹n ®äc vµ hiÓu c¸c chøc n¨ng cña ch−¬ng tr×nh. Tuy nhiªn ®Ó sù t×m hiÓu hiÖu qu¶ h¬n b¹n cã thÓ l−u thµnh mét tÖp kh¸c råi thö viÕt l¹i tõng ®o¹n nhá. C¸c bµi thùc hµnh trong hai ch−¬ng 3 vµ 4 sÏ lµ gi¶i thÝch ch−¬ng tr×nh. http://www.ebook.edu.vn 100 CÊu tróc d÷ liÖu 2 - C©u hái lý thuyÕt vµ c¸c bµi thùc hµnh chuÈn bÞ cho thi hÕt m«n Mét sè ch−¬ng tr×nh mÉu Sau ®©y lµ mét sè ch−¬ng tr×nh mÉu c¬ së t−¬ng ®èi ®¬n gi¶n c¸c b¹n cã thÓ t×m hiÓu ®Ó hiÓu vµ viÕt l¹i: 1. Ch−¬ng tr×nh 11SXF.CPP: S¾p xÕp tÖp nghÞ ph©n b»ng ph−¬ng ph¸p trén trùc tiÕp //11SXF.CPP Sap xep file bang phuong phap tron truc tiep tren tep nhi phan //Programmer: Phan Dang Cau, Khoa CNTT, Hoc vien CNBCVT #include <conio.h> #include <stdlib.h> #include <stdio.h> #define true 1 #define false 0 #define sz (sizeof(float)) //--------------------------int FileNodes(char *TenTep);//Tra ve so phan tu tren tep int EoF(FILE *f);//Tra ve gia tri true neu cuoi tep, false neu chua cuoi tep void CreateFile(char *TenTep);//Tao tep nhi phan chua cac so thuc void ViewFile(char *TenTep);//Cho hien danh sach cac so thuc trong tep //Phan chia cac run do dai p trong tep A cho 2 tep B va C void SplitFile(char *tepA,char *tepB, char *tepC, int p); //Tron cac run do dai p trong B va C thanh run do dai 2p trong A //(tru run cuoi) void MergeFile(char *tepB,char *tepC, char *tepA, int p); //Ap dung phuong phap tron truc tiep de sap xep tep co ten la TenTep void SortFile(char *TenTep); //--------------------------void main() {clrscr(); char *TenTep="ZZ.DAT"; CreateFile(TenTep); ViewFile(TenTep); printf("\n\nTep sau khi sap xep la:\n"); SortFile(TenTep); ViewFile(TenTep); getch(); }; //--------------------------int EoF(FILE *f) {float x; if(fread(&x,sz,1,f)>0) {fseek(f,-1.0*sz,1); return(false); }; return(true); } //--------------------------int FileNodes(char *TenTep) {int k;float x; FILE *f = fopen(TenTep,"rb"); fseek(f,0,2);//Ve cuoi tep k = ftell(f)/sz; fclose(f); http://www.ebook.edu.vn 101 CÊu tróc d÷ liÖu 2 - C©u hái lý thuyÕt vµ c¸c bµi thùc hµnh chuÈn bÞ cho thi hÕt m«n return(k); }; //--------------------------//Tao file co n phan tu void CreateFile(char *TenTep) {int i,m;float x; FILE* f; f = fopen(TenTep,"wb"); rewind(f); clrscr(); printf("\n1. Nhap truc tiep"); printf("\n2. Tao ngau nhien"); printf("\n\n Hay chon 1 hoac 2: "); char ch=getche(); printf("\nCho biet so phan tu can dua vao tep: "); scanf("%d",&m); if(ch=='1') {printf("\nHay nhap %d so: ",m); for(i=0;i<m;i++) {scanf("%f",&x); fwrite(&x,sz,1,f); } } else {randomize(); for(i=0;i<m;i++) {x=float(random(10*m)); fwrite(&x,sz,1,f); } } fclose(f); }; //--------------------------//Hien thi noi dung file len man hinh void ViewFile(char *TenTep) {float x; FILE* f; f = fopen(TenTep,"rb"); rewind(f); printf("\nCac phan tu tren tep %s:\n\n",TenTep); while(fread(&x,sz,1,f)>0) printf("%5.0f",x); fclose(f); }; //--------------------------//Chia xoay vong file a cho file b va file c moi lan p phan tu void SplitFile(char *tepA,char *tepB, char *tepC, int p) {FILE *a,*b,*c;float x;int dem; a = fopen(tepA,"rb"); b = fopen(tepB,"wb"); c = fopen(tepC,"wb"); rewind(a);rewind(b);rewind(c); while(!EoF(a)) {//Chia p phan tu cho b dem = 0; http://www.ebook.edu.vn 102 CÊu tróc d÷ liÖu 2 - C©u hái lý thuyÕt vµ c¸c bµi thùc hµnh chuÈn bÞ cho thi hÕt m«n while(dem<p && !EoF(a)) {fread(&x,sz,1,a); fwrite(&x,sz,1,b); dem++; } dem = 0; while(dem<p && !EoF(a)) {fread(&x,sz,1,a); fwrite(&x,sz,1,c); dem++; } } fclose(a);fclose(b);fclose(c); }; //--------------------------//Tron p phan tu tu tren b voi p phan tu tren c thanh 2*p phan tu tren a //cho den khi file b hoac c het void MergeFile(char *tepB,char *tepC, char *tepA, int p) {FILE *a,*b,*c; float x,y; int ix,iy; b = fopen(tepB,"rb"); c = fopen(tepC,"rb"); a = fopen(tepA,"wb"); rewind(a);rewind(b);rewind(c); while(!EoF(b) && !EoF(c)) {ix = 0;//So phan tu cua b da ghi len a trong so 2*p phan tu can gi len a iy = 0;//So phan tu cua c da ghi len a trong so 2*p phan tu can gi len a fread(&x,sz,1,b); fread(&y,sz,1,c); while(ix<p && iy<p) {if(x<y) {fwrite(&x,sz,1,a);ix++; if(ix==p || EoF(b)) {fwrite(&y,sz,1,a);iy++;break;} //Chua du p phan tu va chua het file b fread(&x,sz,1,b); } else //x>=y) {fwrite(&y,sz,1,a);iy++; if(iy==p || EoF(c)) {fwrite(&x,sz,1,a);ix++;break;} //Chua du p phan tu va chua het file b fread(&y,sz,1,c); } }//Het vong while(ix<p && iy<p) //Chep phan con lai cua p phan tu tren b len a while(ix<p && !EoF(b)) {fread(&x,sz,1,b); fwrite(&x,sz,1,a);ix++; } //Chep phan con lai cua p phan tu tren c len a while(iy<p && !EoF(c)) {fread(&y,sz,1,c); fwrite(&y,sz,1,a);iy++; } http://www.ebook.edu.vn 103 CÊu tróc d÷ liÖu 2 - C©u hái lý thuyÕt vµ c¸c bµi thùc hµnh chuÈn bÞ cho thi hÕt m«n } //Chep phan con lai tren b len a while(!EoF(b)) {fread(&x,sz,1,b); fwrite(&x,sz,1,a); } //Vi co the b co nhieu hon c mot run, nen tren c da het phan tu fclose(a);fclose(b);fclose(c); }; //--------------------------//Sap xep tep co ten la TenTep bang phuong phap tron void SortFile(char *TenTep) {int p,n;char *tepB="vutb.dat",*tepC="vutc.dat"; n=FileNodes(TenTep); p=1; while(p<n) {SplitFile(TenTep,tepB,tepC,p); MergeFile(tepB,tepC,TenTep,p); p = 2*p; } remove("vutb.dat"); remove("vutc.dat"); } 2. Ch−¬ng tr×nh 12SXF.CPP: S¾p xÕp tÖp nghÞ ph©n b»ng ph−¬ng ph¸p trén tù nhiªn //12SXF.CPP Sap xep file bang phuong phap tron tu nhien tren tep nhi phan //Programmer: Phan Dang Cau, Khoa CNTT, Hoc vien CNBCVT #include <conio.h> #include <stdio.h> #include <stdlib.h> #define true 1 #define false 0 #define sz (sizeof(float)) //--------------------------int FileNodes(char *TenTep);//Tra ve so phan tu tren tep int EoF(FILE *f);//Tra ve gia tri true neu cuoi tep, false neu chua cuoi tep int EoR(FILE *f);//Tra ve gia tri true neu cuoi run, false neu chua cuoi run void CreateFile(char *TenTep);//Tao tep nhi phan chua cac so thuc void ViewFile(char *TenTep);//Cho hien danh sach cac so thuc trong tep //Phan chia cac run tu nhien trong tep A cho 2 tep B va C void SplitFile(char *tepA,char *tepB, char *tepC); //Tron cac run tu nhien trong B va C thanh run trong A void MergeFile(char *tepB,char *tepC, char *tepA); int SortedFile(char *TenTep);//Tra ve gia tri true neu tep da sap xep //Ap dung phuong phap tron run tu nhien de sap xep tep co ten la TenTep void SortFile(char *TenTep); //--------------------------void main() {clrscr(); char *TenTep="ZZ.DAT"; CreateFile(TenTep); ViewFile(TenTep); printf("\n\nTep sau khi sap xep la:\n"); http://www.ebook.edu.vn 104 CÊu tróc d÷ liÖu 2 - C©u hái lý thuyÕt vµ c¸c bµi thùc hµnh chuÈn bÞ cho thi hÕt m«n SortFile(TenTep); ViewFile(TenTep); getch(); }; //--------------------------int EoF(FILE *f) {float x; if(fread(&x,sz,1,f)<=0) return(true); fseek(f,-1.0*sz,1); return(false); } //--------------------------int EoR(FILE *f) {float x,y; if(ftell(f)==0) return(false); if(fread(&y,sz,1,f)<=0) return(true); fseek(f,-2.0*sz,1); fread(&x,sz,1,f); if(x<=y) return(false); else return(true); } //--------------------------int FileNodes(char *TenTep) {int k;float x; FILE *f = fopen(TenTep,"rb"); fseek(f,0,2);//Ve cuoi tep k = ftell(f)/sz; fclose(f); return(k); }; //--------------------------//Tao file co n phan tu void CreateFile(char *TenTep) {int i,m;float x; FILE* f; f = fopen(TenTep,"wb"); rewind(f); char ch; do {clrscr(); printf("\nNhap du lieu vao tep:"); printf("\n1. Nhap truc tiep"); printf("\n2. Tao ngau nhien"); printf("\n\n Hay chon 1 hoac 2: "); ch=getche(); } while(ch!='1'&& ch!='2'); printf("\nCho biet so phan tu can dua vao tep: "); scanf("%d",&m); if(ch=='1') {printf("\nHay nhap %d so: ",m); for(i=0;i<m;i++) {scanf("%f",&x); http://www.ebook.edu.vn 105 CÊu tróc d÷ liÖu 2 - C©u hái lý thuyÕt vµ c¸c bµi thùc hµnh chuÈn bÞ cho thi hÕt m«n fwrite(&x,sz,1,f); } } else {randomize(); for(i=0;i<m;i++) {x=float(random(10*m)); fwrite(&x,sz,1,f); } } fclose(f); }; //--------------------------//Hien thi noi dung file len man hinh void ViewFile(char *TenTep) {float x; FILE* f; f = fopen(TenTep,"rb"); rewind(f); printf("\nCac phan tu tren tep %s:\n\n",TenTep); while(fread(&x,sz,1,f)>0) printf("%5.0f",x); fclose(f); }; //--------------------------//Chia xoay vong tung run tren file a cho file b va file c cho den khi het a void SplitFile(char *tepA,char *tepB, char *tepC) {FILE *a,*b,*c;float x; a = fopen(tepA,"rb"); b = fopen(tepB,"wb"); c = fopen(tepC,"wb"); rewind(a);rewind(b);rewind(c); while(!EoF(a)) {//Chia 1 run tren a cho b fread(&x,sz,1,a); fwrite(&x,sz,1,b); while(!EoR(a)) {fread(&x,sz,1,a); fwrite(&x,sz,1,b); } if(EoF(a)) break; //Chia 1 run tren a cho c fread(&x,sz,1,a); fwrite(&x,sz,1,c); while(!EoR(a)) {fread(&x,sz,1,a); fwrite(&x,sz,1,c); } } fclose(a);fclose(b);fclose(c); }; //--------------------------//Tron mot run tren b voi mot run tren c thanh run tren a //cho den khi file b va c het void MergeFile(char *tepB,char *tepC, char *tepA) http://www.ebook.edu.vn 106 CÊu tróc d÷ liÖu 2 - C©u hái lý thuyÕt vµ c¸c bµi thùc hµnh chuÈn bÞ cho thi hÕt m«n {FILE *a,*b,*c; float x,y;int con_x,con_y; //con_x = true co nghia la con phan tu trong run tren b //con_y = true co nghia la con phan tu trong run tren c b = fopen(tepB,"rb"); c = fopen(tepC,"rb"); a = fopen(tepA,"wb"); rewind(a);rewind(b);rewind(c); while(!EoF(b) && !EoF(c)) {fread(&x,sz,1,b);con_x=true; fread(&y,sz,1,c);con_y=true; while(con_x && con_y) {if(x<y) {fwrite(&x,sz,1,a); if(EoR(b)) con_x=false; else fread(&x,sz,1,b); //Neu sau khi ghi x vao a ma het run tren file b thi con_x=false } else //x>=y) {fwrite(&y,sz,1,a); if(EoR(c)) con_y=false; else fread(&y,sz,1,c); //Neu sau khi ghi y vao a ma het run tren file c thi con_y=false } } //Het Run tren b hoac c //Neu chua ghi x hoac y len a thi ghi not if(con_x) fwrite(&x,sz,1,a); if(con_y) fwrite(&y,sz,1,a); //Chep phan con lai cua run hien thoi tu b len a while(!EoR(b)) {fread(&x,sz,1,b); fwrite(&x,sz,1,a); } //Chep phan con lai cua run hien thoi tu c len a while(!EoR(c)) {fread(&x,sz,1,c); fwrite(&x,sz,1,a); } } //Chep phan con lai tren b len a while(!EoF(b)) {fread(&x,sz,1,b); fwrite(&x,sz,1,a); } //Chep phan con lai tren c len a while(!EoF(c)) {fread(&y,sz,1,c); fwrite(&y,sz,1,a); } fclose(a);fclose(b);fclose(c); }; //--------------------------//Kiem tra neu tep da sap xep thi tra ve true int SortedFile(char *TenTep) {FILE *f;float x,y; http://www.ebook.edu.vn 107 CÊu tróc d÷ liÖu 2 - C©u hái lý thuyÕt vµ c¸c bµi thùc hµnh chuÈn bÞ cho thi hÕt m«n f = fopen(TenTep,"rb"); rewind(f); fread(&x,sz,1,f); while(fread(&y,sz,1,f)>0) {if(x>y) {fclose(f);return(false);} x = y; } fclose(f); return(true); } //--------------------------//Sap xep tep co ten la TenTep bang phuong phap tron void SortFile(char *TenTep) {int i;char *tepB="vutb.dat",*tepC="vutc.dat"; while(!SortedFile(TenTep)) {SplitFile(TenTep,tepB,tepC); MergeFile(tepB,tepC,TenTep); } remove("vutb.dat"); remove("vutc.dat"); } 3. Ch−¬ng tr×nh 13SXF.CPP: S¾p xÕp tÖp nghÞ ph©n b»ng ph−¬ng ph¸p trén ®a lèi c©n b»ng //13SXF.CPP Sap xep file bang phuong phap tron da loi can bang //Programmer: Phan Dang Cau, Khoa CNTT, Hoc vien CNBCVT #include <stdio.h> #include <stdlib.h> #include <conio.h> #include <string.h> #define true 1 #define false 0 #define sz (sizeof(float)) //--------------------------int FileNodes(char *TenTep);//Tra ve so phan tu tren tep int EoF(FILE *f);//Tra ve gia tri true neu cuoi tep, false neu chua cuoi tep int EoR(FILE *f);//Tra ve gia tri true neu cuoi run, false neu chua cuoi run void CreateFile(char *TenTep);//Tao tep nhi phan chua cac so thuc void ViewFile(char *TenTep);//Cho hien danh sach cac so thuc trong tep //Phan chia cac run tu nhien trong tep A cho cac tep nguon TepNguon[0], //TepNguon[1],...,TepNguon[nWay-1]. void SplitFile(char *TenTep,char *TepNguon[], int &nWay); //Tron cac run tu nhien trong cac tep nguon dua vao cac tep dich void MergeFile(char *TepNguon[],char *TepDich[], int &nWay); int SortedFile(char *TenTep);//Tra ve gia tri true neu tep da sap xep void CopyFile(char *Tep1, char *Tep2);//Copy cac phan tu tep1 sang tep2 //Ap dung phuong phap tron da loi can bang de sap xep tep co ten la TenTep void SortFile(char *TenTep); //--------------------------void main() {clrscr(); char *TenTep; TenTep = new char[12]; http://www.ebook.edu.vn 108 CÊu tróc d÷ liÖu 2 - C©u hái lý thuyÕt vµ c¸c bµi thùc hµnh chuÈn bÞ cho thi hÕt m«n strcpy(TenTep,"ZZ.DAT"); CreateFile(TenTep); ViewFile(TenTep); SortFile(TenTep); printf("\n\nTep sau khi sap xep la:\n"); ViewFile(TenTep); getch(); }; //--------------------------int EoF(FILE *f) {float x; if(fread(&x,sz,1,f)<=0) return(true); fseek(f,-1.0*sz,1); return(false); } //--------------------------int EoR(FILE *f) {float x,y; if(ftell(f)==0) return(false); if(fread(&y,sz,1,f)<=0) return(true); fseek(f,-2.0*sz,1); fread(&x,sz,1,f); if(x<=y) return(false); else return(true); } //--------------------------int FileNodes(char *TenTep) {int k;float x; FILE *f = fopen(TenTep,"rb"); fseek(f,0,2);//Ve cuoi tep k = ftell(f)/sz; fclose(f); return(k); }; //--------------------------//Tao file co n phan tu void CreateFile(char *TenTep) {int i,m;float x; FILE* f; f = fopen(TenTep,"wb"); rewind(f); char ch; do {clrscr(); printf("\nNhap du lieu vao tep:"); printf("\n1. Nhap truc tiep"); printf("\n2. Tao ngau nhien"); printf("\n\n Hay chon 1 hoac 2: "); ch=getche(); } while(ch!='1'&& ch!='2'); printf("\nCho biet so phan tu can dua vao tep: "); scanf("%d",&m); http://www.ebook.edu.vn 109 CÊu tróc d÷ liÖu 2 - C©u hái lý thuyÕt vµ c¸c bµi thùc hµnh chuÈn bÞ cho thi hÕt m«n if(ch=='1') {printf("\nHay nhap %d so: ",m); for(i=0;i<m;i++) {scanf("%f",&x); fwrite(&x,sz,1,f); } } else {randomize(); for(i=0;i<m;i++) {x=float(random(5*m)); fwrite(&x,sz,1,f); } } fclose(f); }; //--------------------------//Hien thi noi dung file len man hinh void ViewFile(char *TenTep) {float x; FILE* f; f = fopen(TenTep,"rb"); rewind(f); printf("\nCac phan tu tren tep %s: ",TenTep); printf("\n\n"); while(fread(&x,sz,1,f)>0) printf("%5.0f",x); fclose(f); }; //--------------------------//Chia xoay vong tung run tren file a cho cac file nguon cho den khi het a void SplitFile(char *TenTep,char *TepNguon[], int &nWay) { FILE *f[10], *a;float x;int i,j,k; for(i=0;i<nWay;i++) f[i] = fopen(TepNguon[i],"wb"); a = fopen(TenTep,"rb"); rewind(a); for(i=0;i<nWay;i++) rewind(f[i]); while(!EoF(a)) {//Chia xoay vong lan luot cac run tren a cho f[0],f[1],...,f[nWay-1] //hoac chi den f[k] nao do neu het phan tu tren a for(i=0;i<nWay;i++) {if(EoF(a)) break; fread(&x,sz,1,a); fwrite(&x,sz,1,f[i]); while(!EoR(a)) {fread(&x,sz,1,a); fwrite(&x,sz,1,f[i]); } } } fclose(a); for(i=0;i<nWay;i++) fclose(f[i]); for(i=0;i<nWay && FileNodes(TepNguon[i])>0;i++); http://www.ebook.edu.vn 110 CÊu tróc d÷ liÖu 2 - C©u hái lý thuyÕt vµ c¸c bµi thùc hµnh chuÈn bÞ cho thi hÕt m«n nWay=i; }; //--------------------------//Tron cac bo run tren cac tep nguon va dua vao cac tep dich //cho den khi chi con mot tep dich void MergeFile(char *TepNguon[10],char *TepDich[10], int &nWay) {FILE *f[10], *g[10];float x[10],t,t1; int i,j,k,con_x[10],nNguon,CurrDich; /*Neu run tren f[i] chua het thi con_x[i] =true Neu het roi thi con_x[i] = false nNguon la so file nguon co phan tu nDich la so File dich da duoc cap phan tu CurrDich la file dich hien thoi duoc ghi run */ for(i=0;i<nWay;i++) {f[i] = fopen(TepNguon[i],"rb"); rewind(f[i]); g[i] = fopen(TepDich[i],"wb"); } CurrDich=0; while(true) //Se ket thuc khi het cac phan tu tren file nguon {//Vi cac run duoc phan phoi duoc phan bo tu i = 0 do do co the co //mot so tep o phan cuoi co it hon 1 run j=0; for(i=0;i<nWay;i++) if(fread(&t,sz,1,f[i])>0) {x[i]=t;con_x[i]=true;j++;} else con_x[i]=false; nNguon=j; if(nNguon==0) break;//Da het cac phan tu tren cac file nguon while(true) //Bat dau tron cac run va dua vao g[CurrDich] {//Tim phan tu be nhat o dau run trong bo run i=0;//Tim vi tri dau tien con phan tu trong run while(!con_x[i] && i<nWay)i++;//Tim run dang con phan tu if(i==nWay) //Het phan tu trong bo run, chuyen sang bo run khac {CurrDich++;CurrDich = CurrDich%nWay;break;} t = x[i];k=i; for(j=i+1;j<nWay;j++) if(con_x[j] && x[j]<t) {t=x[j];k=j;} //x[k] chinh la gia tri nho nhat trong bo run hien thoi fwrite(&t,sz,1,g[CurrDich]); if(EoR(f[k])) con_x[k]=false; else {fread(&t1,sz,1,f[k]); x[k]=t1; } } } for(i=0;i<nWay;i++) {fclose(f[i]);fclose(g[i]);} for(i=0;i<nWay && FileNodes(TepDich[i])>0;i++); nWay=i; http://www.ebook.edu.vn 111 CÊu tróc d÷ liÖu 2 - C©u hái lý thuyÕt vµ c¸c bµi thùc hµnh chuÈn bÞ cho thi hÕt m«n }; //--------------------------//Kiem tra neu tep da sap xep thi tra ve true int SortedFile(char *TenTep) {FILE *f;float x,y; f = fopen(TenTep,"rb"); rewind(f); fread(&x,sz,1,f); while(fread(&y,sz,1,f)>0) {if(x>y) {fclose(f);return(false);} x = y; } fclose(f); return(true); } //--------------------------void CopyFile(char *Tep1, char *Tep2) {FILE *f1, *f2;float x; f1 = fopen(Tep1,"rb"); f2 = fopen(Tep2,"wb"); rewind(f1); while(fread(&x,sz,1,f1)>0) fwrite(&x,sz,1,f2); fclose(f1);fclose(f2); } //--------------------------//Sap xep tep co ten la TenTep bang phuong phap tron void SortFile(char *TenTep) {int i,n,nWay; char *TepNguon[10],*TepDich[10]; char *s; s= new char[12]; n=0; do {printf("\nSo duong can tron n (1<n<=10) = "); scanf("%d",&n); } while(n<1 || n>10); for(i=0;i<n;i++) {TepNguon[i] = new char[12]; TepDich[i] = new char[12]; } for(i=0;i<n;i++) {s = itoa(i,s,10); strcpy(TepNguon[i],"ZZN"); strcat(TepNguon[i],s); strcat(TepNguon[i],".DAT"); strcpy(TepDich[i],"ZZD"); strcat(TepDich[i],s); strcat(TepDich[i],".DAT"); } nWay=n; SplitFile(TenTep,TepNguon,nWay); while(true) http://www.ebook.edu.vn 112 CÊu tróc d÷ liÖu 2 - C©u hái lý thuyÕt vµ c¸c bµi thùc hµnh chuÈn bÞ cho thi hÕt m«n {MergeFile(TepNguon,TepDich,nWay); if(nWay==1)break; for(i=0;i<nWay;i++) {strcpy(s,TepNguon[i]); strcpy(TepNguon[i],TepDich[i]); strcpy(TepDich[i],s); } } CopyFile(TepDich[0],TenTep); for(i=0;i<n;i++) {remove(TepNguon[i]);remove(TepDich[i]);} } 4. Ch−¬ng tr×nh 23HASHTR.CPP: Cµi ®Æt b¶ng b¨m dïng liªn kÕt trong //23HASHTR.CPP //Bang bam dung lien ket trong noi bo bang ma thoi #include <iostream.h> #include <conio.h> #include <stdio.h> #include <ctype.h> #include <stdlib.h> #include <assert.h> #define true 1 #define false 0 //--------------------------struct node {int* pkey; int next; }; //--------------------------class Hash {public: node* H; int max; int count; int current; Hash(int); ~Hash(); int empty(); int full(); int size(); void display(); void traverse(); int search(int); void insert(int); }; //--------------------------template <class T> void swap(T& x,T& y) {T tmp=x;x=y;y=tmp; } //--------------------------Hash::Hash(int size=10) http://www.ebook.edu.vn 113 CÊu tróc d÷ liÖu 2 - C©u hái lý thuyÕt vµ c¸c bµi thùc hµnh chuÈn bÞ cho thi hÕt m«n {max=size; H = new node[max]; for(int i=0;i<max;i++) {H[i].pkey=NULL;H[i].next=-1; } count=0; }; //--------------------------Hash::~Hash() {for(int i=0;i<max;i++) delete H[i].pkey; }; //--------------------------int Hash::empty() {return count==0; } //--------------------------int Hash::full() {return count==max; } //--------------------------int Hash::size() {return count; } //--------------------------void Hash::display() {if( H[current].pkey!=NULL) cout<<endl<<* H[current].pkey; }; //--------------------------//Hien toan bo danh sach len man hinh. void Hash::traverse() {cout<<endl<<" Key Next" ; for(int i=0;i<max;i++) {cout<<endl<<i<<" : "; if(H[i].pkey!=NULL) cout<<*H[i].pkey<<" "<<H[i].next; } } //--------------------------//Them nut co noi dung x vao bang bam. void Hash::insert(int x) {if(full()) {cout<<endl<<"Bang bam day, khong chen duoc";return;} if(search(x)) {cout<<endl<<"Nut da co, khong chen duoc";return;} int k,i,j; k=x%max; if( H[k].pkey==NULL) { H[k].pkey=new int;* H[k].pkey=x;count++; return;} if(* H[k].pkey%max==k) //Cung lop co phan du la d {i=k; while( H[i].next!=-1) i= H[i].next; for(j=max-1; H[j].pkey!=NULL;j--); H[i].next=j; H[j].pkey=new int; * H[j].pkey=x; H[j].next=-1; count++; http://www.ebook.edu.vn 114 CÊu tróc d÷ liÖu 2 - C©u hái lý thuyÕt vµ c¸c bµi thùc hµnh chuÈn bÞ cho thi hÕt m«n return; } //Truong hop x khong cung so du voi i, ta tim mot vi tri trong de chen for(j=max-1;j>0 && H[j].pkey!=NULL;j--); H[j].pkey=new int; * H[j].pkey=x; H[j].next=-1; count++; return; } //--------------------------//Tim con tro co noi dung x trong danh sach int Hash::search(int x) {int k,i,j; k=x%max; if(* H[k].pkey%max==k) //Cung lop co phan du la d {i=k; while( H[i].pkey!=NULL) {if(* H[i].pkey==x) {current=i;return true;} if( H[i].next==-1) break; else i= H[i].next; } return false; } for(j=max-1; H[j].pkey!=NULL;j--) if(* H[j].pkey==x) {current=j;return true;} return false; }; //--------------------------void main() {Hash H(10);int i,x; while(true) {clrscr(); //Tao menu cout<<endl<<" 1. Bang bam co bi rong khong"; cout<<endl<<" 2. Them phan tu x vao bang bam"; cout<<endl<<" 3. Tim phan tu x trong bang bam"; cout<<endl<<" 4. Duyet bang bam "; cout<<endl<<" z. Ket thuc"; cout<<endl<<endl<<"Hay nhan phim tu 1 -> z de chon: "; char chon=toupper(getch()); if(chon=='Z') break; switch(chon) {case '1':if(H.empty()) cout<<endl<<"Bang bam rong"; else cout<<endl<<"Bang bam khong rong";break; case '2':cout<<endl<<"Phan tu can nhap vao la x = ";cin>>x; H.insert(x);break; case '3':cout<<endl<<"Phan tu can tim la: ";cin>>x; if(H.search(x)) {cout<<endl<<"Phan tu tim thay la "; H.display();} else cout<<endl<<"Khong tim thay";break; case '4':H.traverse();break; } cout<<endl<<endl<<"Nhan phim bat ky de tiep tuc"; getch(); http://www.ebook.edu.vn 115 CÊu tróc d÷ liÖu 2 - C©u hái lý thuyÕt vµ c¸c bµi thùc hµnh chuÈn bÞ cho thi hÕt m«n } } http://www.ebook.edu.vn 116