Cau Truc Du Lieu Va Giai Thuat2

  • November 2019
  • PDF

This document was uploaded by user and they confirmed that they have the permission to share it. If you are author or own the copyright of this book, please report to us by using this DMCA report form. Report DMCA


Overview

Download & View Cau Truc Du Lieu Va Giai Thuat2 as PDF for free.

More details

  • Words: 42,840
  • Pages: 134
Tµi liÖu tham kh¶o hç trî m«n häc

CÊu tróc d÷ liÖu 2

TS. Phan §¨ng CÇu

Hµ néi, th¸ng 12 / 2005 (Tæng sè gåm 112 trang, c¶ b×a)

lêi nãi ®Çu CÊu tróc d÷ liÖu 2 lµ m«n häc khã. Víi thêi lîng 25 tiÕt lý thuyÕt rÊt khã truyÒn ®¹t hÕt nh÷ng néi dung chøa ®ùng trong cuèn gi¸o tr×nh hiÖn cã, nÕu kh«ng cã sù nç lùc cao cña gi¸o viªn vµ sinh viªn. §Ó bµi gi¶ng cã thÓ thùc hiÖn nhanh vµ hiÖu qu¶, t«i nghÜ r»ng c¸c b¹n sinh viªn nªn cã sù chuÈn bÞ tríc ë nhµ. §©y chÝnh lµ lóc c¸c b¹n cÇn ph¸t huy kh¶ n¨ng tù häc cña "sinh viªn ®µo t¹o tõ xa". §Ó hç trî c¸c b¹n trong qu¸ tr×nh tù t×m hiÓu chuÈn bÞ tríc kiÕn thøc cho c¸c buæi nghe gi¶ng, chóng t«i biªn tËp l¹i mét sè néi dung trong cuèn gi¸o tr×nh mét c¸ch chi tiÕt râ rµng h¬n. Cã thÓ nãi r»ng "cÊu tróc d÷ liÖu" lµ chuyªn ngµnh cña c«ng nghÖ th«ng tin nghiªn cøu c¸ch tæ chøc d÷ liÖu (trong bé nhí trong hoÆc trªn bé nhí ngoµi) mét c¸ch hîp lý trong viÖc thùc hiÖn c¸c bµi to¸n trªn m¸y tÝnh. Tríc ®©y ngêi ta vÉn nghÜ r»ng viÕt ch¬ng tr×nh thùc chÊt lµ cµi ®Æt c¸c thuËt to¸n trªn m¸y tÝnh, vµ ch¬ng tr×nh chÝnh lµ c¸c m· lÖnh thÓ hiÖn thuËt to¸n. Víi c¸c bµi to¸n lín th× ®iÒu nµy kh«ng cßn ®óng n÷a. Ngoµi thuËt to¸n, ngêi ta cßn ph¶i tæ chøc d÷ liÖu mét c¸ch hîp lý. Vµ kh¸i niÖm ch¬ng tr×nh, nh nhµ to¸n häc vµ tin häc næi tiÕng thÕ giíi ngêi Thôy sÜ Niklaus Wirth ®· ph¸t biÓu, bao gåm cÊu tróc d÷ liÖu vµ thuËt to¸n (data structures + algorithms = program). C¸ch tæ chøc d÷ liÖu ë ®©y ®îc hiÓu lµ c¸ch tæ chøc logic, v× vËy c¸c cÊu tróc d÷ liÖu thêng ®îc g¾n víi c¸c thuËt to¸n cô thÓ t¹o ra vµ thao t¸c trªn chóng. Còng dÔ hiÓu v× sao c¸c cÊu tróc d÷ liÖu quan träng l¹i ®îc tr×nh bµy trong c¸c tµi liÖu nh "CÈm nang thuËt to¸n", "NghÖ thuËt lËp tr×nh",... Mét trong nh÷ng bµi to¸n quan träng cña "cÊu tróc d÷ liÖu" lµ cµi ®Æt vµ thùc hiÖn c¸c thao t¸c víi c¸c môc d÷ liÖu. C¸c môc d÷ liÖu nµy cã thÓ lµ th«ng tin vÒ nh©n sù cña mét c¬ quan, th«ng tin vÒ c¸c chuyÕn bay cña mét h·ng hµng kh«ng, vÒ qu¶n lý kho, vÒ qu¶n trÞ m¹ng... Trong tin häc ngêi ta thêng gäi c¸c môc d÷ liÖu lµ c¸c nót (node). C¸c thao t¸c cÇn thùc hiÖn thêng lµ: thªm hoÆc xãa mét nót, t×m kiÕm hay s¾p xÕp theo mét trêng nµo ®ã vÝ dô ngµy sinh, hä tªn, gi¸ c¶... Môc ®Ých cña "cÊu tróc d÷ liÖu" lµ tæ chøc c¸c nót th«ng tin sao cho c¸c thao t¸c cËp nhËt, s¾p xÕp vµ t×m kiÕm ®îc thùc hiÖn nhanh nhÊt. MÆc dï nót th«ng tin cã thÓ chøa nhiÒu lo¹i d÷ liÖu kh¸c nhau, nhng ®Ó ®¬n gi¶n trong viÖc m« t¶ c¸c thuËt to¸n, thêng chóng ta chØ gi¶ thiÕt lµ c¸c nót chØ chøa mét trêng th«ng tin duy nhÊt vµ trêng nµy ®îc sö dông ®Ó s¾p xÕp vµ t×m kiÕm. Ta sÏ gäi trêng nµy lµ khãa (key). C¸ch gäi nµy cã kh¸c chót Ýt víi khãa trong c¬ së d÷ liÖu: trong csdl th× ngêi ta thêng hiÓu khãa lµ trêng cã gi¸ trÞ duy nhÊt trong tËp b¶n ghi, nghÜa lµ kh«ng cã 2 b¶n ghi nµo cã khãa trïng nhau. Nhng trong trêng hîp chóng ta xÐt th× ®«i khi cho phÐp ®iÒu ®ã. Khãa ë ®©y ®¬n gi¶n ®îc hiÓu lµ ®¹i lîng chóng ta ®ang quan t©m ®Ó s¾p xÕp t×m kiÕm. §ã cã thÓ lµ ngµy sinh, lµ hä tªn, ®Þa chØ... Th«ng thêng chóng ta xÐt c¸c khãa lµ c¸c sè thùc hoÆc sè nguyªn. Trong trêng hîp cã thÓ nhÇm lÉn víi kiÓu chØ sè, chóng ta sÏ xÐt khãa lµ c¸c sè thùc. Chóng t«i chØ xem b¶n th¶o nµy lµ mét c«ng cô hç trî thªm bªn c¹nh gi¸o tr×nh chÝnh thøc. Chóng t«i mong nhËn ®îc nh÷ng ý kiÕn gãp ý cña c¸c ®ång nghiÖp vµ c¸c em sinh viªn ®Ó bµi gi¶ng ®îc hiÖu qu¶ h¬n.

Hµ néi, th¸ng 12/2005 TS. Phan §¨ng CÇu

2

môc lôc Ch¬ng 1.......................................................................1 S¾p xÕp ngo¹i.............................................................1 1.1. Thao t¸c trªn tÖp b»ng ng«n ng÷ lËp tr×nh C++ ......................1 1.1.1. §Þnh nghÜa tÖp.....................................................................1 1.1.2. C¸c kiÓu truy cËp tÖp: nhÞ ph©n vµ v¨n b¶n........................2 1.1.3. C¸c hµm thao t¸c trªn tÖp......................................................3 1.2. Ph¬ng ph¸p trén run cã ®é dµi cè ®Þnh ....................................5 1.2.1. M« t¶ thuËt to¸n.....................................................................5 1.2.2. Cµi ®Æt ch¬ng tr×nh............................................................8 1.3. Ph¬ng ph¸p trén run tù nhiªn ....................................................13 1.3.1. M« t¶ thuËt to¸n...................................................................13 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) ..........................................................................................................19 1.4.1. M« t¶ thuËt to¸n...................................................................19 1.4.2. Cµi ®Æt ch¬ng tr×nh..........................................................21 1.5. Ph¬ng ph¸p trén ®a pha (Polyphase merge) ............................30

Ch¬ng 2.....................................................................32 B¶ng b¨m (Hash table)................................................32 2.1. Më ®Çu......................................................................................32 2.2. C¸c ph¬ng ph¸p tr¸nh ®ông ®é................................................33 2.2.1. Dïng danh s¸ch liªn kÕt........................................................33 2.2.2. Dïng danh s¸ch kÒ ngoµi......................................................34 2.2.3. Ph¬ng ph¸p dß tuyÕn tÝnh (linear probing method)...........35 2.2.4. Ph¬ng ph¸p dß bËc hai (quadratic probing method)............35 2.3. Cµi ®Æt b¶ng b¨m.....................................................................36 2.3.1. Cµi ®Æt b¶ng b¨m dïng danh s¸ch liªn kÕt ngoµi...............36 2.3.2. Cµi ®Æt b¶ng b¨m dïng liªn kÕt trong.................................39 2.3.4. Vµi nhËn xÐt vÒ b¶ng b¨m..................................................42

Ch¬ng 3.....................................................................43 C©y ®á ®en...............................................................43 3.1. Më ®Çu......................................................................................43

3.2. C©y nhÞ ph©n t×m kiÕm.........................................................44 3.3. C©y 2-3-4..................................................................................47 3.3.1. §Þnh nghÜa c©y 2-3-4.........................................................47 3.3.2. T×m kiÕm trªn c©y 2-3-4....................................................47 3.3.3. Thªm khãa vµo c©y 2-3-4...................................................48 3.3.4. Lo¹i bá khãa trªn c©y 2-3-4................................................49 3.3.5. Ph©n tÝch c¸c thuËt to¸n trªn c©y 2-3-4............................50 3.4. C©y ®á ®en (Red-black tree)...................................................51 3.4.1. §Þnh nghÜa .........................................................................51 3.4.2. Sù t¬ng ®¬ng gi÷a c©y ®á ®en vµ c©y 2-3-4................52 3.5. C©y c©n b»ng chiÒu cao (Height balanced tree).....................52 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 nhÞ ph©n t×m kiÕm............................................................................53 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..........................................................60 3.5.5. Vµi nhËn xÐt vÒ c©y AVL....................................................63 3.5.6. Cµi ®Æt c©y AVL................................................................64 3.5.7. Cµi ®Æt c©y AVL trªn bé nhí ngoµi...................................74

Ch¬ng 4.....................................................................75 B - c©y vµ bé nhí ngoµi...............................................75 4.1. Më ®Çu......................................................................................75 4.2. B - c©y.......................................................................................75 4.2.1. C©y t×m kiÕm nhiÒu nh¸nh (Multiway Search Tree)..........75 4.2.2. §Þnh nghÜa B - c©y.............................................................77 4.2.3. T×m kiÕm trªn B - c©y.......................................................77 4.2.4. Thªm khãa vµo B - c©y.......................................................78 4.2.5. Lo¹i bá khãa trªn B - c©y.....................................................79 4.2.6. Ph©n tÝch c¸c thuËt to¸n trªn B - c©y.................................80 4.3. Cµi ®Æt B - c©y........................................................................81 4.4. B - c©y vµ bé nhí ngoµi...........................................................90

C©u hái vµ bµi tËp.....................................................92 Ch¬ng Ch¬ng Ch¬ng Ch¬ng

1. 2. 3. 4.

S¾p xÕp ngo¹i...............................................................92 B¶ng b¨m.......................................................................93 C©y ®á ®en..................................................................95 B-c©y.............................................................................96

C¸c bµi tËp lo¹i A (7 ®iÓm): ............................................................97 C¸c bµi tËp lo¹i B (8 ®iÓm): ............................................................97 C¸c bµi tËp lo¹i C (9 ®iÓm): ............................................................98

C¸c bµi tËp lo¹i D (10 ®iÓm): ..........................................................98

Tµi liÖu tham kh¶o.....................................................99 Phô lôc. Mét sè ch¬ng tr×nh mÉu viÕt b»ng C++ .......100

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 lu 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, nhng ®Ó ®¬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. (Thùc ra C++ lµ ng«n ng÷ lËp tr×nh híng ®èi tîng, nhng v× c¸c b¹n cha lµm quen víi c¸ch lËp tr×nh nµy nªn chóng t«i chñ yÕu chØ sö dông phÇn C++ t¬ng thÝch víi C mµ th«i, do ®ã ®«i khi chóng t«i viÕt C thay v× C++). 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 lu 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, nhng 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.

CÊu tróc d÷ liÖu 2 - Ch¬ng 1. S¾p xÕp ngo¹i

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µ cha 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 lu tr÷ trªn ®Üa (thêng lµ ë vïng ®Çu cña ®Üa) ®Ó lu 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 lu 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.

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");

2

CÊu tróc d÷ liÖu 2 - Ch¬ng 1. S¾p xÕp ngo¹i

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 nhng 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.

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 lu tr÷ trªn ®Üa, nhng 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 lu 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. C¸ch sö con trá tÖp kh¸ ®Æc biÖt, kh«ng gièng nh con trá cña c¸c kiÓu d÷ liÖu kh¸c. Ta kh«ng thÓ dïng c¸c lÖnh malloc hay lÖnh new ®Ó cÊp ph¸t bé nhí, mµ sö dông lÖnh fopen() ®Ó t¹o tÖp míi vµ më tÖp ®· cã nh sÏ thÊy trong phÇn sau. a. Më vµ ®ãng tÖp Më tÖp: Có ph¸p: = fopen(,); 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 trong b¶ng sau: K ý nghÜa K ý nghÜa iÓu iÓu më më wb Më tÖp nhÞ ph©n míi chØ wt Më tÖp v¨n b¶n míi chØ ghi ghi (nh vËy nÕu ®· cã tÖp (nh vËy nÕu ®· cã tÖp cò cïng cò cïng tªn th× tÖp cò sÏ tªn th× tÖp cò sÏ bÞ xãa) bÞ xãa) w+ Më tÖp nhÞ ph©n míi w+t Më tÖp v¨n b¶n míi ®äc/ ghi

3

CÊu tróc d÷ liÖu 2 - Ch¬ng 1. S¾p xÕp ngo¹i

b rb r+b

®äc/ ghi Më tÖp nhÞ ph©n ®· cã rt chØ ®äc Më tÖp nhÞ ph©n ®· cã r+t ®äc/ ghi

Më tÖp v¨n b¶n ®· cã chØ ®äc Më tÖp v¨n b¶n ®· cã ®äc/ ghi

§ãng tÖp: Có ph¸p: fclose(); 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(, ); VÝ dô: fput('O',f); - Ghi mét chuçi ký tù lªn tÖp: fputs(, ); VÝ dô: fputs("Chao",f); - Ghi c¸c biÓu thøc lªn tÖp: fprintf(,,); 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ù DÊu DÊu Sè 1 Sè DÊu . Sè Ký tù 'A' c¸ch c¸ch 2 5 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>, ); 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µ lu gi¸ trÞ cña nã mµ th«i. c. §äc th«ng tin tõ tÖp vµ ®a vµo biÕn bé nhí C¸ch gi¶i thÝch c¸c lÖnh sau t¬ng tù nh trêng hîp ghi lªn tÖp nhng 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(,<Sè byte tèi ®a>, );//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);

4

CÊu tróc d÷ liÖu 2 - Ch¬ng 1. S¾p xÕp ngo¹i

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>, ); 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µ lu 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(); sÏ ®a con trá tÖp vÒ ®Çu tÖp. VÝ dô rewind(f); - fseek(, <Sè byte cÇn dÞch chuyÓn>, ); = 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() 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 lu 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 a 0 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 nh nhau,

5

CÊu tróc d÷ liÖu 2 - Ch¬ng 1. S¾p xÕp ngo¹i

n n ]+1 run, cßn trªn C cã [ ] run. 2 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ã n 1 phÇn tö, c¸c run trªn A b©y giê ®· cã 2 phÇn tö. Vµ sè run lµ   2 n (hµm trÇn cña . 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: cßn nÕu n lÎ th× trªn B cã [

A B C A '

1 2 9 8 7 6 5 1 9 7 5 2 8 6 1 8 6 5 2 9 7

.. . Bíc k: Lóc nµy trõ run cuèi cïng, c¸c run trªn A ®é dµi n (cã tÊt c¶ [ ]+1 run). Ta sÏ lÇn lît ph©n bæ c¸c p vµ C. TiÕp theo ta lÇn lît trén tõng cÆp run trªn B vµ vµo A. Víi k = 2 trong vÝ dô trªn ta cã p = 2 vµ kÕt trong b¶ng sau: A 1 8 6 5 2 9 7 B 1 6 2 7 C 8 5 9 A 1 2 8 5 6 ' 9 7

cè ®Þnh p = 2 (k-1) run cho 2 tÖp B C víi nhau vµ ghi qu¶ ®îc thÓ hiÖn

§Æ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:

6

CÊu tróc d÷ liÖu 2 - Ch¬ng 1. S¾p xÕp ngo¹i

A B C A '

1 9 1 9 5 1 8

2 2

8 5 7 8

6 7 2 5 9

6

6

7

Khi ®Æt p = p* 2 = 8 ta thÊy vµ tÖp A ®· ®îc s¾p xÕp.

p ≥ n do ®ã

A chØ chøa mét run

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µ cha 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. 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. Lu ý 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
7

CÊu tróc d÷ liÖu 2 - Ch¬ng 1. S¾p xÕp ngo¹i

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 #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); 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:

8

CÊu tróc d÷ liÖu 2 - Ch¬ng 1. S¾p xÕp ngo¹i

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 cha 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 cha 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 cha 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"); 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

9

CÊu tróc d÷ liÖu 2 - Ch¬ng 1. S¾p xÕp ngo¹i

{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 lu 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æ cha 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"); c = fopen(tepC,"wb"); rewind(a);rewind(b);rewind(c); while(!EoF(a)) {//Chia p phan tu cho b dem = 0; while(dem


10

CÊu tróc d÷ liÖu 2 - Ch¬ng 1. S¾p xÕp ngo¹i

dem = 0; while(dem


11

CÊu tróc d÷ liÖu 2 - Ch¬ng 1. S¾p xÕp ngo¹i

} 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

=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


12

CÊu tróc d÷ liÖu 2 - Ch¬ng 1. S¾p xÕp ngo¹i

}; 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
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. Lu ý 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 2 9 8 7 6 5 1 2 7 5 9 8 6 1 2 8 6 5 9 7

13

CÊu tróc d÷ liÖu 2 - Ch¬ng 1. S¾p xÕp ngo¹i

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 7 5 9 C 8 6 A 1 2 8 6 5 ' 9 7 Bíc 2: A B C A '

1 2 9 1 2 9 6 7 1 2 8 9

8 6 7 8 5

5

6

7 5

1 2 8 9 1 2 8 9 5 1 2 8 9

6

7 5

6

7

5

6

Bíc 3: A B C A '

7

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.

14

CÊu tróc d÷ liÖu 2 - Ch¬ng 1. S¾p xÕp ngo¹i

- 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 #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); //===================== 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 cha 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:

15

CÊu tróc d÷ liÖu 2 - Ch¬ng 1. S¾p xÕp ngo¹i

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. 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);

16

CÊu tróc d÷ liÖu 2 - Ch¬ng 1. S¾p xÕp ngo¹i

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× 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 cha ®îc ghi lªn a. Ta ghi nèt phÇn tö cha ®î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ö cha ®î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)) {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:

17

CÊu tróc d÷ liÖu 2 - Ch¬ng 1. S¾p xÕp ngo¹i

//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(&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);

18

CÊu tróc d÷ liÖu 2 - Ch¬ng 1. S¾p xÕp ngo¹i

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 cha. 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Ò cha 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 (cha 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); } } 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

19

CÊu tróc d÷ liÖu 2 - Ch¬ng 1. S¾p xÕp ngo¹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 F1, F2, ..., Fm vµ m tÖp ®Ých G1, G2, ... Gm. ë 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 F1, run thø hai ®îc ph©n phèi cho F2,... NÕu cã nhiÒu h¬n m run th× sau khi ph©n phèi run cho tÖp Fm th× qu¸ tr×nh ph©n phèi l¹i quay l¹i F1, 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 G1, G2, ... Gm, 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è run gi¶m kho¶ng m lÇn (do tõng bé m run ®îc trén thµnh mét run, trõ mét sè run ë cuèi tÖp) vµ khi sè run ®Ých (®îc trén tõ c¸c run nguån) Ýt h¬n tÖp ®Ých 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 1 2

1 1

1 0

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: F 1 F 2 F 3

2 9 6 12 1 8 5 1 1 7 4 0

3

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 G 1 G 2 G 3 B©y giê ta l¹i c¸c tÖp ®Ých F 1

2 10 12 7 8 9 4 5 6

11 3

xem c¸c tÖp G1, G2, G3 lµ c¸c tÖp nguån vµ trén c¸c run vµo F1, F2, F3 vµ ®îc kÕt qu¶ lµ: 2 4 5 6 7 8 9 10 11 12

20

CÊu tróc d÷ liÖu 2 - Ch¬ng 1. S¾p xÕp ngo¹i

F 2

3

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: G 2 3 4 5 6 7 8 9 10 1 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 F1, F2, ..., Fm while(true) { - T¹o míi m tÖp ®Ých G1, G2, ..., Gm sau ®ã lÇn lît trén c¸c bé gåm m run trªn c¸c tÖp nguån vµ ph©n bæ vµo c¸c tÖp ®Ých nµy, 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 G1, G2, ..., Gm trë thµnh c¸c tÖp nguån, cßn c¸c tÖp F1, F2, ..., Fm 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. V× trong C++ chØ sè cña mét m¶ng b¾t ®Çu tõ 0, do ®ã thuËt to¸n thÓ hiÖn trong ch¬ng tr×nh cã kh¸c chót Ýt trong c¸ch ký hiÖu so víi c¸ch m« t¶ trªn ®©y. 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 #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);

21

CÊu tróc d÷ liÖu 2 - Ch¬ng 1. S¾p xÕp ngo¹i

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() {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;i0;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, nhng ®«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 cha 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

22

CÊu tróc d÷ liÖu 2 - Ch¬ng 1. S¾p xÕp ngo¹i

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
23

CÊu tróc d÷ liÖu 2 - Ch¬ng 1. S¾p xÕp ngo¹i

void SplitFile(char *TenTep,char *TepNguon[], int &nWay) { FILE *f[10], *a;float x;int i,j,k; for(i=0;i0;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µ lu 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, nhng 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Ø

24

CÊu tróc d÷ liÖu 2 - Ch¬ng 1. S¾p xÕp ngo¹i

®ä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µ 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;i0) {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] cha 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
25

CÊu tróc d÷ liÖu 2 - Ch¬ng 1. S¾p xÕp ngo¹i

{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
26

CÊu tróc d÷ liÖu 2 - Ch¬ng 1. S¾p xÕp ngo¹i

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;i0;i++); nWay=i; ®Ó thùc hiÖn ®iÒu nµy. ë ®©y ta vÉn cÇn ®iÒu kiÖn i0) {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
27

CÊu tróc d÷ liÖu 2 - Ch¬ng 1. S¾p xÕp ngo¹i

//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;i0;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 lu ý 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ù>, , ); = 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 = 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(, ); thùc hiÖn g¸n cho . VÝ dô sau sÏ g¸n chuçi s thµnh "Ha Noi". char s[10]; strcpy(s,"Ha Noi"); Hµm strcat(, );

28

CÊu tróc d÷ liÖu 2 - Ch¬ng 1. S¾p xÕp ngo¹i

thùc hiÖn ghÐp vµo phÝa sau . 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"); 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;i1) = ");scanf("%d",&n); for(i=0;i
29

CÊu tróc d÷ liÖu 2 - Ch¬ng 1. S¾p xÕp ngo¹i

strcat(TepDich[i],".DAT"); } nWay=n; SplitFile(TenTep,TepNguon,nWay); while(true) {MergeFile(TepNguon,TepDich,nWay); if(nWay==1)break; for(i=0;i
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:

Fn 2) Fn-2

T1 (= Fn-1+Fn- Fn-1

Fn-3 (= 4+Fn-5) ...

Fn-

T2

Fn-2 (= 3+Fn-4) Fn-4 ...

T3

Fn-

Fn-1 (= 2+Fn-3) Fn-3

Fn-

...

VÝ dô víi n = 7 ta cã F7 = 13, F6 = 8. Qu¸ tr×nh trén ®îc m« t¶ trong b¶ng sau:

30

CÊu tróc d÷ liÖu 2 - Ch¬ng 1. S¾p xÕp ngo¹i

T

T

T

1

2

3

1 3 5

8

3 1

5 2 1

1

Gi¶i thÝch Lóc ®Çu cã 13 run trong T1 vµ 8 run trong T2

8 3 2 1

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 T 1 víi 1 run trong T 3 ë bíc tríc vµo T2, T3 cßn l¹i 1 run. Trén 1 run trong T 2 víi 1 run trong T 3 ë 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.

31

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ã log 2n~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, nhng 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 lu 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 lu 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 ®Ó lu 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Ø lu 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

CÊu tróc d÷ liÖu 2 – Ch¬ng 2. B¶ng b¨m

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 ®é. 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 t¹i vÞ trÝ 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 ®é, nhng ta chØ dïng c¸c

33

CÊu tróc d÷ liÖu 2 – Ch¬ng 2. B¶ng b¨m

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 cha 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 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

35

45 15

next -1 -1 -1 -1 -1 9 -1 -1 -1 8

H×nh 2.2 B¶ng b¨m dïng danh s¸ch 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, nhng c¸c thµnh phÇn cña H b©y giê lµ c¸c danh s¸ch kÒ

34

CÊu tróc d÷ liÖu 2 – Ch¬ng 2. B¶ng b¨m

cµi ®Æt b»ng m¶ng ®éng. C¸c danh s¸ch con nµy tuy cã cì cè ®Þnh nhng 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 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. Lu ý 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 tha 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.

35

CÊu tróc d÷ liÖu 2 – Ch¬ng 2. B¶ng b¨m

- 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 lu ý 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 hai ch¬ng tr×nh: cµi ®Æt b¶ng b¨m dïng danh s¸ch liªn kÕt 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 B¶ng b¨m lµ m¶ng mét chiÒu H[0], H{1], H[2], ..., H[m-1] mµ mçi phÇn tö H[i] lµ con trá chØ ®Õn phÇn tö ®Çu tiªn cña danh s¸ch liªn kÕt gåm c¸c phÇn tö cã cã khãa nhËn gi¸ trÞ hµm b¨m b»ng i. PhÇn quan träng nhÊt cÇn cµi ®Æt lµ c¸c thao t¸c liªn quan ®Õn danh s¸ch liªn kÕt ®îc x¸c ®Þnh bëi con trá chØ ®Õn phÇn tö ®Çu tiªn cña danh s¸ch (c¸c phÇn tö cßn l¹i ®îc x¸c ®Þnh qua con trá next cña mçi nót th«ng tin). Sau ®©y chóng t«i chØ giíi thiÖu mét sè thao t¸c chÝnh. B¹n ®äc cã thÓ t×m hiÓu toµn v¨n phÇn cµi ®Æt tõ ch¬ng tr×nh 21HASHLK.CPP trong phÇn phô lôc "Mét sè ch¬ng tr×nh mÉu cµi ®Æt b»ng C++".  Khai b¸o cì cña b¶ng b¨m #define M 10 //M lµ cì cña b¶ng b¨m, ®îc cho gi¸ trÞ ngÇm ®Þnh lµ 10  Khai b¸o cÊu tróc cña mét nót trªn danh s¸ch struct node {int key; node* next; }; Khai b¸o b¶ng b¨m lµ m¶ng c¸c con trá chøa ®Þa chØ ®Çu cña c¸c danh s¸ch liªn kÕt node *H[M];//Bang bam la mot mang gom cac con tro chi den cac danh sach 

 Hµm b¨m lµ hµm chia d //Hash function int h(int x) {return(x%M); }  Xãa danh s¸ch do con trá phead chØ tíi void clear(node* &phead) {node *p,*p1;

36

CÊu tróc d÷ liÖu 2 – Ch¬ng 2. B¶ng b¨m

p=phead; while(p!=NULL) {p1=p; p=p->next; delete p1; } phead=NULL; }  Khëi t¹o danh s¸ch void init(node* &phead) {clear(phead); phead=NULL; }  KiÓm tra danh s¸ch cã rçng kh«ng int empty(node* &phead) {return(phead==NULL); }  TÝm khãa x trong danh s¸ch, tr¶ vÒ ®Þa chØ nót t×m thÊy node* search(node* &phead,int x) {node* p=phead; while(p!=NULL) {if(p->key==x) return(p); p=p->next; } return(NULL); };  ChÌn khãa x vµo danh s¸ch void insert(node* &phead,int x) {node *pp,*p,*p1; p=search(phead,x); if(p!=NULL) {printf("\nKhoa %4d da co, khong chen duoc!",x);return;} pp = new node; pp->key=x;pp->next=NULL; if(phead==NULL) {phead=pp;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; };  Xãa khãa x trong danh s¸ch void dele(node* &phead,int x) {node *p,*p1,*q;

37

CÊu tróc d÷ liÖu 2 – Ch¬ng 2. B¶ng b¨m

if(phead==NULL) return; if(phead->key==x) {p=phead;phead=phead->next;delete p;return;} p1=NULL; p=phead; while(p!=NULL) {if(p->key==x) {q=p; p1->next=p->next; delete q; return;} p1=p; p=p->next; } printf("\nKhoa %4d khong co, khong xoa duoc!"); };  DuyÖt danh s¸ch void traverse(node* &phead) {node* p=phead; while(p!=NULL) {printf("%5d",p->key); p=p->next; } };  Xãa b¶ng b¨m b»ng c¸ch lÇn lît xãa c¸c danh s¸ch void clear() {for(int i=0;i<M;i++) clear(H[i]); }  Khëi t¹o b¶ng b¨m b»ng c¸ch lÇn lît khëi t¹o c¸c danh s¸ch void init() {for(int i=0;i<M;i++) init(H[i]); } KiÓm tra xem b¶ng b¨m xem cã rçng kh«ng (b¶ng b¨m rçng khi tÊt c¶ c¸c danh s¸ch ®Òu rçng) int empty() {for(int i=0;i<M;i++) if(!empty(H[i])) return(false); return(true); } 

T×m khãa x trong b¶ng b¨m chÝnh lµ t×m x trong danh s¸ch ë vÞ trÝ k = h(x) node* search(int x) {int k=h(x);node* p; p=search(H[k],x); return(p); } 

ChÌn khãa x vµo b¶ng b¨m chÝnh lµ chÌn x vµo danh s¸ch ë vÞ trÝ k = h(x) void insert(int x) {int k=h(x); 

38

CÊu tróc d÷ liÖu 2 – Ch¬ng 2. B¶ng b¨m

insert(H[k],x); } Xãa khãa x trong b¶ng b¨m chÝnh lµ xãa x trong danh s¸ch ë vÞ trÝ k = h(x) void dele(int x) {int k=h(x); dele(H[k],x); } 

DuyÖt b¶ng b¨m chÝnh lµ lÇn lît duyÖt tÊt c¶ c¸c danh s¸ch ë c¸c vÞ trÝ trong b¶ng void traverse() {int i; printf("\n\nCac khoa tren bang bam:"); for(i=0;i<M;i++) {printf("\n%3d: ",i);traverse(H[i]);} } 

 ChÌn nhiÒu khãa vµo b¶ng b¨m void InsertMany() {clrscr();int m,i,x;init(); printf("\Nhap du lieu vao bang bam:"); printf("\n1. Nhap truc tiep"); 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(10*m); insert(x); } } };

2.3.2. Cµi ®Æt b¶ng b¨m dïng liªn kÕt trong B¶ng b¨m còng lµ m¶ng mét chiÒu H[0], H{1], H[2], ..., H[m-1] mµ mçi phÇn tö H[i] lµ mét cÊu tróc gåm mét con trá nguyªn pkey chøa ®Þa chØ cña khãa trong bé nhí, mét trêng next kiÓu nguyªn chØ vÞ trÝ cña phÇn tö

39

CÊu tróc d÷ liÖu 2 – Ch¬ng 2. B¶ng b¨m

tiÕp theo trong b¶ng cña danh s¸ch liªn kÕt trong khi cã ®ông ®é. Sau ®©y lµ mét sè thao t¸c chÝnh. B¹n ®äc cã thÓ t×m hiÓu toµn v¨n phÇn cµi ®Æt tõ ch¬ng tr×nh 22HASHTR.CPP trong phÇn phô lôc "Mét sè ch¬ng tr×nh mÉu cµi ®Æt b»ng C++".  Khai b¸o cì cña b¶ng b¨m #define M 10 //M lµ cì cña b¶ng b¨m, ®îc cho gi¸ trÞ ngÇm ®Þnh lµ 10 Khai b¸o cÊu tróc cña mét nót trong b¶ng 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 ®é. 

 Khai b¸o b¶ng b¨m node H[M];  Khai b¸o hµm b¨m lµ hµm chia d //Hash function int h(int x) {return(x%M); }  Khëi t¹o b¶ng b¨m void init() {for(int i=0;i<M;i++) {H[i].pkey=NULL;H[i].next=-1;} } KiÓm tra b¶ng b¨m cã rçng kh«ng (b¶ng b¨m rçng khi tÊt c¶ c¸c vÞ trÝ ®Òu trèng) int empty() {for(int i=0;i<M;i++) if(H[i].pkey!=NULL) return(false); return(true); } 

KiÓm tra b¶ng b¨m cã ®Çy kh«ng (b¶ng b¨m kh«ng ®Çy khi cã Ýt nhÊt mét vÞ trÝ trèng) int full() {for(int i=0;i<M;i++) if(H[i].pkey==NULL) return(false); return(true); } 

T×m khãa 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 = h(x). NÕu *H[k].pkey = x th× t¸c vô tr¶ vÒ gi¸ trÞ true, tr¶ vÒ vÞ trÝ k vµ kÕt thóc; Cßn nÕu kh«ng nh vËy th× ta xem khãa trong « nµy cã cïng hä víi x kh«ng, nghÜa lµ h(*H[k].pkey) cã b»ng h(x) 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Ò vÞ trÝ k vµ kÕt thóc ; hoÆc kh«ng t×m thÊy th× ta dõng 

40

CÊu tróc d÷ liÖu 2 – Ch¬ng 2. B¶ng b¨m

l¹i khi H[i].next = -1, t¸c vô tr¶ vÒ gi¸ trÞ -1. 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Ý M-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× tr¶ vÒ vÞ trÝ j , nÕu kh«ng th× tr¶ vÒ gi¸ trÞ -1 ®Ó ¸m chØ r»ng kh«ng t×m thÊy. int search(int x) {int k,i,j,y,p; k=h(x); if(H[k].pkey==NULL) return(-1);//Khong tim thay y=*H[k].pkey;p=h(y); if(p==k) //y va x co cung gia tri ham bam {i=k; while(H[i].pkey!=NULL) {if(*H[i].pkey==x) return(i); if(H[i].next==-1) break; else i= H[i].next; } return(-1);//Khong tim thay } for(j=M-1;H[j].pkey!=NULL;j--) if(*H[j].pkey==x) return(j); return(-1);//Khong tim thay }; ChÌn khãa vµo b¶ng b¨m Khi cÇn chÌn khãa 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 ®îc vµ kÕt thóc. NÕu b¶ng kh«ng ®Çy th× ta lÊy k = h(x). 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 khãa trong « nµy cã cïng hä víi x kh«ng, nghÜa lµ h(*H[k].pkey) cã b»ng h(x) 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 råi 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Ý M-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Ý M-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 insert(int x) {if(full()) {printf("\nBang bam day, khong chen duoc");return;} if(search(x)>=0) {printf("\nNut da co, khong chen duoc");return;} int k,i,j,y,p; k=h(x); if(H[k].pkey==NULL) //Vi tri k con trong, chen x vao va ket thuc {H[k].pkey=new int;*H[k].pkey=x; return;} y=*H[k].pkey;p=h(y); if(p==k) //x va y co cung gia tri ham bam

41

CÊu tróc d÷ liÖu 2 – Ch¬ng 2. B¶ng b¨m

{i=k;//Lan theo con tro next cho den khi gap next=-1 while(H[i].next!=-1) i= H[i].next;//dung lai khi H[i].next=-1 for(j=M-1;H[j].pkey!=NULL;j--);//Tim vi tri con trong xuat phat tu d y H[i].next=j; H[j].pkey=new int; *H[j].pkey=x; H[j].next=-1; return; } //Truong hop h(x)#h(y), xuat phat tu day ta tim mot vi tri trong de chen for(j=M-1;j>0 && H[j].pkey!=NULL;j--); H[j].pkey=new int; *H[j].pkey=x; H[j].next=-1; return; }  DuyÖt b¶ng b¨m void traverse() {int i; if(empty()) {printf("\nBang bam rong!");return;} printf("\n\n k key next:"); for(i=0;i<M;i++) {printf("\n%3d:",i); if(H[i].pkey!=NULL) printf("%4d %5d",*H[i].pkey,H[i].next); } } 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Ó.

42

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 nhng 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 nhng 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, nhng 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, nhng 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¸.

CÊu tróc d÷ liÖu2 – Ch¬ng 3. C©y ®á ®en

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, nhng ®Ó ®¬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. 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ù nhng 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

C

44

CÊu tróc d÷ liÖu2 – Ch¬ng 3. C©y ®á ®en D

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µ 2 h+1 -1, trong ®ã sè møc cña c©y (còng lµ chiÒu cao cña c©y).

h lµ

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Õ:

45

CÊu tróc d÷ liÖu2 – Ch¬ng 3. C©y ®á ®en



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: ABDEC LNR: DBEAC LRN: DEBCA Breadth: ABCDE

A B

D

C

E

H×nh 3.3. Bèn phÐp duyÖt c©y nhÞ ph©n C¸c híng më réng kh¸i niÖm c©y nhÞ ph©n t×m kiÕm ®Ó tr¸nh trêng hîp c©y suy biÕn Ta biÕt r»ng trong c¸c c©y nhÞ ph©n th× c©y nhÞ ph©n ®Çy ®ñ (complete binary tree) lµ c©y tèi u nhÊt theo nghÜa lµ nã cã chiÒu cao thÊp nhÊt trong c¸c c©y nhÞ ph©n cã cïng sè nót. Ta cã thÓ rót ra hai ®Æc ®iÓm cña c©y nµy nh sau: (1)Mçi nót trong c©y chØ cã mét khãa, vµ tæng sè khãa trong c©y tháa m·n hÖ thøc n = 2h+1 -1 (h lµ chiÒu cao cña c©y). (2)Víi mét nót P bÊt kú trong c©y, chiÒu cao cña c©y con ph¶i vµ c©y con tr¸i cña P b»ng nhau. (C©y con tr¸i cña P lµ c©y cã gèc lµ P vµ c¸c nót phÝa bªn tr¸i P t¹o nªn). Tuy nhiªn viÖc t¹o c©y nµy rÊt khã, h¬n n÷a rµng buéc vÒ tæng sè khãa trªn c©y lµ kh«ng phï hîp thùc tÕ. 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 môc sau ta sÏ xem xÐt hai híng më réng: (a)Ta gi÷ nguyªn ®iÒu kiÖn vÒ chiÒu cao nhng cho phÐp thay ®æi sè khãa trong mét nót, ta ®îc c©y 2-3-4 vµ mét sè d¹ng c©y kh¸c. Nh÷ng c©y

46

CÊu tróc d÷ liÖu2 – Ch¬ng 3. C©y ®á ®en

nµy kh«ng cßn lµ c©y nhÞ ph©n n÷a. Tuy nhiªn ta cã thÓ biÕn ®æi c©y 2-3-4 vÒ c©y nhÞ ph©n vµ ®îc c©y t¬ng ®¬ng lµ c©y ®á ®en. (b)VÉn gi÷ cÊu tróc c©y nhÞ ph©n, nhng níi láng ®iÒu kiÖn vÒ chiÒu cao. VÝ dô t¹i nót P bÊt kú th× chiÒu cao cña c©y con tr¸i vµ c©y con ph¶i lÖch nhau kh«ng qu¸ mét sè k nµo ®ã. Víi k =1 ta ®îc c©y c©n b»ng chiÒu cao næi tiÕng do hai nhµ to¸n häc X« viÕt Anderson Velsky vµ Landis ph¸t minh n¨m 1962, vµ do ®ã cßn ®îc gäi lµ c©y AVL. 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-3-4 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: (1)Mét nót bÊt kú trªn c©y ph¶i cã 1, 2 hoÆc 3 khãa. Trõ nót l¸ 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.

(2)TÊt c¶ c¸c nót l¸ ®Òu cïng møc. (3)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 ®ã. §iÒu kiÖn (3) cã nghÜa lµ c©y 2-3-4 lµ c©y nhiÒu nh¸nh t×m kiÕm. H×nh 3.4 sau m« t¶ mét c©y 2-3-4: 50 20 40

5 10 2 4

70

30

7

15

25

55 65

45

35

42

47 49

52

60 63

75 85

68

72

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ö 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.

47

CÊu tróc d÷ liÖu2 – Ch¬ng 3. C©y ®á ®en

NÕu B lµ ®Ønh trong chøa c¸c khãa k 0, 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 < k 0 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 chÌn x 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 cha 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 < k 0 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: •

Tríc hÕt chÌn x vµo nót B theo thao t¸c chÌn khãa vµo danh s¸ch s¾p thø tù.



NÕu nót l¸ B cha trµn (tøc lµ sau khi chÌn x vÉn cã kh«ng cã 3 khãa) th× kÕt thóc.

• NÕu nót B bÞ trµn, tøc lµ cã 4 khãa k0, k1, k2, k3, Ta t¸ch nót B thµnh

2 nót B1 vµ B2, nót B1 cã c¸c khãa k0, k1 nót thø B2 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 B2 lµ con bªn ph¶i. NÕu nót cha bÞ trµn 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 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 15 B

10

26 35C A

7 15 B

20

10

30

20 30

22 26

35

C

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

48

CÊu tróc d÷ liÖu2 – Ch¬ng 3. C©y ®á ®en

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 sau khi chÌn khãa 22 bÞ trµn, 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 §Ó 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 khãa 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 khã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: - NÕu nót L cha trµn 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 bÞ trµn, tøc lµ cã 4 khãa k 0, k1, k2, k3, ta t¸ch nót L thµnh 2 nót vµ khãa k2 ®î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 cha ®a nót cha xuèng, cßn khãa f chÝnh lµ khãa k3 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 15

10

22 24 E

30 F

34 36 I

40 42

46 48

J

K

49

CÊu tróc d÷ liÖu2 – Ch¬ng 3. C©y ®á ®en

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 15

10

34 36

22 24 E

F

I

40 42

46 48

J

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 15

10

22 26 E

34 36

24 F

I

40 42

46 48

J

K

H×nh 3.8. C©n b»ng l¹i nót F 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µ 1, 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ã

50

CÊu tróc d÷ liÖu2 – Ch¬ng 3. C©y ®á ®en

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ã 4 i 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õ 3 ®©y ta cã h+1 = 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Ø lu 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, nhng l¹i tèn Ýt bé nhí h¬n, ®ã lµ c©y ®á ®en 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 víi c¸c nót ®îc quy íc nhËn mét trong hai mµu ®á hoÆc ®en 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

HoÆc

1

§á

1

§en

2

§á

2

- Víi nót cã 4 con ta chuyÓn nh sau:

1 2 3

§en

§á

1

2 3

§á

51

CÊu tróc d÷ liÖu2 – Ch¬ng 3. C©y ®á ®en

H×nh 3.9. ChuyÓn ®æi c©y 2-3-4 sang c©y ®á ®en Ta gäi c©y nhÞ ph©n ®îc chuyÓn ®æi tõ c©y 2-3-4 theo c¸ch trªn ®©y lµ 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 (tøc lµ con cña nót l¸) ®î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. (Ta cã thÓ thÊy r»ng së dÜ ph¶i quy íc nót l¸ rçng lµ ®en ®Ó trong trêng hîp nót l¸ cã mµu ®á th× vÉn kh«ng cã hai nót kÒ nhau cã cïng mµu ®á).

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 khãa trªn c¸c nót ®á ®îc chÌn vµo nót cha cã mµu ®en theo c¸ch phï hîp víi qu¸ tr×nh t¸ch nót). 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 ®Õn nót l¸ bÊt kú 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. Gi¶ sö sè nót ®en lµ n', khi ®ã møc thÊp nhÊt cña nót l¸ lµ h'=log2(n'+1), lµ nót mµ ®êng ®i tõ gèc ®Õn nã chØ toµn lµ nót cã mµu ®en. Vµ nót l¸ cã møc cao nhÊt lµ h''=2log2(n'+1), lµ nót mµ ®êng ®i tõ gèc ®Õn nã cã mét nöa lµ nó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) (v× 2log2(n'+1) ≤ 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 nót 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

52

CÊu tróc d÷ liÖu2 – Ch¬ng 3. C©y ®á ®en

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 (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

a

Q

b

Q

Xoay tr¸i quanh nót P

c

P

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 nhÞ ph©n t×m kiÕm §Ó cã thÓ x¸c ®Þnh vÞ trÝ ®Ó xoay l¹i c©y, t¹i mçi nót ta sÏ lu 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 l(P) lµ chiÒu cao cña c©y con tr¸i, r(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)=r(P)-l(P) VËy bal(P) cña mét nót bÊt kú trªn c©y AVL chØ cã thÓ nhËn mét trong 3 gi¸ trÞ 0,-1,+1, trong ®ã bal(P) = 0 c©y gèc P c©n b»ng c¶ hai bªn (tr¸i ph¶i b»ng nhau). bal(P) = -1 c©y gèc P lÖch tr¸i. bal(P) = +1 c©y gèc P lÖch ph¶i. Ghi chó. ë ®©y dÔ cã sù hiÓu nhÇm vÒ thuËt ng÷: c©y AVL ®îc coi lµ c©n b»ng nÕu chØ sè c©n b»ng cña tÊt c¶ c¸c nót thuéc tËp hîp {-1, 0, 1}, trong

53

CÊu tróc d÷ liÖu2 – Ch¬ng 3. C©y ®á ®en

khi ®ã theo c¸ch nãi trªn ®©y th× sù lÖch cã nghÜa lµ chiÒu cao c¸c c©y bªn tr¸i vµ bªn ph¶i kh«ng b»ng nhau.

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:

54

CÊu tróc d÷ liÖu2 – Ch¬ng 3. C©y ®á ®en

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) P

-

0

0 0

0

U

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, nhng 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. 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) x

s 1

s

0

-

C

A

B

chiÒ u cao n

chiÒ u cao n

chiÒ u cao n

55

CÊu tróc d÷ liÖu2 – Ch¬ng 3. C©y ®á ®en

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 x 1

A

0

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

-

s1

c

-

b

n

n

s

Xoay ph¶i nót s quanh nót

n

a

0

0

a b

c

x

x

H×nh 3.13.a. Xoay tr¸i c©y s. 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 s 1 1

s

-

C chiÒ u cao n

s2

-

C chiÒ u cao n

56

CÊu tróc d÷ liÖu2 – Ch¬ng 3. C©y ®á ®en

s 2

A chiÒ u cao n

B1 chiÒ u cao x

B2 chiÒ u cao

Xoay tr¸i nót s1

s 1

A chiÒ u cao n

0 B1 chiÒ u cao

B2 chiÒ u cao

x

57

CÊu tróc d÷ liÖu2 – Ch¬ng 3. C©y ®á ®en 0

Xoay ph¶i nót s

s1

0

B1 chiÒ u cao

A chiÒ u cao n

s2 1 B2 chiÒ u cao

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

-

s1 1 1

A chiÒ u cao n

B1 chiÒ u cao

C

s2 B2 chiÒ u cao

-

Xoay tr¸i nót s1

chiÒ u cao n

s 1

0

A

chiÒ u cao n

B1 chiÒ u cao

-

s 2

C B2 chiÒ u cao

chiÒ u cao n

x

x

0

Xoay ph¶i nót s -

A chiÒ u cao n

s2

s1 B1 chiÒ u cao

0 B2 chiÒ u cao x

s

C chiÒ u cao n

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:

58

CÊu tróc d÷ liÖu2 – Ch¬ng 3. C©y ®á ®en

Trêng hîp 1: C©y gèc Trêng Tríc khi hîp thªm nót x a bal(s) = -1 bal(s1)= 0 b1 bal(s) = -1 bal(s1) = 0 bal(s2)=0 b2

bal(s) = -1 bal(s1) = 0 bal(s2)=0

Trêng hîp 2: C©y gèc Trêng Tríc khi hîp thªm nót x a bal(s) = +1 bal(s1)= 0 b1 bal(s) = +1 bal(s1) = 0 bal(s2)=0 b2

bal(s) = +1 bal(s1) = 0 bal(s2)=0

s vèn lÖch tr¸i. Sau khi C¸c phÐp xoay vµ chØ sè thªm nót x c©n b»ng míi bal(s)=-2 bal(s1)= -1

Xoay ph¶i nót s bal(s) = 0, bal(s1) = 0

bal(s)= -2 bal(s1)= +1 bal(s2)=-1

Xoay kÐp: 1. Xoay tr¸i nót s1 2. Xoay ph¶i nót s bal(s)=+1,bal(s1) 0,bal(s2)=0 Xoay kÐp: 1. Xoay tr¸i nót s1 2. Xoay ph¶i nót s bal(s)=0,bal(s1) = bal(s2)=0

bal(s)= -2 bal(s1)= +1 bal(s2)=+ 1

=

-1,

s vèn lÖch ph¶i. Sau khi C¸c phÐp xoay vµ chØ sè thªm nót x c©n b»ng míi bal(s)=+2 bal(s1)= +1

Xoay tr¸i nót s bal(s) = 0, bal(s1) = 0

bal(s)= +2 bal(s1)= -1 bal(s2)=+ 1

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

bal(s)= +-2 bal(s1)= -1 bal(s2)= -1

=

=

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

59

CÊu tróc d÷ liÖu2 – Ch¬ng 3. C©y ®á ®en

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: 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

c

a

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

a n

-

c n1

60

CÊu tróc d÷ liÖu2 – Ch¬ng 3. C©y ®á ®en

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

s1

-

s1

+

s

c

0

a

b

n

n

(=n+1).

Xoay ph¶i nót s quanh nót s1

-

n1

a

c

b

n

n1

n

H×nh 3.14.a. Bal(s1)=0, xoay ph¶i s, ®é cao c©y kh«ng ®æi

Trêng hîp b: bal(s1)=-1. s

s1

-

Xoay ph¶i nót s quanh nót s1

s1

0

s

c

-

a

b

n

n1

0

n1

a

c

b

n

n1

n1

H×nh 3.14.b. Bal(s1)=-1, xoay ph¶i s, c©y thÊp h¬n (nright, bal(s2)=0 s s 1

A chiÒ u cao n-1

s

-

C

1 0 B1 chiÒ u cao

s 2 B2 chiÒ u cao

chiÒ u cao n-1

-

s2 Xoay tr¸i nót s1

s 1

A chiÒ u cao n-1

0 B1 chiÒ u cao

B2 chiÒ u cao

C chiÒ u cao n-1

61

CÊu tróc d÷ liÖu2 – Ch¬ng 3. C©y ®á ®en

Xoay ph¶i nót s

0

s1

0

0

B1 chiÒ u cao

A chiÒ u cao n-1

s2

B2 chiÒ u cao

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
s

-

A B1 chiÒ u cao

Xoay tr¸i nót s1

chiÒ u cao n-1

s 2

chiÒ u cao n-1

s2

C

1

s 1

0

1

B1 chiÒ u cao

chiÒ u cao n-1

chiÒ u cao n-1

s2

s1

0

B2 chiÒ u cao

B1 chiÒ u cao

chiÒ u cao n-1

Xoay ph¶i nót s

C

0

A

B2 chiÒ u cao

A

-

B2 chiÒ u cao

s

C n-1

H×nh 3.16.c.2. Bal(s1)=+1, bal(s2)=-1,xoay kÐp, c©y thÊp h¬n (n
C

1 1

A chiÒ u cao n-1

s

-

B1 chiÒ u cao

s 2

chiÒ u cao n-1

s2 Xoay tr¸i nót s1

s 1

A

B2 chiÒ u cao

Xoay ph¶i nót s

-

chiÒ u cao n-1 0

s2

B1 chiÒ u cao

B2 chiÒ u cao

C chiÒ u cao n-1

62

CÊu tróc d÷ liÖu2 – Ch¬ng 3. C©y ®á ®en -

A chiÒ u cao n-1

H×nh 3.14.c.3. (n
s1 B1 chiÒ u cao

0 B2 chiÒ u cao

s

C n-1

Bal(s1)=+1, bal(s2)=1,xoay kÐp, c©y thÊp h¬n

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 nhng 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. Nhng 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 §Æ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. Ta biÕt r»ng nÕu ®Æt n = F k , khi ®ã n ~ a k víi a ~ 1.61803... lµ “tû sè vµng”. Tõ ®©y cã thÓ tÝnh ®îc k ~ 1.44log2n. §Æt n = Dh , ta cã n = Dh = Gh -1 = Fh+2 - 1 , tõ ®©y n+1 = Fh+2 , suy ra h+2 ~ 1.44log(n+1)

63

CÊu tróc d÷ liÖu2 – Ch¬ng 3. C©y ®á ®en

vµ do ®ã cã thÓ xem 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 ®Ó lu 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*);

64

CÊu tróc d÷ liÖu2 – Ch¬ng 3. C©y ®á ®en

Node* LeftBal(Node*); //Can bang lai cay khi cay con trai cao len 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

a

Q

b

Q

Xoay tr¸i nót P quanh nót Q

c

P

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; }

65

CÊu tróc d÷ liÖu2 – Ch¬ng 3. C©y ®á ®en



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

c

Q

a

b

Xoay ph¶i nót P quanh nót Q

P

a b

c

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

66

CÊu tróc d÷ liÖu2 – Ch¬ng 3. C©y ®á ®en

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; 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 cha, 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.

67

CÊu tróc d÷ liÖu2 – Ch¬ng 3. C©y ®á ®en

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) {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(xkey) {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*/

68

CÊu tróc d÷ liÖu2 – Ch¬ng 3. C©y ®á ®en

//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; } 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

69

CÊu tróc d÷ liÖu2 – Ch¬ng 3. C©y ®á ®en

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 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;

70

CÊu tróc d÷ liÖu2 – Ch¬ng 3. C©y ®á ®en

} p2->bal=0; p->left=RotateLeft(p1); pp=RotateRight(p); };//End of switch(p1->bal) }; return(pp); };//RightBal2 •

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

71

CÊu tróc d÷ liÖu2 – Ch¬ng 3. C©y ®á ®en

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 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; } }

72

CÊu tróc d÷ liÖu2 – Ch¬ng 3. C©y ®á ®en

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;} }; 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;

73

CÊu tróc d÷ liÖu2 – Ch¬ng 3. C©y ®á ®en

} //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 {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.

74

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
5 10 2 4

70

45

30

15

25

35

42

47 49

55 65 52

60 63

80 85 68

75

H×nh 4.1 C©y t×m kiÕm bËc 3.

95

CÊu tróc d÷ liÖu2 – Ch¬ng 4. B - c©y vµ bé nhí ngoµi

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.

76

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

H×nh 4.2 kho¸ (trõ gèc)

43 45

53 57 62

71 72

90 91 92

B- c©y cÊp 2, tÊt c¶ c¸c nót ®Òu cã tõ

2 ®Õn 4

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.

77

CÊu tróc d÷ liÖu2 – Ch¬ng 4. B - c©y vµ bé nhí ngoµi

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 cha 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-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 cha ®Ç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 B

26 30 35 40 C A

7 10 15 18 B

20 30 22 26

35 40

C

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.

78

CÊu tróc d÷ liÖu2 – Ch¬ng 4. B - c©y vµ bé nhí ngoµi

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 nhng 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ã. 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

34 36

22 24 28 30 E

F

I

40 42

46 48

J

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 20 26

38 44

79

CÊu tróc d÷ liÖu2 – Ch¬ng 4. B - c©y vµ bé nhí ngoµi

7 10 15 18

34 36

22 24 28 E

F

I

40 42

46 48

J

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

22 24 26 28 E F

34 36 I

40 42

46 48

J

K

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

20 30 38 44

22 24 26 28 E F

34 36 I

40 42 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.

80

CÊu tróc d÷ liÖu2 – Ch¬ng 4. B - c©y vµ bé nhí ngoµi

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Ï 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 ®Ó lu 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

81

CÊu tróc d÷ liÖu2 – Ch¬ng 4. B - c©y vµ bé nhí ngoµi

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); }; • 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

82

CÊu tróc d÷ liÖu2 – Ch¬ng 4. B - c©y vµ bé nhí ngoµi

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*/ int BTree::NodeSearch(Node* &p, int x) {int i; for(i=0;ikeynum && 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.

83

CÊu tróc d÷ liÖu2 – Ch¬ng 4. B - c©y vµ bé nhí ngoµi

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 ®Ó lu 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]. Lu 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 cha 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. */ 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;

84

CÊu tróc d÷ liÖu2 – Ch¬ng 4. B - c©y vµ bé nhí ngoµi

} //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(kkeynum && 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; } 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);

85

CÊu tróc d÷ liÖu2 – Ch¬ng 4. B - c©y vµ bé nhí ngoµi

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, nhng 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]; pl->keynum--; p->keynum++; return; }; //pl->keynum<=M, tron pl, fp->key[k-1] va p, xoa p roi don dep fp

86

CÊu tróc d÷ liÖu2 – Ch¬ng 4. B - c©y vµ bé nhí ngoµi

pl->key[pl->keynum]=fp->key[k-1]; for(i=0;ikeynum;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;ikeynum-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;ikeynum-1;i++) {fp->key[i]=fp->key[i+1]; fp->son[i+1]=fp->son[i+2]; } fp->keynum--;

87

CÊu tróc d÷ liÖu2 – Ch¬ng 4. B - c©y vµ bé nhí ngoµi

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 ®Ó lu 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 cha 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 nhng fp l¹i cã thÓ bÞ c¹n kiÖt vµ ta l¹i ph¶i c©n b»ng l¹i fp.

88

CÊu tróc d÷ liÖu2 – Ch¬ng 4. B - c©y vµ bé nhí ngoµi

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. 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(kkeynum && 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;ikeynum-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;

89

CÊu tróc d÷ liÖu2 – Ch¬ng 4. B - c©y vµ bé nhí ngoµi

p=p->son[p->keynum]; } //fp la nut la, nut cuc phai se thay x pp->key[k]=fp->key[fp->keynum-1]; 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

90

CÊu tróc d÷ liÖu2 – Ch¬ng 4. B - c©y vµ bé nhí ngoµi

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 lu 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 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ò.

91

C©u hái vµ bµi tËp 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 lu 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 (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µ F1, F2, ..., Fm vµ c¸c tÖp ®Ých ban ®Çu lµ G1, G2, ..., Gm. 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 (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. 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 = 3, c¸c tÖp nguån ban ®Çu lµ F1, F2, F3 vµ c¸c tÖp ®Ých ban ®Çu lµ G1, G2, G3. 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 (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 = 3. 1.8. H·y so s¸nh c¸c ph¬ng ph¸p s¾p xÕp trªn ®©y. 1.9. Cho tÖp A chøa c¸c phÇn tö lµ c¸c sè thùc nh sau: 15 2 29 11 8 6 42 30 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 = 2. d) 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. e) So s¸nh c¸c ph¬ng ph¸p s¾p xÕp trªn. 1.10. Cho tÖp A chøa c¸c phÇn tö lµ c¸c sè thùc nh sau:

CÊu tróc d÷ liÖu2 – C©u hái vµ bµi tËp

2 5 22 20 18 16 6 7 15 14 13 4 H·y thùc hiÖn c¸c c©u hái a, b, c, d, e trong c©u 1.9. ®èi víi tÖp A nµy. 1.11. 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, e trong c©u 1.9. ®èi víi tÖp A nµy. 1.12. 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. M« t¶ ho¹t ®éng cña ph¬ng ph¸p trén ®a pha khi ta cã ban ®Çu tÖp T1 chøa 21 run, tÖp T2 chøa 13 run vµ tÖp T3 th× rçng

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 = (a 0, 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 h(k) lµ hµm lÊy gi¸ trÞ trong tËp hîp {0,1,...,m-1}. b. Cho b¶ng b¨m chia d (tøc lµ b¶ng b¨m sö dông hµm b¨m cã d¹ng h(k)=k%m) 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: 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. Cho b¶ng b¨m H chøa c¸c khãa lµ c¸c sè nguyªn vµ b¶ng cã kÝch thíc lµ m = 7. Hµm b¨m lµ hµm chia d h(x) = x%m, vµ ph¬ng ph¸p tr¸nh ®ông ®é lµ dïng danh s¸ch liªn kÕt ngoµi. Cho d·y A chøa c¸c sè 3, 21, 17, 47, 37, 21, 25, 48. B¹n h·y thªm vµo 3 sè n÷a sao cho c¸c sè míi kh«ng trïng víi c¸c sè cò, sau ®ã h·y m« t¶ qu¸ tr×nh chÌn c¸c sè trªn vµo b¶ng b¨m nãi trªn. Cuèi cïng vÏ s¬ ®å minh häa b¶ng b¨m sau

93

CÊu tróc d÷ liÖu2 – C©u hái vµ bµi tËp

khi ®· chÌn c¸c phÇn tö. 2.6. T¬ng tù nh c©u 2.5. nhng víi m = 15 vµ ph¬ng ph¸p tr¸nh ®ông ®é lµ ph¬ng ph¸p dß tuyÕn tÝnh. 2.7. 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 h(k) lµ hµm lÊy gi¸ trÞ trong tËp hîp {0,1,...,m-1}. b. Gi¶ sö hµm b¨m lµ hµm chia d, tøc lµ h(k)=k%m. 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.

94

CÊu tróc d÷ liÖu2 – C©u hái vµ bµi tËp

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. 2.8. Cho b¶ng b¨m chøa c¸c khãa lµ c¸c sè nguyªn vµ b¶ng cã kÝch thíc lµ m = 10. Hµm b¨m lµ hµm chia d h(x) = x%m, vµ ph¬ng ph¸p tr¸nh ®ông ®é lµ dïng danh s¸ch liªn kÕt trong. a. Gi¶ sö ta cÇn chÌn vµo b¶ng b¨m 6 sè nguyªn kh¸c nhau cã gi¸ trÞ tõ 0 ®Õn 99 trong ®ã 4 sè ®Çu tiªn lµ 13, 9, 8, 47,33. B¹n h·y thªm vµo 2 sè n÷a sao cho c¸c sè míi kh«ng trïng víi c¸c sè cò, sau ®ã h·y m« t¶ qu¸ tr×nh chÌn c¸c sè trªn vµo b¶ng b¨m. Cuèi cïng vÏ s¬ ®å minh häa b¶ng b¨m sau khi ®· chÌn c¸c phÇn tö. b. H·y m« t¶ thao t¸c t×m khãa 42 (khãa nµy cã thÓ kh«ng xuÊt hiÖn trong b¶ng). 2.7. H·y nªu mét vµi nhËn xÐt cña b¹n vÒ c¸c ph¬ng ph¸p tr¸nh ®ông ®é khi cµi ®Æt cÊu tróc d÷ liÖu b¶ng b¨m nh dïng liªn kÕt trong, dïng liªn kÕt ngoµi, dß tuyÕn tÝnh, dß bËc hai.

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 cao nhÊt cã n khãa, 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 khãa. 3.6. H·y ®a ra ®¸nh gi¸ vÒ chiÒu cao cña c©y ®á ®en cao nhÊt cã n khãa, tõ ®ã suy ra ®¸nh gi¸ vÒ thêi gian t×m kiÕm c¸c khãa trªn c©y ®á ®en cã n khãa. 3.7.* V× sao khi ®¸nh gi¸ vÒ thêi gian t×m kiÕm c¸c khãa trªn c©y 2-3-4 hoÆc c©y ®á ®en cã n khãa, ta l¹i ph¶i ®¸nh gi¸ chiÒu cao cña c©y cao nhÊt mµ kh«ng ph¶i lµ chiÒu cao cña c©y thÊp nhÊt? ViÖc ®¸nh

95

CÊu tróc d÷ liÖu2 – C©u hái vµ bµi tËp

gi¸ chiÒu cao cña c©y thÊp nhÊt cã ý nghÜa g×? H·y ®¸nh gi¸ chiÒu cao cña c©y 2-3-4 vµ c©y ®á ®en thÊp nhÊt vµ nãi lªn ý nghÜa cña kÕt qu¶ ®¸nh gi¸. 3.8. 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.9. Cho d·y c¸c khãa 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 b»ng c¸ch lÇn lît chÌn c¸c khãa trªn vµo c©y. ChuyÓn c©y 2-3-4 võa t¹o thµnh c©y ®á ®en t¬ng øng. 3.10. Gi¶ sö ®· t¹o ®îc c©y 2-3-4 nh ë bµi 3.9. 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.11. Gi¶ sö ®· t¹o ®îc c©y 2-3-4 nh ë bµi 3.9 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.12. Nªu ®Þnh nghÜa c©y c©n b»ng chiÒu cao (c©y AVL). 3.13. 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. 3.14. Cho d·y c¸c khãa lµ c¸c sè thùc nh sau: 5 13 9 7 6 4 8 11 H·y t¹o vµ vÏ c©y AVL b»ng c¸ch lÇn lît chÌn c¸c khãa trªn vµo c©y. 3.15. H·y lËp luËn ®Ó ®a ra íc lîng cña c©y AVL cao nhÊt chøa n khãa , tõ ®ã suy ra ®¸nh gi¸ vÒ thêi gian t×m kiÕm c¸c khãa trªn c©y AVL cã n khãa.

Ch¬ng 4. B-c©y 4.1. H·y nªu ®Þnh nghÜa B - c©y cÊp m vµ B-c©y cÊp 2. 4.2. 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. 4.3. Cho d·y A chøa c¸c khãa 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.4. Gi¶ sö ®· t¹o ®îc B-c©y nh ë bµi 4.3. 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.5. Gi¶ sö ®· t¹o ®îc B-c©y nh ë bµi 4.3 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,

96

CÊu tróc d÷ liÖu2 – C©u hái vµ bµi tËp

15. 4.6. H·y lËp luËn ®Ó ®a ra íc lîng cña B-c©y cÊp m cao nhÊt chøa n khãa, tõ ®ã ®a ra ®¸nh gi¸ vÒ ®é phøc t¹p tÝnh to¸n cña c¸c thao t¸c t×m kiÕm, chÌn vµ xãa khãa trªn B-c©y cÊp m vµ B-c©y cÊp 2. 4.7. H·y so s¸nh sù kh¸c biÖt gi÷a B-c©y cÊp 2 vµ c©y 2-3-4. PhÇn THI Thùc hµnh (dù kiÕn): H×nh thøc thi thùc hµnh cña m«n häc nµy lµ lµm bµi tËp lín. Nh thÕ mçi sinh viªn sÏ nhËn mét vÊn ®Ò trong phÇn néi dung m«n häc vµ cµi ®Æt thuËt to¸n thùc hiÖn trªn m¸y tÝnh. C¸c vÊn ®Ò cÇn cµi ®Æt trong m«n häc nµy phÇn lín kh¸ phøc t¹p, do ®ã chóng t«i ®· viÕt s½n c¸c ch¬ng tr×nh mÉu. NhiÖm vô cña sinh viªn lµ ®äc ®Ó hiÓu ®îc c¸c ch¬ng tr×nh quy ®Þnh, vµ cã thÓ viÕt l¹i tõng phÇn mét ch¬ng tr×nh tù lùa chän. Sinh viªn cã thÓ viÕt ch¬ng tr×nh hoµn toµn kh¸c víi ch¬ng tr×nh mÉu, nhng ph¶i chøng tá ®îc lµ ch¬ng tr×nh do chÝnh sinh viªn viÕt. V× kh¶ n¨ng cña c¸c sinh viªn kh«ng ®ång ®Òu, do ®ã chóng t«i ®· ph©n lo¹i c¸c bµi tËp tõ dÔ ®Õn khã ®Ó sinh viªn lùa chän vÊn ®Ò phï hîp víi kh¶ n¨ng cña m×nh. Chóng t«i t¹m ®a ra møc ®iÓm dù kiÕn (nÕu sinh viªn hiÓu râ vµ cã thÓ viÕt l¹i ®îc ch¬ng tr×nh ®· chän) cho tõng lo¹i. Sinh viªn sau khi hoµn thµnh phÇn ®· nhËn vµ ®· ®¹t ®îc ®iÓm dù kiÕn th× gi¸o viªn sÏ hái thªm, chñ yÕu xoay quanh mét sè ch¬ng tr×nh mÉu quy ®Þnh, ®Ó cã thÓ ®¹t ®îc ®iÓm cao h¬n. C¸c ch¬ng tr×nh mÉu quy ®Þnh mµ sinh viªn cÇn hiÓu thªm ®Ó cã thÓ ®¹t ®iÓm cao h¬n ®iÓm dù kiÕn lµ: trén trùc tiÕp (11SXF.CPP), trén tù nhiªn (12SXF.CPP), trén ®a lèi c©n b»ng (13SXF.CPP) vµ b¶ng b¨m dïng danh s¸ch liªn kÕt ngoµi (21HASHLK.CPP). C¸c bµi tËp lo¹i A (7 ®iÓm):

Chän mét trong c¸c c©u sau (trong ngoÆc lµ ch¬ng tr×nh mÉu): 1. Cµi ®Æt thuËt to¸n s¾p xÕp ngo¹i sö dông ph¬ng ph¸p trén trùc tiÕp (11SXF.CPP). 2. Cµi ®Æt thuËt to¸n s¾p xÕp ngo¹i sö dông ph¬ng ph¸p trén run tù nhiªn (12SXF.CPP). 3. Cµi ®Æt b¶ng b¨m dïng danh s¸ch liªn kÕt ngoµi (21HASHLK.CPP). 4. Cµi ®Æt b¶ng b¨m dïng danh s¸ch liªn kÕt trong (22HASHTR.CPP). C¸c bµi tËp lo¹i B (8 ®iÓm):

Chän mét trong c¸c c©u sau: 1. Cµi ®Æt thuËt to¸n s¾p xÕp ngo¹i sö dông ph¬ng ph¸p trén ®a lèi c©n b»ng (13SXF.CPP). 2. ViÕt ch¬ng tr×nh cµi ®Æt tõ ®iÓn dïng 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 ngoµi. 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.

97

CÊu tróc d÷ liÖu2 – C©u hái vµ bµi tËp

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õ. (Tham kh¶o ch¬ng tr×nh 21TUDIEN.CPP) C¸c bµi tËp lo¹i C (9 ®iÓm):

Chän mét trong c¸c c©u sau: 1. Cµi ®Æt c©y AVL (31CAYAVL.CPP). 2. Cµi ®Æt c©y AVL b»ng ph¬ng ph¸p ®Ö quy (33CAYAV2.CPP). 3. Cµi ®Æt c©y AVL trªn tÖp (32CAYAVF.CPP). 4. Cµi ®Æt B-c©y cÊp m (41BTREE.CPP). C¸c bµi tËp lo¹i D (10 ®iÓm):

Chän mét trong c¸c c©u sau: 1. BiÓu diÔn ®å häa c¸c thao t¸c trªn c©y AVL (hoÆc c©y ®á ®en, c©y 23-4, B-c©y cÊp 2). 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; thunhap;}

char ten[25]; int luong;int phucap, int

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: Khëi t¹o hÖ thèng NhËp c¸c nh©n viªn míi. T×m vµ cho hiÖn nh©n viªn biÕt m· nh©n viªn. T×m vµ cho hiÖn nh©n viªn biÕt tªn vµ thu nhËp. Xãa nh©n viªn biÕt m· sè. HiÖn danh s¸ch nh©n viªn theo ®iÖn tho¹i m· sè. HiÖn danh s¸ch nh©n viªn theo l¬ng t¨ng dÇn. Dän dÑp sè liÖu. CÊt sè liÖu vµ tho¸t. NÕu d÷ liÖu lu 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.

98

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 Hång Ch¬ng, CÊu tróc d÷ liÖu, øng dông vµ cµi ®Æt b»ng C, NXB TPHCM, 2000 9. NguyÔn Trung Trùc, CÊu tróc d÷ liÖu, §¹i häc B¸ch khoa TPHCM, 1997 10. NguyÔn Xu©n Huy, ThuËt to¸n, Nhµ xuÊt b¶n Thèng kª, 1988 11.

Robert Sedgewick, CÈm nang thuËt to¸n, NXB KH&KT,1998

12.

Tr¬ng H¶i B»ng, Gi¸o tr×nh CÊu tróc d÷ liÖu 2, §HQG HCM.

Phô lôc. Mét sè ch¬ng tr×nh mÉu viÕt b»ng C++ Ghi chó: C¸c lÖnh sau ë trong phÇn c¸c chØ thÞ tiÒn xö lý cña tÊt c¶ c¸c ch¬ng tr×nh: #include #include <stdlib.h> #include <stdio.h> #include #define true 1 #define false 0 0. Ch¬ng tr×nh 10FILE.CPP: C¸c thao t¸c trªn tÖp nghÞ ph©n //Programmer: Phan Dang Cau, Khoa CNTT, Hoc vien CNBCVT #define sz (sizeof(float)) //--------------------------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 void ViewRun(char *TenTep);//Cho hien cac run trong tep 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 //--------------------------//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);

CÊu tróc d÷ liÖu2 –Phô lôc. Mét sè ch¬ng tr×nh mÉu viÕt b»ng C++

}; //--------------------------//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); }; //--------------------------//Hien thi noi dung file len man hinh void ViewRun(char *TenTep) {float x;int i; FILE* f; f = fopen(TenTep,"rb"); rewind(f); i=1; printf("\n\nCac run tren tep %s:\n",TenTep); while(1) {printf("\n%3d: ",i); while(1) {if(fread(&x,sz,1,f)>0) printf("%5.0f",x); if (EoR(f)) {i++;break;} } if(EoF(f)) break; } fclose(f); }; //--------------------------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); }; //--------------------------int EoF(FILE *f) {float x; if(fread(&x,sz,1,f)>0) {fseek(f,-1.0*sz,1); return(false); }; return(true); } //--------------------------int EoR(FILE *f) {float x,y;

101

CÊu tróc d÷ liÖu2 –Phô lôc. Mét sè ch¬ng tr×nh mÉu viÕt b»ng C++

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); } //--------------------------void main() {clrscr();char ch, *tep = "thu.dat", *ThongBao; while(1) {clrscr(); printf("\n1. Tao tep"); printf("\n2. Xem tep"); printf("\n3. Xem cac run"); printf("\nz. Ket thuc"); printf("\n\nHay chon chuc nang 1 -> z: "); ch=toupper(getch()); if(ch=='Z') break; switch(ch) {case '1': CreateFile(tep); ThongBao="Tep da tao xong, nhan phim bat ky de tiep tuc";break; case '2': ViewFile(tep);printf("\n\nSo phan tu tren tep = %5d",FileNodes(tep)); ThongBao="Xem xong nhan phim bat ky";break; case '3': ViewFile(tep);ViewRun(tep); printf("\n\nSo phan tu tren tep = %5d",FileNodes(tep)); ThongBao="Xem xong nhan phim bat ky";break; } printf("\n\n%s",ThongBao);getch(); } } 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 //Programmer: Phan Dang Cau, Khoa CNTT, Hoc vien CNBCVT #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()

102

CÊu tróc d÷ liÖu2 –Phô lôc. Mét sè ch¬ng tr×nh mÉu viÕt b»ng C++

{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); 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));

103

CÊu tróc d÷ liÖu2 –Phô lôc. Mét sè ch¬ng tr×nh mÉu viÕt b»ng C++

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; while(dem


104

CÊu tróc d÷ liÖu2 –Phô lôc. Mét sè ch¬ng tr×nh mÉu viÕt b»ng 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

=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


105

CÊu tróc d÷ liÖu2 –Phô lôc. Mét sè ch¬ng tr×nh mÉu viÕt b»ng C++

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 //Programmer: Phan Dang Cau, Khoa CNTT, Hoc vien CNBCVT #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"); 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

106

CÊu tróc d÷ liÖu2 –Phô lôc. Mét sè ch¬ng tr×nh mÉu viÕt b»ng C++

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); 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

107

CÊu tróc d÷ liÖu2 –Phô lôc. Mét sè ch¬ng tr×nh mÉu viÕt b»ng C++

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) {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(&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 } }

108

CÊu tróc d÷ liÖu2 –Phô lôc. Mét sè ch¬ng tr×nh mÉu viÕt b»ng C++

//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; 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");

109

CÊu tróc d÷ liÖu2 –Phô lôc. Mét sè ch¬ng tr×nh mÉu viÕt b»ng C++

} 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 //Programmer: Phan Dang Cau, Khoa CNTT, Hoc vien CNBCVT #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]; 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); }

110

CÊu tróc d÷ liÖu2 –Phô lôc. Mét sè ch¬ng tr×nh mÉu viÕt b»ng C++

//--------------------------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); 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);

111

CÊu tróc d÷ liÖu2 –Phô lôc. Mét sè ch¬ng tr×nh mÉu viÕt b»ng C++

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;i0;i++); 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
112

CÊu tróc d÷ liÖu2 –Phô lôc. Mét sè ch¬ng tr×nh mÉu viÕt b»ng C++

{//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;i0) {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] && i0;i++); nWay=i; }; //--------------------------//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");

113

CÊu tróc d÷ liÖu2 –Phô lôc. Mét sè ch¬ng tr×nh mÉu viÕt b»ng C++

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 (110); for(i=0;i
114

CÊu tróc d÷ liÖu2 –Phô lôc. Mét sè ch¬ng tr×nh mÉu viÕt b»ng C++

struct node {int key; node* next; }; node *H[M];//Bang bam la mot mang gom cac con tro chi den cac danh sach //--------------------------int h(int x);//Ham bam, bien doi khoa x thanh vi tri tren bang bam void clear(node* &phead);//Xoa danh sach do phead tro den void init(node* &phead);//Khoi tao danh sach do phead tro den int empty(node* &phead);//Tra ve true neu danh sach do phead tro den rong node* search(node* &phead,int x);//Tim khoa x tren danh sach do phead tro den void insert(node* &phead,int x);//Chen khoa x vao danh sach do phead tro den void dele(node* &phead,int x);//Xoa khoa x tren danh sach do phead tro den void traverse(node* &phead);//Duyet danh sach do phead tro den void clear();//Xoa bang bam void init();//Khoi tao bang bam int empty();//Kiem tra xem bang bam co rong khong node* search(int x);//Tim khoa x trong bang bam void insert(int x);//Chen khoa x vao bang bam void dele(int x);//Xoa khoa x trong bang bam void traverse();//Duyet bang bam //--------------------------//Hash function int h(int x) {return(x%M); } //--------------------------//Xoa danh sach, tuc la giai phong tat ca cac nut trong danh sach. void clear(node* &phead) {node *p,*p1; p=phead; while(p!=NULL) {p1=p; p=p->next; delete p1; } phead=NULL; } //--------------------------//Khoi tao danh sach, dat phead=NULL. void init(node* &phead) {clear(phead); phead=NULL; } //--------------------------//Kiem tra xem danh sach co rong khong. int empty(node* &phead) {return(phead==NULL); }

115

CÊu tróc d÷ liÖu2 –Phô lôc. Mét sè ch¬ng tr×nh mÉu viÕt b»ng C++

//--------------------------//Tim khoa x trong danh sach lien ket do phead chi den, //tra ve dia chi tim thay (tra ve NULL neu khong tim thay) node* search(node* &phead,int x) {node* p=phead; while(p!=NULL) {if(p->key==x) return(p); p=p->next; } return(NULL); }; //--------------------------//Chen x vao danh sach lien ke do phead tro den void insert(node* &phead,int x) {node *pp,*p,*p1; p=search(phead,x); if(p!=NULL) {printf("\nKhoa %4d da co, khong chen duoc!",x);return;} pp = new node; pp->key=x;pp->next=NULL; if(phead==NULL) {phead=pp;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; }; //--------------------------//Xoa khoa x trong danh sach lien ket do phead chi den, void dele(node* &phead,int x) {node *p,*p1,*q; if(phead==NULL) return; if(phead->key==x) {p=phead;phead=phead->next;delete p;return;} p1=NULL; p=phead; while(p!=NULL) {if(p->key==x) {q=p; p1->next=p->next; delete q; return;} p1=p; p=p->next; } printf("\nKhoa %4d khong co, khong xoa duoc!"); }; //--------------------------//Duyet danh sach lien ket do phead chi den, void traverse(node* &phead) {node* p=phead; while(p!=NULL) {printf("%5d",p->key); p=p->next; }

116

CÊu tróc d÷ liÖu2 –Phô lôc. Mét sè ch¬ng tr×nh mÉu viÕt b»ng C++

}; //================================ //Xoa bang bam void clear() {for(int i=0;i<M;i++) clear(H[i]); } //--------------------------//Khoi tao bang bam void init() {for(int i=0;i<M;i++) init(H[i]); } //--------------------------//Kiem tra bang bam co rong khong int empty() {for(int i=0;i<M;i++) if(!empty(H[i])) return(false); return(true); } //--------------------------//Tim khoa x trong bang bam node* search(int x) {int k=h(x);node* p; p=search(H[k],x); return(p); } //--------------------------//Chen x vao bang bam void insert(int x) {int k=h(x); insert(H[k],x); } //--------------------------//Xoa khoa x trong bang bam void dele(int x) {int k=h(x); dele(H[k],x); } //--------------------------//Duyet bang bam void traverse() {int i; printf("\n\nCac khoa tren bang bam:"); for(i=0;i<M;i++) {printf("\n%3d: ",i);traverse(H[i]);} } //--------------------------void InsertMany() {clrscr();int m,i,x;init(); printf("\Nhap du lieu vao bang bam:"); printf("\n1. Nhap truc tiep"); printf("\n2. Tao ngau nhien"); printf("\n\n Hay chon 1 hoac 2: "); fflush(stdin); char ch=getch();

117

CÊu tróc d÷ liÖu2 –Phô lôc. Mét sè ch¬ng tr×nh mÉu viÕt b»ng C++

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(10*m); insert(x); } } }; //=========================== void main() {clrscr();int x,k;node* p; while(true) {clrscr(); //Tao menu printf("\n 1. Chen cac khoa vao bang bam"); printf("\n 2. Tim kiem khoa tren bang bam"); printf("\n 3. Xoa khoa tren bang bam "); printf("\n 4. Duyet bang bam "); printf("\n z. Ket thuc"); printf("\nHay nhan phim tu 1 -> z de chon: "); char chon=toupper(getch()); if(chon=='Z') break; switch(chon) {case '1':InsertMany();break; case '2':printf("\nPhan tu can tim la: ");scanf("%d",&x); k=h(x);p=search(x); if(p!=NULL) printf("\nPhan tu tim thay o vi tri %d: %d",k,p->key); else printf("\nKhong tim thay");break; case '3':printf("\nPhan tu can xoa la: ");fflush(stdin);scanf("%d",&x); dele(x);break; case '4':if(empty()) printf("\nBang bam rong"); else traverse();break; } printf("\n\nNhan phim bat ky de tiep tuc"); getch(); } } 6. Ch¬ng tr×nh 21TUDIEN.CPP: Cµi ®Æt tõ ®iÓn dïng b¶ng b¨m dïng danh s¸ch liªn kÕt ngoµi //Moi phan tu cua bang la con tro chi den dau mot danh sach lien ket //Programmer: Phan Dang Cau, Khoa CNTT, Hoc vien CNBCVT #include <string.h>

118

CÊu tróc d÷ liÖu2 –Phô lôc. Mét sè ch¬ng tr×nh mÉu viÕt b»ng C++

#define M 26 //--------------------------struct node {char word[10], mean[20]; node* next; }; node *H[M];//Bang bam la mot mang gom cac con tro chi den cac danh sach //--------------------------int h(int x);//Ham bam, bien doi khoa x thanh vi tri tren bang bam void clear(node* &phead);//Xoa danh sach do phead tro den void init(node* &phead);//Khoi tao danh sach do phead tro den int empty(node* &phead);//Tra ve true neu danh sach do phead tro den rong node* search(node* &phead,char word[10]);//Tim word tren danh sach do phead tro den void insert(node* &phead, char word[10], char mean[20]); //Chen word vao danh sach do phead tro den void dele(node* &phead,char word[10]);//Xoa khoa x tren danh sach do phead tro den void traverse(node* &phead);//Duyet danh sach do phead tro den void clear();//Xoa bang bam void init();//Khoi tao bang bam int empty();//Kiem tra xem bang bam co rong khong node* search(char word[10]);//Tim khoa x trong bang bam void insert(char word[10], char mean[20]);//Chen tu vao bang bam void dele(char word[10]);//Xoa tu trong bang bam void traverse();//Duyet bang bam //--------------------------//Hash function int h(char word[10]) {char ch=toupper(word[0]); return((ch-65)%M); } //--------------------------//Xoa danh sach, tuc la giai phong tat ca cac nut trong danh sach. void clear(node* &phead) {node *p,*p1; p=phead; while(p!=NULL) {p1=p; p=p->next; delete p1; } phead=NULL; } //--------------------------//Khoi tao danh sach, dat phead=NULL. void init(node* &phead) {clear(phead); phead=NULL; } //---------------------------

119

CÊu tróc d÷ liÖu2 –Phô lôc. Mét sè ch¬ng tr×nh mÉu viÕt b»ng C++

//Kiem tra xem danh sach co rong khong. int empty(node* &phead) {return(phead==NULL); } //--------------------------//Tim tu x trong danh sach lien ket do phead chi den, //tra ve dia chi tim thay (tra ve NULL neu khong tim thay) node* search(node* &phead,char x[10]) {node* p=phead; while(p!=NULL) //strcmpi: so sanh chuoi khong phan biet chu ha chu thuong {if(strcmpi(p->word,x)==0) return(p); p=p->next; } return(NULL); }; //--------------------------//Chen x vao danh sach lien ke do phead tro den void insert(node* &phead,char x[10], char mean[20]) {node *pp,*p,*p1; p=search(phead,x); if(p!=NULL) {printf("\nTu %s da co, khong chen duoc!",x);return;} pp = new node; strcpy(pp->word,x);strcpy(pp->mean,mean); pp->next=NULL; if(phead==NULL) {phead=pp;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; }; //--------------------------//Xoa khoa x trong danh sach lien ket do phead chi den, void dele(node* &phead,char x[10]) {node *p,*p1,*q; if(phead==NULL) return; if(strcmpi(phead->word,x)==0) {p=phead;phead=phead->next;delete p;return;} p1=NULL; p=phead; while(p!=NULL) {if(strcmpi(phead->word,x)==0) {q=p; p1->next=p->next; delete q; return;} p1=p; p=p->next; } printf("\nTu %s khong co, khong xoa duoc!"); };

120

CÊu tróc d÷ liÖu2 –Phô lôc. Mét sè ch¬ng tr×nh mÉu viÕt b»ng C++

//--------------------------//Duyet danh sach lien ket do phead chi den, void traverse(node* &phead) {node* p=phead; while(p!=NULL) {printf("%s(%s) ",p->word,p->mean); p=p->next; } }; //================================ //Xoa bang bam void clear() {for(int i=0;i<M;i++) clear(H[i]); } //--------------------------//Khoi tao bang bam void init() {for(int i=0;i<M;i++) init(H[i]); } //--------------------------//Kiem tra bang bam co rong khong int empty() {for(int i=0;i<M;i++) if(!empty(H[i])) return(false); return(true); } //--------------------------//Tim tu x trong bang bam node* search(char x[10]) {int k=h(x);node* p; p=search(H[k],x); return(p); } //--------------------------//Chen tu vao bang bam void insert(char x[10], char mean[20]) {int k=h(x); insert(H[k],x,mean); } //--------------------------//Xoa khoa x trong bang bam void dele(char x[10]) {int k=h(x); dele(H[k],x); } //--------------------------//Duyet bang bam void traverse() {clrscr(); int i,k;k=0; //printf("\n\nCac tu trong bang bam:"); for(i=0;i<M;i++) {if(!empty(H[i]))

121

CÊu tróc d÷ liÖu2 –Phô lôc. Mét sè ch¬ng tr×nh mÉu viÕt b»ng C++

{printf("\n%3d: ",i);traverse(H[i]);k++;} if(k>20) {k=0;getch();}

} } //--------------------------void InsertMany() {clrscr();int m,i;init();char x[10], mean[20]; printf("\Nhap du lieu vao bang bam:"); printf("\n1. Nhap truc tiep"); 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 tu:\n",m); for(i=0;i<m;i++) {printf("Tieng Anh: ");fflush(stdin);gets(x); printf("Tieng Viet:");fflush(stdin);gets(mean); insert(x,mean); } } else {randomize();int j; for(i=0;i<m;i++) {for(j=0;j<5;j++) {x[j]=65+random(25);mean[j]=65+random(25);} x[j]='\0';mean[j]='\0'; insert(x,mean); } } }; //=========================== void main() {clrscr();char x[10],mean[20];int k;node* p; while(true) {clrscr(); //Tao menu printf("\n 1. Chen cac word vao bang bam"); printf("\n 2. Tim kiem word tren bang bam"); printf("\n 3. Xoa word tren bang bam "); printf("\n 4. Duyet bang bam "); printf("\n z. Ket thuc"); printf("\nHay nhan phim tu 1 -> z de chon: "); char chon=toupper(getch()); if(chon=='Z') break; switch(chon) {case '1':InsertMany();break; case '2':printf("\nTu can tim la: ");fflush(stdin);gets(x); k=h(x);p=search(x);

122

CÊu tróc d÷ liÖu2 –Phô lôc. Mét sè ch¬ng tr×nh mÉu viÕt b»ng C++

}

if(p!=NULL) printf("\nTu tim o vi tri %d: %s(%s)",k,p->word,p->mean); else printf("\nKhong tim thay");break; case '3':printf("\nTu can xoa la: ");fflush(stdin);gets(x); dele(x);break; case '4':if(empty()) printf("\nBang bam rong"); else traverse();break; } printf("\n\nNhan phim bat ky de tiep tuc"); getch(); }

7. Ch¬ng tr×nh 22HASHTR.CPP: Cµi ®Æt b¶ng b¨m dïng danh s¸ch liªn kÕt trong //Programmer: Phan Dang Cau, Khoa CNTT, Hoc vien CNBCVT #define M 10 //--------------------------struct node {int* pkey; int next; }; node H[M];//Bang bam la mot mang gom cac node //--------------------------int h(int x);//Ham bam, bien doi khoa x thanh vi tri tren bang bam void init();//Khoi tao bang bam int empty();//Kiem tra xem bang bam co rong khong int full();//Kiem tra xem bang bam co bi day khong int search(int x);//Tim khoa x trong bang bam, tra ve vi tri tim thay void insert(int x);//Chen khoa x vao bang bam void traverse();//Duyet bang bam //--------------------------//Hash function int h(int x) {return(x%M); } //================================ //Khi tao bang bam void init() {for(int i=0;i<M;i++) {H[i].pkey=NULL;H[i].next=-1;} } //--------------------------//Kiem tra bang bam co rong khong int empty() {for(int i=0;i<M;i++) if(H[i].pkey!=NULL) return(false); return(true); } //--------------------------//Kiem tra bang bam co bi day khong int full() {for(int i=0;i<M;i++) if(H[i].pkey==NULL) return(false); return(true); } //---------------------------

123

CÊu tróc d÷ liÖu2 –Phô lôc. Mét sè ch¬ng tr×nh mÉu viÕt b»ng C++

//Tim khoa x trong bang bam, tra ve vi tri tim duoc int search(int x) {int k,i,j,y,p; k=h(x); if(H[k].pkey==NULL) return(-1);//Khong tim thay y=*H[k].pkey;p=h(y); if(p==k) //y va x co cung gia tri ham bam {i=k; while(H[i].pkey!=NULL) {if(*H[i].pkey==x) return(i); if(H[i].next==-1) break; else i= H[i].next; } return(-1);//Khong tim thay } for(j=M-1;H[j].pkey!=NULL;j--) if(*H[j].pkey==x) return(j); return(-1);//Khong tim thay }; //--------------------------//Chen khoa x vao bang bam void insert(int x) {if(full()) {printf("\nBang bam day, khong chen duoc");return;} if(search(x)>=0) {printf("\nNut da co, khong chen duoc");return;} int k,i,j,y,p; k=h(x); if(H[k].pkey==NULL) //Vi tri k con trong, chen x vao va ket thuc {H[k].pkey=new int;*H[k].pkey=x; return;} y=*H[k].pkey;p=h(y); if(p==k) //x va y co cung gia tri ham bam {i=k;//Lan theo con tro next cho den khi gap next=-1 while(H[i].next!=-1) i= H[i].next;//dung lai khi H[i].next=-1 for(j=M-1;H[j].pkey!=NULL;j--);//Tim vi tri con trong xuat phat tu d y H[i].next=j; H[j].pkey=new int; *H[j].pkey=x; H[j].next=-1; return; } //Truong hop h(x)#h(y), xuat phat tu day ta tim mot vi tri trong de chen for(j=M-1;j>0 && H[j].pkey!=NULL;j--); H[j].pkey=new int; *H[j].pkey=x; H[j].next=-1; return; } //--------------------------//Duyet bang bam void traverse() {int i; if(empty()) {printf("\nBang bam rong!");return;} printf("\n\n k key next:"); for(i=0;i<M;i++)

124

CÊu tróc d÷ liÖu2 –Phô lôc. Mét sè ch¬ng tr×nh mÉu viÕt b»ng C++

{printf("\n%3d:",i); if(H[i].pkey!=NULL) printf("%4d %5d",*H[i].pkey,H[i].next); } } //--------------------------void InsertMany() {clrscr();int m,i,x;init(); printf("\Nhap du lieu vao bang bam:"); printf("\n1. Nhap truc tiep"); 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(10*m); insert(x); } } }; //=========================== void main() {clrscr();int x,k; while(true) {clrscr(); //Tao menu printf("\n 1. Chen cac khoa vao bang bam"); printf("\n 2. Tim kiem khoa tren bang bam"); printf("\n 3. Duyet bang bam "); printf("\n z. Ket thuc"); printf("\nHay nhan phim tu 1 -> z de chon: "); char chon=toupper(getch()); if(chon=='Z') break; switch(chon) {case '1':InsertMany();break; case '2':printf("\nPhan tu can tim la: ");scanf("%d",&x); k=search(x); if(k>=0) printf("\nKhoa tim thay la %d",*H[k].pkey); else printf("\nKhong tim thay");break; case '3':traverse();break;

125

CÊu tróc d÷ liÖu2 –Phô lôc. Mét sè ch¬ng tr×nh mÉu viÕt b»ng C++

}

} printf("\n\nNhan phim bat ky de tiep tuc"); getch(); }

126


Related Documents