You are on page 1of 88

| 


  

Giҧng viên: Văn Thiên Hoàng


Đҥi hӑc Kӻ Thuұt Công NghӋ TP. HCM
v 
D [n tұp kiӃn thӭc vӅ xӱ lý tұp tin.
D Trình bày cách phân tích, giҧi thích hoҥt đӝng và
thӵc hiӋn giҧi thuұt đӋ quy, tӯ đó phân loҥi các loҥi
đӋ quy.
D BiӃt và hiӇu thӃ nào là chia đӇ trӏ. Làm quen vӟi mӝt
vài giҧi thuұt chia đӇ trӏ cơ bҧn.

KTLT Nâng cao 2008 - Văn Thiên Hoàng - Khoa CNTT V


Ä 
D Cơ bҧn vӅ tұp tin
D ĐӋ quy
D Chia đӇ trӏ

KTLT Nâng cao 2008 - Văn Thiên Hoàng - Khoa CNTT š


u 
 
D $ liӋu nhұp iChương trình i $ liӋu xuҩt
Bàn phím Màn hình
Đĩa (file) Đĩa (file)
Modem Modem
..... Máy in
....

KTLT Nâng cao 2008 - Văn Thiên Hoàng - Khoa CNTT ß


u 
 
D HӋ điӅu hành xác đӏnh 1 file bҵng Absolute path
hay Relative path. Đó là 1 chuӛi ký tӵ.
D Ví dө đưӡng dүn tuyӋt đӕi trong C:
³C:\\TM1\\TM11\\f1.txt´ hoһc
³C:/TM1/TM11/f1.txt´ hoһc
D Vӟi 1 file nҵm trong thư mөc hiӋn hành, chӍ cҫn chӍ
đӏnh file này bҵng tên file ngҳn gӑn (relative path).
Ví dө : ³nhanvien.dat´

KTLT Nâng cao 2008 - Văn Thiên Hoàng - Khoa CNTT ]


K 
D Hai dҥng lưu tr d liӋu trong file cӫa C
D |   : Mӑi d liӋu đưӧc lưu dҥng ký tӵ ký sӕ ( mã
ascii). Thí dө có 2 d liӋu ³AB´, 12 đưӧc lưu lên text
file cách nhau khoҧng trӕng:



  
V

D    : Mӑi d liӋu đưӧc lưu dҥng biӇu diӉn nhӏ
phân cӫa d liӋu i $ liӋu ch đưӧc lưu dҥng mã
ASCII, còn d liӋu sӕ đưӧc lưu dҥng nhӏ phân cӫa sӕ.
Ví dө có 2 d liӋu ³AB´, 12(int) lưu lên binary file:



    V

KTLT Nâng cao 2008 - Văn Thiên Hoàng - Khoa CNTT ”


K 
D Hai loҥi lưu tr khác nhau nên viӋc truy xuҩt d liӋu tӯ file ra
biӃn cҫn đӃn các hàm thư viӋn khác nhau.
D Binary file đưӧc dùng đӇ lưu tr d liӋu dҥng cҩu trúc có kích
thưӟc cӕ đӏnh. Khi ghi biӃn cҩu trúc lên file sӁ ghi 1 khӕi có
kích thưӟc cӕ đӏnh, và khi đӑc tӯ file ra biӃn cҩu trúc cũng
đӑc tӯ file theo tӯng khӕi có kích thưӟc cӕ đӏnh.
D Muӕn lұp trình vӟi file cҫn phҧi biӃt dҥng lưu tr cũng như ý
nghĩa cӫa d liӋu trong file.
D z   : file có d liӋu sӁ đưӧc truy cұp đӇ đưa vào biӃn.
D   : File sӁ chӭa trӏ cӫa biӃn khi trӏ cӫa biӃn đưӧc ghi
vào.

KTLT Nâng cao 2008 - Văn Thiên Hoàng - Khoa CNTT ¨


|     

byte '
K     

   
(3) OS đӑc d liӋu
code segment miêu tҧ tұp tin

...........

(4) Đӏa chӍ file ...........


desc. đưa vào   
biӃn f cӫa
chương trình .....  !"

$ata segment
(1)chương (2) OS kiӇm
Bӝ nhӟ cӫa trình nhӡ OS tra sӵ tӗn tҥi
chương trình C mӣ tұp tin cӫa tұp tin
 z   '

KTLT Nâng cao 2008 - Văn Thiên Hoàng - Khoa CNTT '
| 
D Khai báo biӃn tұp tin trong C
FILE* f ;
D Chú ý:
- KiӇu FILE đưӧc khai báo trong thư viӋn stdio.h
- Khai báo File * f; là SAI.
D Thao tác tұp tin
- Đӑc d liӋu tӯ tұp tin ra biӃn i Đӑc file
- Ghi d liӋu tӯ biӃn vào tұp tin i Ghi file

KTLT Nâng cao 2008 - Văn Thiên Hoàng - Khoa CNTT 


u

1. Chӑn sách 1. Chӑn file (hàm main làm)
2. Mӣ sách đӇ đӑc 2. Mӣ file đӇ đӑc
3. Chӑn vӏ trí sӁ đӑc 3. Chӑn vӏ trí sӁ đӑc
4. Lһp khi chưa xong 4. Lһp khi chưa xong
‡ Đӑc data vào óc ‡ Đӑc data tӯ fileibiӃn
‡ Xӱ lý data trong óc ‡ Xӱ lý biӃn
5. Đóng sách 5. Đóng file

u  #
NӃu đӑc d liӋu tӯ đҫu file thì bӓ qua bưӟc chӑn vӏ trí sӁ đӑc.
Vӏ trí hiӋn hành cӫa file ngay sau khi mӣ file là đҫu file.
NӃu viӃt hàm thì tên file là tham sӕ.

KTLT Nâng cao 2008 - Văn Thiên Hoàng - Khoa CNTT 


u
 
1. Chӑn sách 1. Chӑn file (hàm main làm)
2. Mӣ sách đӇ ghi 2. Mӣ file đӇ ghi
3. Chӑn vӏ trí sӁ ghi 3. Chӑn vӏ trí sӁ ghi
4. Lһp khi chưa xong 4. Lһp khi chưa xong
‡ Chuҭn bӏ data trong óc ‡ Chuҭn bӏ trӏ cho biӃn
‡ Ghi data trong óc lên sách ‡ Ghi biӃn i File
5. Đóng sách 5. Đóng file

u  #
` NӃu ghi d liӋu ngay tӯ đҫu file thì bӓ qua bưӟc chӑn vӏ trí sӁ ghi.
Vӏ trí hiӋn hành cӫa file ngay sau khi mӣ file là đҫu file.
` NӃu viӃt hàm thì tên file là tham sӕ.
` NӃu trӏ cӫa biӃn đã có rӗi thì bӓ qua bưӟc 4.1
KTLT Nâng cao 2008 - Văn Thiên Hoàng - Khoa CNTT 
ë 
D ViӃt chương trình đӑc mӝt dãy sӕ có n phҫn tӱ lưu
trong tұp tin có tên ³c:/$uLieu.txt´, hiӇn thӏ các sӕ
chҹn lên màn hình console và viӃt các sӕ lҿ ra tұp
tin ³c:/Le.txt´.

KTLT Nâng cao 2008 - Văn Thiên Hoàng - Khoa CNTT V


u     u
D Thư viӋn stdio.h ĐӇ tham khҧo stdio.h, đһt con nháy vào
dưӟi ch stdio.h, gõ Ctrl + F1

KTLT Nâng cao 2008 - Văn Thiên Hoàng - Khoa CNTT š


v
D z    !     $  !   % 
D mode
|       !

$    %


&$ & & & $ '  ()   (* + ,
   %$ - .     /
0$ 0 0 - (1 23 (4 23 ' 
&0$ &0 &0 - (1 23 (4 23 ' 
0$ 0 0 - (1 23 (4 0 '  - 5  $ -
.     + ,
D Trҧ trӏ: NULL : thҩt bҥi Khác NULL: thành công.
D Ví dө: FILE* f = fopen(³c:/$ulieu.txt´ , ³r´ );

KTLT Nâng cao 2008 - Văn Thiên Hoàng - Khoa CNTT ß


v
D Mӝt tұp tin sau khi mӣ đưӧc quҧn lý thông qua mӝt
con trӓ FILE.
D Khi mӣ tұp tin (wb, rb), con trӓ FILE chӍ đӃn đҫu tұp
tin.
D Khi mӣ tұp tin (ab), con trӓ FILE chӍ đӃn cuӕi tұp tin.
D Con trӓ FILE chӍ đӃn tӯng byte trong tұp tin nhӏ
phân
D Sau mӛi lҫn đӑc tұp tin, con trӓ FILE sӁ di chuyӇn đi
mӝt sӕ byte bҵng kích thưӟc (byte) cӫa khӕi d liӋu
đӑc đưӧc.

KTLT Nâng cao 2008 - Văn Thiên Hoàng - Khoa CNTT ]


$    
D VӅ đҫu file : 2%  & % z  
D $ӡi n byte tӯ 1 vӏ trí:
- ! " z  $  ' $  ' !
- pos = SEEK_SET ( hҵng 0) : tӯ đҫu file
- pos = SEEK_CUR ( hҵng 1): tӯ vӏ trí hiӋn hành
- pos = SEEK_EN$ (hҵng 2): tӯ cuӕi file
- n>0 : dӡi tӟi, n<0: dӡi lui, n=0: đӭng tҥi chӛ
- $ӡi qúa biên: gây lӛi trҧ vӅ -1L
D Lҩy vӏ trí hiӋn hành trong file:
 '  z  

KTLT Nâng cao 2008 - Văn Thiên Hoàng - Khoa CNTT ”


|   !   
D ë. 6  "7  . .
D Lҩy vӏ trí hiӋn hành
  ' !z  $ !8 !
D ThiӃt lұp vӏ trí hiӋn hành tӯ vӏ trí đã lưu
  ! !z  $  ! !8 !
D Ví dө:
long filelength(const char* fname)
{
FILE *f = fopen(fname, ³r´);
fseek(f , 0, SEEK_EN$);
long len = ftell(f);
fclose(f);
return len;
}

KTLT Nâng cao 2008 - Văn Thiên Hoàng - Khoa CNTT ¨


à" #$%

|  9 2. :4  i  ;   i 


Ký tӵ char c c=fgetc(f); fputc(c,f);

Chuӛi: char S[]; fgets(S, n, f) fputs (S,f);

Sӕ fscanf(f,´format´, &var); fprintf(f,´format´, var);

n cҩu trúc nhӏ size_t fread int fwrite


phân (&Rec,sizeof(struct),n,f) (&Rec,sizeof(struct),n,f )
Đӑc chuӛi char * fgets ( char *Str, int int fputs ( const char *Str,
NumOfChar, FILE *f ); FILE * f );

KTLT Nâng cao 2008 - Văn Thiên Hoàng - Khoa CNTT '
à  
D   ! z  
D Trҧ trӏ: 0: thành công
D Trҧ trӏ EOF ( hҵng -1) thҩt bҥi
D Ví dө:
m  mm 
   

   
    
m      !
m   

 
"

KTLT Nâng cao 2008 - Văn Thiên Hoàng - Khoa CNTT 


v &' ( 
D KiӇm tra hӃt file chưa?
- int feof(FILE* f)
Trҧ trӏ: 1: HӃt file rӗi
Trҧ trӏ 0: chưa hӃt file
D Đәi tên/ Huӹ 1 file đã đóng
- int rename (const char* oldName, const char* newName);
- int remove (const char* filename);
Trҧ trӏ 0: thành công
Trҧ trӏ -1: thҩt bҥi
OS không thӇ đәi tên/ hӫy 1 file đang mӣ

KTLT Nâng cao 2008 - Văn Thiên Hoàng - Khoa CNTT V


ë 
//nҥp thư viӋn
#include <stdio.h>
#define MAX 100
void main(){
//khai báo con trӓ tұp tin
FILE * f;
//khai báo mҧng arr
int arr[MAX];
//mӣ tұp tin
f=fopen(³c:/dulieu.txt´, ³r´);

KTLT Nâng cao 2008 - Văn Thiên Hoàng - Khoa CNTT V


ë 
//kiem tra mo thanh cong khong?
if (!f) {
printf(³Khong mo duoc tap tin!´);
return;
}
//mӣ thành công và đӑc tӯng sӕ
int n=0;
while (!feof(f)){
fscanf(f, ³%d´, &arr[n]);
if (arr[n]%2==0) printf(³%4d´,arr[n]); //hien thi so chan
n++;
}//đӑc hӃt tұp tin
fclose(f); //đóng tұp tin lҥi

KTLT Nâng cao 2008 - Văn Thiên Hoàng - Khoa CNTT VV


ë 
//mӣ tұp tin ra đӇ viӃt kӃt quҧ vào
f = fopen(³sole.txt´, ³w´);
//kiem tra mo thanh cong khong?
if (!f) {
printf(³Khong mo duoc tap tin!´);
return;
} //mӣ thành công
//lһp tӯng phҫn tӱ mҧng, kiӇm tra là sӕ nguyên tӕ
for (int i=0; i<n; i++)
if( arr[i] % 2)
//viӃt sӕ nguyên tӕ vào tұp tin
fprintf(f, ³%4d´, arr[i]);
fclose(f); //đóng tұp tin lҥi
} //kӃt thúc hàm main

KTLT Nâng cao 2008 - Văn Thiên Hoàng - Khoa CNTT Vš


ù
D ViӃt chương trình đӑc mӝt chuӛi tӕi đa 100 kí tӵ tӯ
bàn phím. Lưu các ký tӵ là nguyên âm vào tұp tin
³NguyenAm.txt´. Đӑc các kí tӵ tӯ tұp tin này và hiӇn
thӏ lên màn hình console.

KTLT Nâng cao 2008 - Văn Thiên Hoàng - Khoa CNTT Vß


ù&)
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
const char STRNA[] = ³AEIOU´; //các nguyên âm
void main()
{
FILE * f; //con trӓ tұp tin
char ch; //lưu ký tӵ gõ vào tư bàn phím
// mӣ tұp tin mӟi đӇ ghi
if ((f = fopen (³NguyenAm.txt´, ³w´ )) == NULL )
{
printf ( ³Create file error \n´);
exit (1);
}
while (( ch = getche() ) != µ\r¶ ) // đӑc cho đӃn khi gһp ENTER
if(strchr(STRNA,ch)) putc (f, ch ); //ghi vào tұp tin nguyên âm này

KTLT Nâng cao 2008 - Văn Thiên Hoàng - Khoa CNTT V]


ù&)
fclose ( f );
//mӣ tұp tin này ra xem
if ((f = fopen (³NguyenAm.txt´, ³r´ )) == NULL )
{
printf ( ³Open file error \n´);
exit (1);
}
printf(³Cac nguyen am la: ´);
while (( ch = getc( f )) != EOF ) // đӑc cho đӃn hӃt tұp tin
//hiӇn thӏ các kí tӵ này lên màn hình
printf(³%c´,ch);
fclose ( f );
}

KTLT Nâng cao 2008 - Văn Thiên Hoàng - Khoa CNTT V”


t)* ! 
D File nhӏ phân thưӡng đưӧc dùng đӇ lư tr cҩu trúc
có kích thưӟc cӕ đӏnh.
D Ví dө:
- struct HS { char Name[31]; int d; }
- Kích thưӟc cӫa cҩu trúc: 33 bytes.
D Mӝt đơn vӏ đӑc ghi file là 1 cҩu trúc.
D Không cҫn biӃt cҩu trúc mà thao tác theo tӯng khӕi
d liӋu đӇ trong buffer (bӝ đӋm).

KTLT Nâng cao 2008 - Văn Thiên Hoàng - Khoa CNTT V¨


ù
D ViӃt chương trình nhұp vào mӝt danh sách n sinh
viên. Mӛi sinh viên lưu thông tin vӅ (hӑ tên, năm
sinh, điӇm trung bình). Lưu n sinh viên này vào tұp
tin ³danhsach.txt´. Đӑc các danh viên tӯ tұp tin này
vào chương trình, hiӇn thӏ lên màn hình nh ng sinh
viên có điӇm trung bình >5.0.

KTLT Nâng cao 2008 - Văn Thiên Hoàng - Khoa CNTT V'
à+
D ĐӋ quy là mӝt thuұt toán dùng đӇ đơn giҧn hóa nh ng bài
toán phӭc tҥp bҵng cách phân nhӓ phép toán đó thành
nhiӅu phҫn đӗng dҥng. Qua viӋc giҧi nh ng bài toán
đưӧc phân nhӓ này, nh ng lӡi giҧi sӁ đưӧc kӃt hӧp lҥi đӇ
giҧi quyӃt bài toán lӟn hơn.
D v  !5 27 %< (= >
1. Đӏnh nghĩa sӕ tӵ nhiên
0 là sӕ tӵ nhiên
N là sӕ tӵ nhiên n-1 là sӕ tӵ nhiên
2. Đӏnh nghĩa giai thӯa cӫa n
0! là 1
NӃu n>0, n! = n *(n-1)!

KTLT Nâng cao 2008 - Văn Thiên Hoàng - Khoa CNTT V


%+
D r  (= > : Hàm đӋ quy là mӝt hàm trong đó có
dùng lӡi gӑi hàm đӃn chính bҧn thân nó.
D Bài toán giҧi bҵng thuұt giҧi đӋ quy phҧi có điӅu
kiӋn dӯng.
D Thuұt toán đӋ quy trên máy tính có thӇ bӏ giӟi hҥn
bӣi dung lưӧng bӝ nhӟ do lӡi gӑi hàm liên tiӃp.

KTLT Nâng cao 2008 - Văn Thiên Hoàng - Khoa CNTT š


%+
Ví dө hàm đӋ quy như sau: void main()
int Sum(int n) {
{ printf(³Tong cac so tu 1-3 la:
if (n==0) return 0; %d´, Sum(3));
// gӑi đӋ quy đӃn chính bҧn getch();
// thân hàm sum }
return (n+Sum(n-1));
} main

c c c c

   
 Sum(3) Sum (2) Sum (1) Sum (0)

KTLT Nâng cao 2008 - Văn Thiên Hoàng - Khoa CNTT š


ù
D ViӃt chương trình nhұp vào sӕ nguyên n, tính n! và
hiӇn thӏ kӃt quҧ lên màn hình (bҵng 2 cách đӋ quy
và không đӋ quy).
- Đӏnh nghĩa n giai thӯa không đӋ quy

„  „„
- Đӏnh nghĩa đӋ quy

  „
„ 
 „  „ „  
°

KTLT Nâng cao 2008 - Văn Thiên Hoàng - Khoa CNTT šV


ù&)
//Phương pháp thӭ nhҩt là dùng vòng lһp (không đӋ quy)
long GT(int n)
{
long result = 1;
for(int i=1; i <= n; i++)
result *= i;
return result;
}
//Phương pháp thӭ hai là dùng hàm đӋ quy:
long Giaithua(int n)
{
if (n == 0) return 1;
else return (n*Giaithua(n-1));
}

KTLT Nâng cao 2008 - Văn Thiên Hoàng - Khoa CNTT šš


ù
D Tìm trӏ phҫn tӱ thӭ n cӫa 1 cҩp sӕ cӝng có sӕ hҥng
đҫu là a, công sai là r
Un = a nӃu n=1
Un = r + Un-1
D Tìm trӏ phҫn tӱ thӭ n cӫa 1 cҩp sӕ nhân có sӕ hҥng
đҫu là a, công bӝi là q
Un = a, n=1
Un = q*Un-1
Bҥn tӵ viӃt

KTLT Nâng cao 2008 - Văn Thiên Hoàng - Khoa CNTT šß


K  %+
D Tùy thuӝc cách diӉn đҥt tác vө đӋ quy mà có các
loҥi đӋ quy sau
‡ ĐӋ quy tuyӃn tính.
‡ ĐӋ quy nhӏ phân.
‡ ĐӋ quy phi tuyӃn
‡ ĐӋ quy hӛ tương

KTLT Nâng cao 2008 - Văn Thiên Hoàng - Khoa CNTT š]


à+, 
D |   '4  ?  7 /
Un = a nӃu n=1 ( trӏ thӭ n cӫa cҩp sӕ cӝng)
Un = r + Un-1 , n>1

double U (int n, double a, double r)


{
if (n==1) return a;
return r + U(n-1,a,r);
}

KTLT Nâng cao 2008 - Văn Thiên Hoàng - Khoa CNTT š”


à+ ! 
D Thân hàm gӑi 2 lҫn chính nó.
D Ví dө: Chuӛi sӕ Fibonacci: 1 1 2 3 5 8 13 ...
- Un = 1, n=1,2
- Un = Un-2 + Un-1 , n>2

 '    
@
  AV   
   BV 0  B
C

KTLT Nâng cao 2008 - Văn Thiên Hoàng - Khoa CNTT š¨


à+ ,
D Thân hàm ü  gӑi 1 sӕ lҫn chính nó
- Un = n , n <6
- Un = Un-5 + Un-4 + Un-3 + Un-2 + Un-1 ,n >6

 ' D    
@
  A”   
 '  
     ] E BB 0 D B
  
C

KTLT Nâng cao 2008 - Văn Thiên Hoàng - Khoa CNTT š'
à+  
D r  (= > '4 
- D  $ A]
- D  D B 0 ; BV $ E]
- ;  Bš $ A'
- ;  D B 0 ; BV $ E'
D u  (F
ü „
 „ „
ü „   „ „{
 „  „ „
 „ „ 
„
}
ü „
 „ „{
 „  „ „
 „ „ 
„
}

KTLT Nâng cao 2008 - Văn Thiên Hoàng - Khoa CNTT š


ð  -%   +
D Thông sӕ hóa bài toán.
D Tìm các điӅu kiӋn biên(chһn), tìm giҧi thuұt cho các
tình huӕng này.
D Tìm giҧi thuұt tәng quát theo hưӟng đӋ quy lui dҫn
vӅ tình huӕng bӏ chһn.

KTLT Nâng cao 2008 - Văn Thiên Hoàng - Khoa CNTT ß


ð  -%   +
D |7 G '  H ' $  ? I
D Thông sӕ hóa: int*a, int n
D ĐiӅu kiӋn biên: Mҧng 0 phҫn tӱ thì tәng bҵng 0.
D Giҧi thuұt chung:
Sum(a,n) = a[0] + a[1] + a[2] + ... + a[n-2] +a[n-1]

$ B
Sum (a,n) = 0 , n=0
a[n-1] + Sum(a, n-1) , n>0

D Vӟi các thuұt toán đӋ quy trên mҧng, ta nên !  


sӕ phҫn tӱ cӫa mҧng.

KTLT Nâng cao 2008 - Văn Thiên Hoàng - Khoa CNTT ß


ð  -%   +
Thông sӕ hóa: int*a, int n
ĐiӅu kiӋn biên: Mҧng 1 phҫn tӱ thì trӏ lӟn nhҩt là a[0].
Giҧi thuұt chung:
Max(a,n) = a[0] a[1] a[2] ... a[n-2] + a[n-1]
v$ B
Max (a,n) = a[0] , n=1
a[n-1] > Max(a, n-1)? a[n-1] : Max(a,n-1)

Thuұt toán đӋ quy tìm trӏ nhӓ nhҩt cӫa mҧng?

KTLT Nâng cao 2008 - Văn Thiên Hoàng - Khoa CNTT ßV


ù| Ä 
D TruyӅn thuyӃt kӇ rҵng: Mӝt nhà toán hӑc Pháp sang Đông
$ương đӃn mӝt ngôi chùa cә ӣ Hà Nӝi thҩy các vӏ sư đang
chuyӇn mӝt chӗng đĩa quý gӗm 64 đĩa vӟi kích thưӟc khác
nhau tӯ cӝt A sang cӝt C theo cách:
- Mӛi lҫn chӍ chuyӇn mӝt đĩa
- Khi chuyӇn có thӇ dùng mӝt cӝt trung gian B
- Trong suӕt quá trình chuyӇn các chӗng đĩa ӣ các cӝt luôn
đưӧc xӃp đúng (đĩa có kích thưӟc bé đưӧc đһt trên đĩa có
kích thưӟc lӟn).
D Khi đưӧc hӓi các vӏ sư cho biӃt khi chuyӇn xong chӗng đĩa là
đӃn ngày tұn thӃ.
D Vì vӟi n đĩa cҫn 2n ± 1 lҫn chuyӇn đĩa
D Vӟi n=64 i T=(264 ± 1)* t. giҧ sӱ t=1/100s i T = 5.8 tӹ năm.

KTLT Nâng cao 2008 - Văn Thiên Hoàng - Khoa CNTT ߚ


ù| Ä 

KTLT Nâng cao 2008 - Văn Thiên Hoàng - Khoa CNTT ßß


ù| Ä 

V
š
 !  !

š V 


V š

 !
V
 š

u
KTLT Nâng cao 2008 - Văn Thiên Hoàng - Khoa CNTT ß]
Ä .
D Hàm đӋ quy là hàm mà trong thân hàm lҥi gӑi chính nó.
D Giҧi thuұt đӋ quy đҽp (gӑn gàng, dӉ chuyӇn thành chương
trình).
D HÀM Đӊ QUY: Vӯa tӕn bӝ nhӟ vӯa chҥy chұm
D NhiӅu ngôn ng không hӛ trӧ giҧi thuұt đӋ quy (Fortran).
D NhiӅu giҧi thuұt rҩt dӉ mô tҧ dҥng đӋ quy nhưng lҥi rҩt khó
mô tҧ vӟi giҧi thuұt không-đӋ-quy.
D Hàm đӋ quy kém hiӋu qӫa vì: tӕn bӝ nhӟ và gӑi hàm qúa
nhiӅu lҫn. Tuy nhiên viӃt hàm đӋ quy rҩt ngҳn gӑn

KTLT Nâng cao 2008 - Văn Thiên Hoàng - Khoa CNTT ߔ


ù
D $ùng kӻ thuұt đӋ quy đӇ giҧi phương trình f(x) trong
khoҧng [a,b] vӟi sai sӕ epsilon.
D Gӑi px là pointer cӫa nghiӋm
if (f(a).f(b)>0) return NULL (không có nghiӋm)
else if (b-a <= epsilon) return &a;
else
{ c=(b+a)/2) ;
if (f(a).f(c)<=0) return Tìm nghiӋm trong đoҥn [a,c];
else return Tìm nghiӋm trong đoҥn [c,b];
}

KTLT Nâng cao 2008 - Văn Thiên Hoàng - Khoa CNTT ߨ


u   !/$ u+ 
D Giҧi thuұt phân rã vҩn đӅ thành nh ng vҩn đӅ con, giҧi
nh ng vҩn đӅ con này và kӃt hӧp nh ng lӡi giҧi cӫa nh ng
vҩn đӅ con thành lӡi giҧi cho vҩn đӅ nguyên thӫy.
D ChiӃn lưӧc này bao gӗm 3 bưӟc sau đây ӣ mӛi cҩp đӋ quy:
- p    (divide) đҫu vào thành các bài toán con
-  
(recur): giҧi quyӃt các bài toán con bҵng gӑi đӋ quy.
- (Conquer, combine): KӃt hӧp các giҧi pháp tìm đưӧc đӇ
giҧi quyӃt bài toán.
D Chú ý: đӝ phӭc tҥp giҧi thuұt thưӡng là:
(log n × (divide(n) + combine(n))).

KTLT Nâng cao 2008 - Văn Thiên Hoàng - Khoa CNTT ß'
u
%  
D Sҳp xӃp trӝn
- Chia: chӑn điӇm gi a O(1)
- ĐӋ quy: Sҳp xӃp cho hai nӱa đưӧc chia
- Trӏ: Trӝn hai nӱa đã đưӧc sҳp xӃp O(n)
i Tәng chi phí sҳp xӃp là O(nlogn)
D Sҳp xӃp nhanh
- Chia: Phân danh sách đҫu vào thành hai phҫn dӵa vào
cӝt mӕc O(n)
- ĐӋ quy: sҳp xӃp trên hai nӱa
- Trӏ: kӃt nӕi hai nӱa đã đưӧc sҳp xӃp O(n)
i Tәng chi phí là O(nlogn)
D Tháp Hà Nӝi, chuӛi Fibonacci..

KTLT Nâng cao 2008 - Văn Thiên Hoàng - Khoa CNTT ß


v 0 1 2%
&'()*  + &'() ,-./0
"    # $ %    % $ "   #

"    # $ %   "    % $ #
#

"    # $ %  "    $ #  %

"    # $ %  "    # $ % 

"    # $ % 

KTLT Nâng cao 2008 - Văn Thiên Hoàng - Khoa CNTT ]


03, 
D Đҫu vào: Mҧng A lưu n sӕ, p,r chӍ sӕ phҫn tӱ đҫu
và cuӕi dãy sӕ.
D Đҫu ra: Mҧng A đưӧc sҳp xӃp
D | 6 9
v !  $ $ 
 p <
  „ (p+ )/2|
v    (, p, )
v    (, +1, )
v  (, p, , ) // trӝn [p] vӟi [ ]
D Gӑi hàm:
MergeSort(, 1, )

KTLT Nâng cao 2008 - Văn Thiên Hoàng - Khoa CNTT ]


03, 
D Đҫu vào: Mҧng A lưu n sӕ, p,r chӍ sӕ phҫn tӱ đҫu
và cuӕi dãy sӕ.
D Đҫu ra: Mҧng A đưӧc sҳp xӃp
D | 6 9
v !  $ $  JJ| 
 p <
  „ (p+ )/2| //vӏ trí gi a dãy O(1)
v    (, p, ) //T(n/2)
v    (, +1, ) //T(n/2)
v  (, p, , ) // trӝn [p] vӟi [ ] O(n)
D Gӑi hàm:
MergeSort(, 1, )

KTLT Nâng cao 2008 - Văn Thiên Hoàng - Khoa CNTT ]V


|   v /
v ' $ $ $ 
D Đҫu vào: 2 mҧng A[p..q] và
1 1 „  ± p + 1 //sӕ phҫn tӱ mҧng trái
 2 „ ±  //sӕ phҫn tӱ mҧng phҧi A[q..r] đã đưӧc sҳp xӃp.
š   „ 1  1 //chép ra mҧng L D Đҫu ra: Trӝn A[p..q] và
4 % ã[] „ [p +  ± 1]
5 //chép vào mҧng phҧi A[q..r] vào A[p..r]. A[p..r]
”  W „ 1  2 //chép ra mҧng R đưӧc sҳp xӃp.
7 % M[W] „ [ + W]
ã[+1] „  //đһt lính canh
 M[+1] „  //đһt lính canh
  „ 1
 W „ 1
12 //Bҳt đҫu trӝn 2 mҧng
š  r „p 
14 %  ã[] U M[W] //dùng lính canh
15  [r] „ ã[]
16 „+1
17 ! [r] „ M[W]
18 W„W+1

KTLT Nâng cao 2008 - Văn Thiên Hoàng - Khoa CNTT ]š


v 1 ë  

2 1 
 "
 
"   
%  % # # 1
r r r r r r r r r

ã  "     % # # 
     W W W W W

KTLT Nâng cao 2008 - Văn Thiên Hoàng - Khoa CNTT ]ß


v 0 

p q q+1 r
V š ”    ß ] ¨ '

KTLT Nâng cao 2008 - Văn Thiên Hoàng - Khoa CNTT ]]


v 0 
p q q+1 r
V š ”    ß ] ¨ '

KTLT Nâng cao 2008 - Văn Thiên Hoàng - Khoa CNTT ]”


v 0 
p q q+1 r
V š ”    ß ] ¨ '

0 1 2 3 4

KTLT Nâng cao 2008 - Văn Thiên Hoàng - Khoa CNTT ]¨


v 0 
p q q+1 r
 ß ] ¨ '

0 1 2 3 4
V š ”  

KTLT Nâng cao 2008 - Văn Thiên Hoàng - Khoa CNTT ]'
v 0 
p r

0 1 2 3 4
V š ”  
 ß ] ¨ '

KTLT Nâng cao 2008 - Văn Thiên Hoàng - Khoa CNTT ]


v 0 
p r

0 1 2 3 4
V š ”  
 ß ] ¨ '

KTLT Nâng cao 2008 - Văn Thiên Hoàng - Khoa CNTT ”


v 0 
p r


0 1 2 3 4
V š ”  
ß ] ¨ '

KTLT Nâng cao 2008 - Văn Thiên Hoàng - Khoa CNTT ”


v 0 
p r
 V

0 1 2 3 4
š ”  
ß ] ¨ '

KTLT Nâng cao 2008 - Văn Thiên Hoàng - Khoa CNTT ”V


v 0 
p r
 V š

0 1 2 3 4
”  
ß ] ¨ '

KTLT Nâng cao 2008 - Văn Thiên Hoàng - Khoa CNTT ”š


v 0 
p r
 V š ß

0 1 2 3 4
”  
] ¨ '

KTLT Nâng cao 2008 - Văn Thiên Hoàng - Khoa CNTT ”ß


v 0 
p r
 V š ß ]

0 1 2 3 4
”  
¨ '

KTLT Nâng cao 2008 - Văn Thiên Hoàng - Khoa CNTT ”]


v 0 
p r
 V š ß ] ”

0 1 2 3 4
 
¨ '

KTLT Nâng cao 2008 - Văn Thiên Hoàng - Khoa CNTT ””


v 0 
p r
 V š ß ] ” ¨

0 1 2 3 4
 
'

KTLT Nâng cao 2008 - Văn Thiên Hoàng - Khoa CNTT ”¨


v 0 
p r
 V š ß ] ” ¨ '

0 1 2 3 4
 

KTLT Nâng cao 2008 - Văn Thiên Hoàng - Khoa CNTT ”'
v 0 
p r
 V š ß ] ” ¨ '  

0 1 2 3 4

KTLT Nâng cao 2008 - Văn Thiên Hoàng - Khoa CNTT ”


K   &3, 
D Thӡi gian thӵc thi là |
D Chia: ](1)
D ĐӋ quy: sҳp xӃp cho 2 dãy con 2 (/2)
D Trӏ: trӝn n phҫn tӱ ]()
D Tәng chi phí:
() ](1) if 1
() 2 (/2) ]() if 1
: ()  ]( lg )

KTLT Nâng cao 2008 - Văn Thiên Hoàng - Khoa CNTT ¨


ð %   %  
ĐӋ quy: () = 1 if  = 1
() = 2 (/2) +  if  > 1

Á&3 45 |„6„ 7„ „


Á87 9(:5
;u „: „ 7„ „ 66|„
;—   |r6r 7r r
 r <„
;ù 
 |„6|„=„
Ž„= 7„=„=„
„  7„=„
6„ 7„ > „„
6„ 7„ „

KTLT Nâng cao 2008 - Văn Thiên Hoàng - Khoa CNTT ¨


K   &3, 
 

 8  8 


 8  8  8  8 

      
| 7 ?5„ 7„„
KTLT Nâng cao 2008 - Văn Thiên Hoàng - Khoa CNTT ¨V
03, 
D Chia: lҩy mӝt phҫn tӱ x
ngүu nhiên (gӑi là cӑc) và
và chia dãy sӕ a thành 3 Î
thành phҫn.
- L phҫn tӱ nhӣ hơn x
- E phҫn tӱ bҵng x
- G phҫn tӱ lơn hơn x Î
D ĐӋ quy: sҳp xӃp L và G.  
D Trӏ: KӃt hӧp L, E và G.

KTLT Nâng cao 2008 - Văn Thiên Hoàng - Khoa CNTT ¨š


03, 
D Giҧi thuұt phân chia dãy a[left], a[left+1],...,a[right] thành hai
dãy con:
D B1: Chӑn tùy ý mӝt phҫn tӱ a[k] trong dãy là giá trӏ mӕc, left U
k U right,
- Cho x = a[k], i = left, j = right.
D B2: Tìm và hoán vӏ cһp phҫn tӱ a[i] và a[j] không đúng thӭ tӵ
đang sҳp.
- B2-1: Trong khi a[i] < x : i++;
- B2-2: Trong khi a[j] > x : j--;
- B2-3: NӃu i < j : Swap(a[i], a[j]) // a[i], a[j] sai thӭ tӵ
D B3:
- NӃu i < j: : Bưӟc 2;
- NӃu i j: : $ӯng.

KTLT Nâng cao 2008 - Văn Thiên Hoàng - Khoa CNTT ¨ß


ë    $&'
D Phân hoҥch
- Giҧi sӱ chӑn cӝt mӕc ngүu nhiên là phҫn tӱ gi a.

A 2K
K2    E 2K
K K K

2 B¨
” V B”
 
] š  Bß 
] B”
 ”


   
K K L

KTLT Nâng cao 2008 - Văn Thiên Hoàng - Khoa CNTT ¨]


03, 
D GT đӇ sҳp xӃp dãy a[left], a[left+1],...,a[right]: đưӧc phát biӇu
theo cách đӋ quy như sau:
D B1: Phân chia dãy a[left]...a[right] thành các dãy con:
- $ãy con 1: a[left]...a[j] < x
- $ãy con 2: a[j+1]...a[i-1] = x
- $ãy con 3: a[i]...a[right] > x
D B2:
- NӃu (left < j) // dãy con 1 có nhiӅu hơn 1 phҫn tӱ
Phân chia dãy a[left]...a[j] //gӑi đӋ quy sҳp xӃp nhanh cho a[left]..a[j]
- NӃu (i < right) // dãy con 3 có nhiӅu hơn 1 phҫn tӱ
Phân chia dãy a[i]...a[right] //gӑi đӋ quy sҳp xӃp nhanh
//cho a[i]..a[right]

KTLT Nâng cao 2008 - Văn Thiên Hoàng - Khoa CNTT ¨”


ë 

D Chӑn cӑc

¨    ¨   p      ¨  

¨    p   ¨      p    

p   p   p p

p p

KTLT Nâng cao 2008 - Văn Thiên Hoàng - Khoa CNTT ¨¨


ë 

D Phân hoҥch, gӑi đӋ quy, chӑn cӑc

¨     ¨  p      ¨  

   p   ¨      p    

p   p   p p

p p

KTLT Nâng cao 2008 - Văn Thiên Hoàng - Khoa CNTT ¨'
ë 

D Phân hoҥch, gӑi đӋ quy, trưӡng hӧp cơ sӣ

¨    ¨  pp      ¨  

    pp   ¨     p    

p   p   p p

p p

KTLT Nâng cao 2008 - Văn Thiên Hoàng - Khoa CNTT ¨


ë 

D Gӑi đӋ quy, .., trưӡng hӧp cơ sӣ, kӃt hӧp

¨    ¨  p      ¨  

    p         p    

p   p   p p

p p

KTLT Nâng cao 2008 - Văn Thiên Hoàng - Khoa CNTT '
ë 

D Gӑi đӋ quy, chon cӑc (cӝt mӕc)

¨    ¨  p      ¨  

    p     ¨  ¨  p    

p   p   p p

p p

KTLT Nâng cao 2008 - Văn Thiên Hoàng - Khoa CNTT '
ë 

D Phân hoҥch, .., gӑi đӋ quy, trưӡng hӧp cơ sӣ.

¨    ¨  p      ¨  

    p     ¨  ¨  p    

p   p   p p

p p

KTLT Nâng cao 2008 - Văn Thiên Hoàng - Khoa CNTT 'V
ë 

D KӃt hӧp

¨     ¨   p     ¨ ¨ 

    p     ¨  ¨ p ¨ ¨ 

p   p   p p

p p

KTLT Nâng cao 2008 - Văn Thiên Hoàng - Khoa CNTT 'š
ë  4
š       š
 

š
Chӑn ngүu nhiên
    š   š giá trӏ cӑc

    š   š
  

 


  š š    

  š š    
 š 

 


   
š š     

š š     
      ___  

KTLT Nâng cao 2008 - Văn Thiên Hoàng - Khoa CNTT 'ß
03, 
void QuickSort(int a[], int left, int right) {
1. int i, j, x;
2. x = a[(left+right)/2]; // chӑn phҫn tӱ gi a làm gӕc
3. i = left; j = right;
//phân chia dãy sӕ thành hai phҫn
4. do {
5. while (a[i] < x) i++; // lһp đӃn khi a[i] >= x
6. while (a[j] > x) j--; // lһp đӃn khi a[i] <= x
7. if ( i <= j) {
8. Swap(a[i], a[j]);
9. i++; // qua phҫn tӱ kӃ tiӃp
10. j--; // qua phҫn tӱ đӭng trưӟc
11. }
12. } while (i<j);
13. if (left < j) // ph đoҥn bên trái
14. QuickSort(a, left, j);
15. if (right > i) // ph đoҥn bên phҧi
16. QuickSort(a, i, right);
}

KTLT Nâng cao 2008 - Văn Thiên Hoàng - Khoa CNTT ']
à    
D Trong trưӡng hӧp tӗi tӋ nhҩt (cӑc luôn là phҫn tӱ
lӟn nhҩt hoһc nhӓ nhҩt).
D L hoһc G có kích thưӟc là n-1, phҫn còn lҥi kích
thưӟc 0.
D $o vұy, đӝ phӭc tҥp O(n2)

- n
- n-1
- n-2
- ..
- 1

KTLT Nâng cao 2008 - Văn Thiên Hoàng - Khoa CNTT '”
03, 

¨    ¨   ¨    ¨  

    ¨  ¨  p   ¨¨

 ưӡ„
ӧ ӕ  ưӡ„
ӧ ҩ

 V
  V V 
6Šń

6Å 6Å ń

Å„
6Å 6Å 6Å 6Å ń

V V V
V  ń„

KTLT Nâng cao 2008 - Văn Thiên Hoàng - Khoa CNTT '¨
KTLT Nâng cao 2008 - Văn Thiên Hoàng - Khoa CNTT ''

You might also like