1. Trang chủ
  2. » Công Nghệ Thông Tin

bài tập nâng cao cấu trúc dữ liệu cài đặt bằng c

419 672 3
Tài liệu được quét OCR, nội dung có thể không chính xác
Tài liệu đã được kiểm tra trùng lặp

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Tiêu đề Bài Tập Nâng Cao Cấu Trúc Dữ Liệu Cài Đặt Bằng C
Người hướng dẫn PTS. Nguyễn Văn A
Trường học University of Technology and Education - Hanoi University of Science and Technology
Chuyên ngành Data Structures and Algorithms
Thể loại Bài tập nâng cao
Năm xuất bản 2023
Thành phố Hà Nội
Định dạng
Số trang 419
Dung lượng 9,67 MB

Các công cụ chuyển đổi và chỉnh sửa cho tài liệu này

Nội dung

'Với cuốn bài tập nâng cao nầy, bạn sẽ học được nhiều cách giải các bài loần khác nhau bằng lập trình như tính trị của một định thức NxN, nhân hai ma trận, đổi một biểu thức infix trung

Trang 1

(TS; Ban Lan THE)

NHA XUAT BAN THONG KE

Trang 2

Bai Lập nang cao

Trang 3

La NÓI ĐẦU

Cuốn "Bài đập nẵng cao, cẩu trúc dữ liệu, tửi đặt bing C” được biên soạn với các bài tập nãng cáo về mắng, ngản xếp,

hằng đợi, các danh sách liên kết, chuỗi, đổ thị và nhiều bãi tập

khác được thực hiện trên cở sở ngôn ngữ lập trình C

'Với cuốn bài tập nâng cao nầy, bạn sẽ học được nhiều cách

giải các bài loần khác nhau bằng lập trình như tính trị của một

định thức NxN, nhân hai ma trận, đổi một biểu thức infix (trung

tố) sang dạng prefix (tiển tố), đảo ngược các liên kết, quản lý bộ nhớ nhờ đũng các dzm*es4abs#\a2;høä ng cách giữa hai chuỗi, tạo

mã Huffman, thực th: một tập hợp nhờ dùng cây nhi phan, tim

đường dẫn ngắn nhất, ánh xạ N hàng đợi trong một mảng, thực thị

thuật toán À*

Sách được phân chia bố cục một cách rõ rằng Trong mỗi hài tập đều có giải thích cụ thể về mỗi chương trình, đặc biệt ở cuối

mỗi bài tập, chúng tôi có đưa vào phẩn "Những điểm cẵn ghi

nhđ" tóm tắt những điểm chỉnh nhằm giúp ban nhớ lại những vấn

để đã được nêu ra trong bài tập đẳng thời củng cố kiến thức hạn '

đã học được

Chúng tôi hy vọng cuốn bài tập này sẽ là iài liệu tham khảo

thật sự hữu ích chơ các bạn, Mong nhận được sự đồng góp ÿ kiến xây dưng từ hạn đọc Xin chân thanh cdm on

Tae gtd,

Trang 4

hương 1 ; Các hãi tập về mảng, tìm kiếm, phân loại

(hưởng ƒ

Eác bài tận về mảng, tìm kiếm,

phân loại, và tạo băm (hash)

Bài tap: Tính trị của một định thức N x N

* print the matrix

for( i=0: ?<Ñ; ++i ) {

Trang 5

Chương 1 : Các bài tập về mảng, tìm kiếm, phân loại

* makes a an upper-triangular matrix

* returns 0 if any of the diagonal entries are 0; 1 otherwise

* int 4 jr

double factor = 1.0:

double temp;

for( i=l: iN: +71) J1 dont worry about row 0

for( je: i<i; +i) (

if( fabs(temp} > EPSILON && fabs(temp-1.0) > EPSILON ) {

printf( “factor=tg dividing row td by %g \n",

factor, j, temp ):

divRow( a, j, temp );

print(a):

factor *= temp:

Trang 6

Chương 1 : Các hài tập vé mảng, tìm kiếm, phân loại - 9

double multDia( double a[][N] ) { _

* returns multiplication of diagonal elements

1 Cách thông thường để tìm trị của một định thức N x N là lấy

phần tử đầu tiên trong hang đầu tiền nhân với trị của định thức

được tạo thành bằng cách loại bỏ hàng đó và cột đó Thủ tục này

được thực hiện theo phép đệ quy ở mọi bước cho đến khi chỉ còn lại một phần tử duy nhất mà trị củn nó chính là trị của định thức

11 Dấu của phần tử đưng được nhân cả thể thay đối tay thuộc

vàe hãng và cột củe nó Nái chung, nếu phần tử cá hàng ¡ và cột

Trang 7

10

vi mang, tim kiết

j thì đấu cua n6 được xác định bởi cảng thức (-31^(i+y)

3 Có mật cách khác đê grái hài tập này Lưu ý rằng nấu ta thực

hiện các phép biến đổi hàng hay cột trên định thức thí trị của nó không th.i đổi, Tận dụng dữ kiện nãy để biếp đổi mạ Lrận tương

ứng với định thực thành mật ma trận tan giác trên hay đưới rồi tìm trị định thức của ná Rô ràng trị định thức eủä một rna trận

tam giác trên hay đưới là tích tủa các phần tứ chéo Da vậy, tìm mot tr] định thức rw hắn chỉ là việc làm ghủ một ma tran trở

thành mna trận Lam giác trên hay dui

8 Bể biến đổi một ma trận thành ma trận tam giác trên

tralkeUpper(3), tạ thực hiện cae phép biển đổi hãng trên ma

trận đố, Một la ý quan trọng lhác là phép nhân của một đình thie D với một ti: + ìà một định thức mới mà trong đỏ bắt kỳ

hàng rúa D được nhân với v Phép nhân một hàng với v có nghữx

là nhãn mới phần tư trong hằng đó với y Do đá tá duy trì một

thứa sẽ biến đổi để theo đài số nhân khi các hàng của định thức

được nhắn hay chia cho ahiểu thừa sổ khác nhau trong tiến

trình tạo tam giác trên (upper-triangulatian), Ở đãy, ta giả sử

mọi phần tử của định thức là các số đấu chấm động

4 Trong tiến trinh upper-triangulation, nếu có bất vị phan tt ado trang eác phần tư cháo trúgSàssssxsssflero(ï), điều đủ cá mghịa

là trị cua định thức bằng 0 (ghi nhớ rằng trị của định thức bằng phép nhân tủa các phần tử chéo {maulEDiat)),

5 Wế từ đây, tả giả sử các phần tử là các số đấu chấm dong (float-

ing-point number}, phép tinh od thé không chính xác Để gia]

thích cho tỉnh gắn đúng này, ta duy trì một thuật new lai BPSI-

LON vữn được xác lập sang một trị đỏ thấp (có thể bằng f), Bất

kỹ trị nao nam trong day +EPSILON_0.-EPSILON sẽ được xem

là 0

6, Thuật toán để biến một ma trân thành một ma trận tam giáp

trên là như sau:

Trang 8

hương 1 : Các bai tập về mang tìm kiếm, phân loại

2 1 chia hang 1 cho 0.5 24

Trang 9

12 Chương 1 : Dác bài lập về mảng, tìm kiếm, phân loại

100125

| 0 00.0617) Vậy, định thức = 24*(1*1*0.0417) = 1

Những đểm cẩn ghi nhớ

1 Cách đầu tiên để giải bài tập này theo phép đệ quy là tự nhiên,

nhưng khó sử dụng vì nó yêu câu loại bỏ một hàng và một cột Vì

vậy, khi thiết kế một thuật toán, bạn nên thử nhiễu phương

pháp khác nhau rồi chọn phương pháp thích hợp nhất

* find min value in row of a

* return the yalue,

Trang 10

hương 1 : Cac bai tap vé mang, tìm kiếm, phân I

int findMax( int a[][N] int col ) {

„~

* find max val in col of a

* return the value

1 Một ma tran M x N duge cho là có một điểm saddle (yên ngựa)

nếu một mục nhập a[¡]f] là nhỏ nhất trong hàng ¡ và lớn nhất trong cột j Trong ví dụ ma trận sau đây, 7 là điểm saddle.

Trang 11

14 Phương 1 : bác hãi tập vể mảng, tìm kiểm, phân loại,

J123|

a=|456|

|783|

2 Chuong trinh thi don gian va ¢6 thé duoc hoan chinh trong O(M

x NxM) lan bang efich sw dung cdc vang lap for duoe xép lang

“Thuật toán như sau:

}

8 Phép tìm trị nhỏ nhất trong một.hàng là O(N) và lớn nhất trong

một cột là O(M), Do đó phức hợp của thuật toán trở thành O(M*(N+N*M), hoặc O(M*N*M)

Những điểm cần ghi nhớ sated

1 Một điểm saddle là trí nhỏ nhất trong hãng và lữn nhất trong

cột,

2 Uó thê có trên một điểm saddle trong một ra trận (matrix)

3 Có thể không cổ điểm saddle nào trong một ma trần,

4 Phức hợp của thuật toán là O(M xM x NÌ, trong đó M xN là kích

cỡ của ma trận,

Bài lận: Nhân hai ma trận 5parse

Viết một hàm m mult() để nhân hai ma trận sparse trải rác) và chứa

kết quả trong một ma trận sparse khác Mỗi mna trân sparse được biểu thị bãi một mảng các bộ ba Mỗi bộ bai (triplet) gồm có một hàng, một

Trang 12

Chương 1 : Cac bai tap vé mang, tim kiểm, phân loại

void ftrans( int a[}{3], int b[]f3] ) {

void printMatrix( int afJ(3] ) {

Trang 13

16 Chương 1; Cac bai t@p về mang, tim kiém, phan logi

void insert( int c[][3] int row int col, int val) (

for( 1=1; i<=terms &ä c[1](0]<row; +1 )

for( : i<=terns &k c[1][1]<col; #>i )

†f( i<=terms && c[ï][1] = col ) // already inserted

in *É = (int *)ma]loc( rơøsofb*sizeof(int) 3:

ing temp, temp2;

TnỆ arow, acol, aval brow, browstart browend;

Tor( ï=l; i<=rowsofb; ++i )

temp2 = t[i], t[i] = t[1-1]+temp, temp = temp2:

Trang 14

hương 1 ; Các bài tập vế máng, tìm kiếm, phân loại 17

/Í now start mult

for( i=l; {<=aterms; +1 ) ( arơ = a[i][0]: aco] = a[1]I1]; aval = a[1][2];

brow = acol;

hroestart = t[brœ]; brgwend = t[brơw+1]:

for( jebrowstart: j<browend; ++) )

insert( ©, arow b[4]f1], aval*b[J][2] 3:

} }

#mt maln() {

1nt a[](31 = {

{4.2.3}, {01.2}

pr ntMatrix(b); TRƯỜNG ĐẠI HỌC TRÀ VINH

maith Ay Be Sys THU VIEN

tử khác trong ma trận sparse Do vậy, ta duy trì một mảng có

kích cỡ N x 3 cho mỗi ma tran sparse, trong đó Ñ là số các phần

tử khác 0 trong mang Hang dau tiên của mỗi ma trận sparse chứa số hàng, số cột và các phần tử khác Ù trong ma trận Sau

đây là một ví dụ `

Trang 15

18 hương 1 - bác tải lập về mảng, lim kiếm, phân loại

a[01I0] = 7 là số hãng của ma trận a a[0]|1]=7 là sà cật của ma

trận a a[0][2|=8 lã sẽ eác phẩn tử khác 0 trong ma trận a Các

phần tứ khác 0 được lưu trang các hãng i=1 đến ¡=B trong đó

a(i][0] là hàng, a[il[1] là eột và af[2] 1a tri trong ma tran a- Luu

ý rằng các phấn tử được phân loại theo hăng nhưng bên trong

một hàng, chúng được phản loại theø các cột

3 Hàm m mulk(a, h, c) lấy tmn8&jzphẩmr4ttuvảm a, với hằng araw và cột

acol, nhân với mỗi phần tử hàng acol của b Tích được cộng vào

phan tử trong e với hàng arow và cột băng cột của phần tử trong

h, Lưu ý rằng vì a và b được phân loại theo (hang, cột) nên các mục nhập mới được tạo cha c cũng có cùng thứ tự phân løại, Da

dé taco thé dé dang chén các mục nhập mới trong ¢ vao cudi cde mục nhập đang được lưu tzữ _,

3 Vấn để duy nhất bây giờ Tà cách dat tei mye nhap dau tiên trong

b với hàng acol Một cách là sử dạng phép tìm nhị phân để đạt

tới hàng này, vi nú được phân loại theø hằng, Nhưng lưu ý rằng

số hãng của lì là không đổi Vì vậy ta duy tri một mắng các chỉ sẽ

trõ đến cầu mục nhập đầu tiên chu mỗi hằng trong b Dø vảy,

niểu ma trận h giống như được minh họa trước đãy thì các chỉ số được duy trì trong một veetor t sẽ giống như được minh họa ở

day.

Trang 16

hương 1 : ác bài tập về mảng, tim kiếm, phân lnại 18

t[i]= 0 biểu thị hàng ¡ của b không có chứa bất kỳ phần tử nào

Do bởi điểu này, phép tìm nhị phân ban đầu của thứ tự O(logn)

bay giờ có thể được thực hiện trong O(1) lần Nhưng điểu này

cần thêm O(Nb) lần để tạo t(] trong đó Nb là số các mục nhập

hàng acol của b được rảo qua

phần tử trong a được nhân với mỗi phản tử trong hàng danh sách

(row-list) của b với hàng acol và cột beol, và

các tích được chèn vào e là c[arrow][bcol]

Do đó trong mọi bước, một phần tit trong a sé lam tăng thêm e tiên e[arrow][beol] hiên hữu thì tích được cộng vào trị ban đâu I"hóp ulin của a với b được cho ở đây cho ví dụ trước

Trang 17

z0 hương 1 : bác bài tận vé mắng, tìm kiếm, phần loại

Bước AROW ACOL ECOL AlAROWJ|ACOL] 'IAROWJIBCOL]

danh cho cdc pointer, nếu một ma tran sparse được biểu diễn bởi

duy trì (hàng, cột) lớn nhất được chèn vào c và bằng cách thực

hiên một phép tìm nhị phân trong khi tìm kiếm một một (hang, edt) hiện cá, hộc bằng cách duy trì một mảng tương tự với 1]

chơ b Bằng cách chứa thêm những chỉ số như vậy, việc chèn

trong e cĩ thể được thực hiện trong O(1) vốn sé lam cho mmult()

trở thành O(Na*Cb)

Bài tận: Phép nhãn hai ma trận Sparse (các phiên bản khác

nhau) Cho a và b là hai ma trận sparse (rải rác) Viết mật hàm sMatMul(a,

b, e) để thiết lập cấu trúc chu e = a*b.

Trang 18

hương 1 : Các bài tập về mảng, tìm kiếm, phân loại

typedef int type;

typedef struct node node:

mat->rows = (node *)malloc( sizeof(node)*rows );

mat->cols = (node *)malloc( sizeof(node)*cols );

for{( i=0; i<rows; ++i) { mat->rows[i].hnext = mat->rows+i;

Trang 19

22 Chương † : Các hài tập về mảng, tìm kiếm, phân loại

int sAddi spmat ‘mat, int row int col, type data > { “

* adds a new node to the sparse matrix

for( prev=head, ptr=prev.>hnext; ptrl=head && ptr->col<dataptr:

* inserts dataptr in appropriate «| of sparse matrix

* Assume that cRowlnsert() was ca‘ ed before

Trang 20

thương † : Cac bai tập về mảng, tim kiém, phan loại 23

free(dataptr) ; return SUCCESS:

Trang 21

24 Chuong 1 : Cac bai tập vé mang, tìm kiếm, phân loại

int i:

Trang 22

Chương 1 : bác bài tập về mảng, tìm kiếm, nhân loại 25

for( i=0; ict; +7)

for( ptri=a->rows[{i].hnext; ptril=a->rows+i; ptri=ptri->hnext )

‘int row = ptri->col;

fort ptrjeb->rows[row].hnext: ptrj!=b->rows+row;

ptrj*ptrj->hnext ) {

} }

sAdd( &b, 1,1, 6);

sHPrint(&a,M) ; SHPrint(&b, P) :

SMatMul( ša, &b, &c ), SHPrint(&c ,M)

i va cing nut này trong danh sách đọc của cột j Mật nút (mode)

tiêu biểu cho một mục nhập Do đó, nó chứa hàng, cột, và các trị

cùng với các pointer ngang và dọc trong các danh sách

Trang 23

26 Chương † : Các bài tập về mắng, tìm kiếm, phân loại

3 Cho kích cỡ của các ma trận sparse a, b là MxP, PxN Do do, kich

cỡ của e là MxN, Ta mẽ tả một thuật toán bằng cách sử dụng

mét vi du Cho

lo 2) a= |3 0|, b=|005|

3 Thuật todn rao gua méi hàng của a và kiểm tra danh sách ngang

của nö tương ứng với mỗi hàng cho bất kỳ phần tử trang nó Đối

với mỗi phần til trong a với hàng arow và cột aeol, hàng acol của

b được rảo qua và phần tử trong a được nhân với mỗi phần tử

trong hàng-danh sách (rowslist);eja:h.xới hàng acal và cột bcol Các tích được chèn vào ¢ theo dạng e[arow][beol] Do đó trong

Tmọi bước, một phần tử trong a làm tăng thêm c Nếu e[araw][beol] hiện hữu thĩ tích được cộng vàn tri bar đầu Phép nhân của a và

b được cho ở đây cho ví dụ trước

Bước AROW ACOL BCOL AlAROWIIACOLI'B €[AROWI(BCOL]

Bước 4 biểu thị a[4] được lấy dé 14 jaa nhung khang dive ro

qua khi nụ rồng lưu ý rằng tích bảng 24 ở bước 4, trong khi t[Ä|[2| có một tế; là 29, Điều này xuy ra bởi vì cL8](9) đã có chứa

một trị 5 ở bước 5

Trang 24

hương 1 : Các bài tập về mảng, tim kiếm, phân luại 27

4 Gha na, nb là sä các mục nhập lkhác 0 trang a và b Bước e¿ hán

trong thuật tnấn này là cộng các tích của các nhắn lử lrũng a vá

b với c Vì vậy, ngay cả khi vòng lập ngoài rảo qua từ (} đến M-1

thì hàm eAddU được viện dẫn chø mỗi mục nhấp afï|(J] ự viện dẫn này được thực hiên cho mỗi nhẳn tử khác 0 trong hãng j của

b Da đó, tối da số phẻn nhãn cho a[ïllj] sẽ bằng N, số cột tua b,

Vay phức hợp của thuật toán nhần ma trân là O(na*M) Tụy nhiên, nếu ta thăm phức hợp Lới vòng lầp ngoài tùng thì phù

Những điểm cần ghỉ nhữ

1, Mật sự sữa đổi nhỏ cho ham ađđ(matrix,xow,col.value) thăng

thường đã đãn đến sư thực thị đề đãng của phép nhãn ma trận

Ni chung, nếu ali]UJ] được chèn vào và nó đã cũ thị ta ghỉ đề trị

hose cho ra một lâi, Rầằng cách cộng Lrị mái vào trị ban đầu, ta cá

thể cảng các Lích của các phản Lử trong a và h vào c theo cách gia

diễn này như b dO, phde hợp tầng lên cho

G(M*P*?NTP| khi aGetVal là O(P)

4 Các phần chèn được đơn giản bằng sự biểu điễn các hàng và các

cột rỗng qua các nút tiêu dé thay vi các đanh sách NƯU|,

Bài tập: Thực hiện phép phân luại - tron theo K cach dé phan

luại một File có chứa cac Recard (bản nhi)

#define K 2 #/ Keway ergs

oer ine DATAFILE “main trt* sq

#def|ne TEHPFILE ~temp trt~

typedef struct node node:

typedet enum (FALSE TRUE) boo} ;

struct node

fot vat | char «IN}

}:

Trang 25

28 Chuang 1 : Cac bài tập về mảng, tìm kiếm, phân Iại

ede buf[K];

int rec[K];

f/ buffer used for merging,

// record numbers of nodes in buffer

‘int ements char *filename ) {

}

void readFromFile( char *filename, node *n, int off ) {

/#

* reads a record at offset off from file filename into n

* off is number of records before the record in the file (NOT bytes}

* off starts from 0

mf

FILE *fp;

/fprintf( “reading rec no ¥d \n", off );

if( off >= getNRecords(filename) ) {

fprintf( stderr “ERROR: reading beyond the file.\n™ ):

Trang 26

Đương 1 : Các hài tập vé mang, tim kiếm, phan loại

void writeFun( char *filename ) {

‘int i, nrec = getNRecords( filename);

for( 1-0; i<orec; ++i) { readFromFile( filename &n, 1);

printf( “S2de{%2d,%-5s}.\n", i, n.val, ns ):

} }

void copyrec{ int rec, int *rec2 ) {

* fills buf and rec with appropriate values

* 7 is length of each run

* start is rec no of first rec in first run

* data is in srefile in nrec records

29

Trang 27

au hương 1 : Các bai tap về mảng, lìm kiếm, phân luại

qt i;

prrntf( “start=td l=%d.\n", start, 1);

for( i=0; ick; +41) {

int startoff = start+I*i;

if( startaff >= nrec )

break:

rec[i] = startoff;

printf( “buf(ad]=sd.\n" 1, startoff ):

TreadFromf1Ìe( srcfile buf+1 startoff );

void updatebuf( node *buf int *rec, int *rec2, int prevrec int }

char *srefile int nrec ) {

*

* updates buf+rec2 as rec2[prevrec] was output

* read appropriate record from srcffÏe if necessary

* rec st†]] contains the original rec nos which can be used for

* checking ends of runs -

* 7 15 runtength,

*/

1f( rec2[prevrec] < nred' KỸ Fecal prevrec) < recCprevrec}+1-1 ) (

2/ rẹc2[prevrec] was M0T the Vast rec of that run rec2[prevrec]++;

readFromFile( srcftle, buf*prevrec, rec2[prevrec] ):

else {

JJ recZ[prevrec] was the ]ast rec of that run

rec2[prevrec] = -1; // job of this run is aver

}

}

1nt getMin( node *buf, int *rec2 ) {

* returns index in buf of that record which has min sorting value

* rec2 is needed for checking whether a buf entry is valid

Trang 28

hương 1 : Các bải tập vể mảng, lÌm kiếm, phân loại #1

* the same at this point

* buf contains their actual data

* 1 is run]ength

* srefile is needed for reading next data,

* the data is appended to dstfile

* total no of records being written is min(1*k, nrec-rec[0])

1T( nextrec =— -1 ) {

fprintf( stderr, "ERROR: merge()¡ all recZ are -1l\n" );

return:

}

2/prinkf( "mìme%d.Vn" newtrec );

// this is the index jn rec2 of next record to be output

writeToFile( dstfile, buf*nextrec );

7} remove this written record read new record from srcfile if

needed

updatebuf( huf, rec, rec2 nextrec, 1, srefile nrec 3:

f7printf( “after updatebuf : rec2=xd td šd.\n" rec2{[0]

rec2[1], rec2[2] ):

1 }

void mergedriver( char *srefite char *dstfile } {

/*

* sort+merge srcfile and store in dstfile

*/

Trang 29

a2 hương 1 : Các bài lận về măng, fìm kiếm, phãn luại

int nrec = getNRecords(srcfT1e);

int i, 1:

‘int rec2(k];

char tempname[M]:

for( =1: 1<nfec; 1* ) {

/? T 3s 1ength nf each run

// no 0f runs = ceiT( nrec/] );

// we teed to consider only K runs at a time

for( i=0; i<nrec; †+el*K ) {

Z! TiT1 Buf with appropriate values, Fillbuf( i, 1 nrec, srcfile );

C€0pyrec( rec rec2 };

merge( srcfile, dstfile buf, recở, I nrec };

un}ink( srcfile );

strepy( tempname, srcfile );

strcpy( srcfile dstfile }:

strepy( dstfile, tempname };

7/ sorted file is srcfile

readFun( srcfile ): - 2#4#msefEiectesm

int main() {

char srcfile[N] = DATAFILE;

char dstfive(N] = TEMPFILE:

untink( srcfile }:

unlink( dstfile );

writeFun( srcfile 3;

readFun( srefile );

printf( "nrec=*d.\n", getNRecords(srcfile) );

mergedriver( srefile, dstfile ):

return 0;

}

Giải thích

1 Ham main() tạo một file kiểm tra bằng cách sử dung writeFuntl

va goi mergedriver() mergedriver() goi ham merge() sau khi dow

các khối K (fillbuf{)) ctia file vao bộ nhớ

3 Hàm merge() so sánh các khối và phản loại chúng trân khóa đã

xác định trước Khối cổ khóa nhỏ nhất (getMinU) được viết vàø

file và Ichi của nẻ được điển đẩy (updntebuff]) với rueard kế tiếm

Trang 30

Chương † : ác bải tặp vế mảng, tìm kiếm, phân lơại 33

từ ñle, Do đô phép phan loai (sorting) và trén (merging) tién

hành đồng thửi để phân loại RÌa liền tục

8 Số lượng khối được so sánh được gọi là run Mỗi chiều dài run tăng với mỗi lần lặp lại Nếu ban đâu nó là 1 thì nó trả thành , roi K*K và cứ như vây tiếp tục Khi nỏ trở nên lớn hon hoặc

bang sé record trong file (getNRecords()), file duge phan loi boi

vì tất cã các record trong mỗi run được phân loại sau mỗi lắn

4 Ví dụ: Giá sử các khối được lưu trong mật file như minh họa dưới

đây và cho K=3 Thuät toán biển đổi file như sau:

1, Phúc hợp của phép trộn -phân loai (merge-sort) la O(mlogn) trong

đó n là số record trong file Tuy nhiên, nái chung các câu lệnh

được thêm vào phức hợp là các phép su sánh hay một phép gan

xếp lẻng, Nhưng trong trường hợp của các file, ta cắn xem xét

việc đọc và ghi của các record trong ñie, vì thời gian cần thiết để thue thi mét thao tác như vậy lớn hơn nhiễu so với một phép sử

sánh trang bộ nhớ hay một phép gân đơn giản

3 Phân loại trang các file được gụi là phân Ìoai ngoài (external

sorting) trong khi phan loai trong bộ nhớ chính được gợi là phân

loại trong có kỳ hạn (termed laternal sort)

3 Bằng rách trao đổi tên của các ñlè nguân và file đích trong mergedriver( ), ta da tránh được việc sao chép các file trong rnỗi

lần lặp

Trang 31

34 Chương 1 : Lác hài.tập vể mâng, tìm kiếm, nhân loại

Bai tap: Tim mot plateau (đoạn bằng) trong một ma trận

Tìm một miễn chữ nhật trong một ma trận với tổng lớn nhất của

* filter the matrix of size k*] starting frơm a[i][i]

* size of the matrix 1s rows*cols

Trang 32

nương 1 : Các bãi tập về máng, tìm kiếm, phân loại 35

for(jjj=0: j3j<l && (itjj4)<c01s: #+Jjj!

printf(3d " a[i*i111f3*4431):

prinEf( An");

Yo oath

}

void prstezagint a[]J[C0LS] int rows int cols) {

‘sf a rectangular region having max sum of elements in it

int maxsum = a[0]{0]:

int maxrowl=0, maxrow2=0, maxcoll=0 maxcol2=0;

Trang 33

38 Thương 1 : tác bẵi tập v6 mang, tim kiểm, phãn luại

if sum > maxsum

waxsum = sum,

3 }

Các trị của ¡, j, width (chiểu rộng) và height (chiéu cao) tai một

điểm bất kỳ tiêu biểu cho ma trận Các trị đó có thế được lưu để

_ in ma tran ở cuối thuật toán

Phức hợp của thủ tục nãy là O(m*m*m#n#n#n), trang đỏ kích cữ

của ma trận ban đâu là m x a Phức hựp của phép tìm tổng các phần tử của M là Oứn*n),

3, Phủ tục này có thể được thực hiện hiệu quả hơn bằng cách lưu ý rang khang phải mọi ma trận trong M đều cẩn được tạo Êli với

mật phần từ matrisli]U] chiểu rộng lớn nhất của ma trận bắt đầu từ phần tử co thể là columns-j và chiều cao lớn nhất cả thể

ia rows-i Do do, s6 lan lap eda cde ving lp qua chiều rộng và

chiéu cao cỏ thế bị giảm Nguài ra, đối với một phần tử e, nếu

tổng các phần tử của một miễn chữ nhat cũ height x width (can

x rangi bat đầu từ e là am thay vĩ không có miễn chữ nhật cỡ lớn

hơn height x width bắt đấu từ e có thể có một tổng lớn hơn kết

Trang 34

hương 1 : Các tải lấp vế mảng, tìm kiếm, ghân luạl 3T

quả sau cùng Ta chứng mình điều này trong ví dụ ma trận -

Cho i=1 và j=8 matrix[iKj] = 10 Cho height = 2 và width = 1,

Suy ra ma trận có chứa hai phần bử trong nó, |10, -11| và tổng

bằng ‹] Vì tổng âm nên không có điểm nàa để tăng kích cỡ của

na trận và xét các phẫn tử khác hổi vì cha dù tổng của chúng là

bạo ahiều (giả sử sì, bằng cách cộng rna trận này vào nó, thì

tổng (sum) nhất định sẽ nhả hơn s Ma trận ở chứa tổng s cỏ

thể là môt đơn cữ cho kết quả Vì vậy, ma trân ở đây không thể

cố một tổng lớn hơn lết qué sau rùng Da dé, nếu ta tang thềm

chiều cao của.maa trận san cho các phan tif lz (10, -11, 3) thi ting tré thanh 2, nhé hon mot ma tran 1 x 1 bắt đầu từ 3, Thay vào

đó, nếu ta tăng chiều rộng sae che cde phan ti la (20, -11, -6, -71

thi tầng là -14, nhủ hứa nữa,

Ham ñlter(ï thực hiện phương án này,

1 Bằng cách xét chỉ hai ma trần bắt đầu từ một phần tử e, nghĩa là

các mu trận tàng chiều rùng đ phia nhai của e và tăng chiều cau xuống phía dưới e, ta chọn tất cả các miền chữ nhật có thé of ma

không bị bất kỳ sự lặp lại nào,

2, Ta không cẮn tầrg@#€k‡:g0#4J@søi2( ma trận con ngay khi tổng

eac phan tử của nó trở nên äm

3 Nếu muụi trị trang ma trận nhập liệu (input matrix) ãm thì kết quả là mật ma trận 1 x 1 với phần tử duy nhất có một liển độ

4, Gó thể cớ nhiều cách giải cha bai tap nay

5 Phức hợp của phép tìm các phẩn tử của một ma trận cøn

(submatrix) cd thé gia tăng bằng cách chủ ÿ Lổng giá tăng

Bài lập: Thực hiện một phép tim bam (hash)

*Viết mặt chương trình lấy các chuỗi ở dạng nhập liêu (ìnput] và chứa chủng trong một bảng bắm (hash table? hương trinh nay sau do sé yêu cầu người đùng tìm các chuỗi trong hash Lable Dùng sự địch chuyén- 3p 1am ham hashing va sv tao chuỗi để xử lý tràn

Chương trình

#ïnc]ude =st4ie.hz

#include <string b>

#include <maloc.h>

Trang 35

38 Chương † : Các hài tập về mảng, tim kiếm, phân i:

#deFine MAXLEN B0

#define HASHSI7E 23 (/ some prime val

#define SHIFTBY 3 // each group size in hashing,

typedef struct node node:

typedef char *type;

typedef node xhashtahle[HASHSI7E]:

* returns index into hashtable applying hash function

* uses shift-folding followed by mod function for hashing

TRE ï n, finalm9:

char *keyptr: 7

for(keyptr=key; *keyptr: finalnt=n)

for(i=0 nO: 1-šŠHIFfUP°fEĐyZWfn++i, +xkeyptr)

# cae shift-falcing feitowed by moc: function for hashing,

% dows NOT check for duglicate insertion

otr->ke =< strdup(key!

ptr-ova + vi

ptr->next = h[†ndex1- h[fndex] = ptr

printf( "he Sd] = 23 \n", index key)

Trang 36

Chương 1 : Các bi tận về mảng, Tìm kiếm, phân l0ại 39

Tt hGetVal(hashtable h, char *key) {

M2 , ĐEP->key, ptf->val);

printf(*\n"); á

} }

Trang 37

41 hương † : bâc băi tập về mảng, lìm kiếm, nhên I:

line hủ:

return O:

}

Giải thích

1 Bảng hđm (bash table) duge duy i nh 14 mot wang the cde

danh sâch Mỗi danh sâch (lišt) 2aôc rỗng hoặc chứa câc aũL (node) bao gĩm cfc chudi ânh xa sang chỉ số trong hash ‡ahÌe,

sau khi ân dụng hầm hashing Chudi trong nút được gọi lă khóa

fkay), Mỗi nút cũng: chứa một số nguyín vấn lă gố mă tại đó

chuỗi được chỉn văo hash tahle, Do đồ, mỗi sút chứa một rắp

(chda, tră)” Trang một tình huống Lhực, một Erị (value) cả thể lă

bất kỳ trị năo eó mặt khóa liín quan với nó

® Chương Lrinh câ chữa hai vòng lặp (fo¿p) Trang vòng lặp đầu

tiín, nó yíu cầu người dùng nhập văo một laat cẩ chuối (strrig)

vă gại AInsert() dĩ chĩn ede chudi ceong hash tahle Vòng lêp thứ

hai yíu cầu người tùng nhập một chudi vă trả về so ma tai db nd

đê được chỉn văo Mật số chỉn lă -1 biểu thị chuỗi không có

trong hash table Điều nảy được thực hiện bằng câch sử dụng

hăm hetVal(J Câ hai braid bâm hashing hGettndex() znă với một chuỗi chụ brute, nd tra về chi sĩ tao hash (hashing)

cla nĩ Nd gdp chudi lại thănh một mẫu gồm m ký tự (sở lẽ

ngoạt trữ kỷ tý sau cũng), vă tao thănh một số nguyín từ mỗi ký tum Sau Íồ nú cộng tất cô câc số nguyễn năy lại với nhìu để cho ra mat số khâc Số năy sau đâ sẻ được chia cho lich cỡ của

mĩ hash table dĩ lay phan du lam chi si yao hash table, hÏnsert()

thím chuỗi mâi năy vă trinh tu chĩn eda ni yao mgt mit va out

nay dược thím văo đầu danh sâch tại chỉ số đó hGetVwl() tim

danh sâch tại chí số đó cho chuối nhập liệu, Nếu nĩ tìm thấy một chuỗi như vậy 4hi trình tự chỉn của nề được trả về, nếu

không nó trả vĩ -1

3 Vì phức hợp của phĩp chđn một nút trong danh sâch lă O(1l nền

phức hợp của hlneerM() lă phức hợp cũa hăm hashing, Phifc hop cua ham hashing la Olp| trong dĩ p la chiĩu dai trung hình của

chuỗi, Suy ra phite hop vie hinsert() 14 Ofp), Phie hep eda

hGetValt) lă O(p+q) brong đó q lă số trung bình của câc out trong

tmỗi danh sâch, Sự tạo chuỗi (ehaning! liín quan đến mặt phĩp

tìm tuyển tính

1 Phức hợp của phĩp chỉn trong hash table được quyết định bởi

Trang 38

hương † : Các bài tập về mảng, tìm kiếm, nhân luại 4†

ham hashing nếu sự tạa chuỗi đơn giản được sử dụng để xử lý tran

2 Phức hựp của phép tìm kiếm được quyết đình bởi ca ham hashing

và leỹ thuật xử lý tran (overflow handling)

3, Một hãm hash lý tưởng ánh xạ mọi chuỗi nhập liệu (input string) sang một chỉ số khác và do đó không có sự xung đột nàn Giả sử phúc hợp của rnột: hàm hash là O(1) thi các phép chèn vã tìm

kiếm vào một hash table lÿ tưởng là O(1)

4, Các hash tabla được sử dụng trong các trình biên dịch để quản [ÿ hắng ký hiệu Các hash table còn có nhiễu ứng dụng khác

5 Các lẹỹ thuật xử ]ý tràn kháe nhau chẳng hạn như dò tuyến tính

(linear prohing), dà bậc 4 (quadratic prøbing), đồ ngẫu nhiên

(random ‘probing), tao lai bam (rehashing), được sử dụng tùy thuộc vào yêu cầu ửng dụng

Bai tap: Sy thye thi cia ky thual rehashing

Viết các hàm để chèn và tìm kiếm trang mật hash table bang cach sử

dung ky thudt rehashing (tao lai bam), Ding linear probing (đỏ tuyến

tinh) néu ky thuat rehashing khéng thanh céng

Chương trình

#inclute <stdio,h> h

#include <šstring.h> ¬ PI

#incìuđe <malloc.h> na

#define HASHSIZE 23 71 some prime val

typedef struct node node:

typedef char “type;

typedef node *hashtable[HASIS17E]:

* returns index into hashtable applying hash function

* Uses sum of elements followed by mod Function for hashing,

Trang 39

* returns index into hashtable applying hash function,

* sums the products of elements with their indices and then mod

int hLinearProbe(hashtable h, type key int index) {

* search for node having key in h starting from index+]

*”

int †:

for(i=index+l: i<HASHSI7E; ++i) // index to end of hashtable

if(hL4] && !strcme(h[1]->key, key))

return i:

e]se Íf(!h[1])

return -1;

for(i=0; i<index; +1) // starting from 0 to index-1

1f(h[i] &® !strcmp(h[1]->key, key))

return i:

else if(!h{i})

return -1;

Trang 40

ÿñương 1 : bac tải lập vẽ mảng, tim kiếm, phân loại

int index = hGetIndexi (key);

if(h{index] && strcmp(h[index]->key, key)} {

‘index = hGet Index2(key):

if(hlindex} && stremp(h[index]->key, key)) {

index = hLinearProbech, key, index);

Ngày đăng: 19/02/2014, 08:02

TỪ KHÓA LIÊN QUAN

🧩 Sản phẩm bạn có thể quan tâm

w