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

Các cấu trúc dữ liệu và giải thuật hiệu quả cho bài toán tìm kiếm

110 462 0

Đ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

Định dạng
Số trang 110
Dung lượng 2,03 MB

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

Nội dung

TỔNG QUAN VỀ CÁC GIẢI THUẬT TÌM KIẾM CƠ BẢN 1.1.Tìm kiếm tuyến tính Tìm kiếm tuyến tính[2], [3], [4], [9] hay tìm kiếm tuần tự là phương pháp tìm kiếm một phần tử cho trước trong một da

Trang 1

BỘ GIÁO DỤC VÀ ĐÀO TẠO TRƯỜNG ĐẠI HỌC BÁCH KHOA HÀ NỘI

-

NGUYỄN THỊ THANH VÂN

CÁC CẤU TRÚC DỮ LIỆU VÀ GIẢI THUẬT HIỆU QUẢ CHO BÀI TOÁN TÌM KIẾM

Chuyên ngành: CÔNG NGHỆ THÔNG TIN

Trang 2

LỜI CAM ĐOAN

Luận văn thạc sỹ này do em nghiên cứu và thực hiện dưới sự hướng dẫn của

Cô giáo TS Nguyễn Thị Thanh Huyền Với mục đích học tập, nghiên cứu để nâng

cao kiến thức và trình độ chuyên môn nên em đã làm luận văn này một cách nghiêm

túc và hoàn toàn trung thực

Để hoàn thành bản luận văn này, ngoài các tài liệu tham khảo đã liệt kê, em

cam đoan không sao chép toàn văn các công trình hoặc thiết kế tốt nghiệp của người

Trang 3

LỜI CẢM ƠN

Đầu tiên, em xin gửi lời cảm ơn đến thầy, cô giáo Viện Công nghệ Thông tin

và Truyền thông đã tận tình dạy dỗ, dìu dắt chúng em trong suốt quá trình học tập tại Viện

Đặc biệt, em xin bày tỏ lòng biết ơn sâu sắc tới cô giáo Tiến sĩ Nguyễn Thị Thanh Huyền, Viện Toán ứng dụng và Tin học, Trường Đại học Bách khoa Hà Nội

đã tận tình hướng dẫn, đưa ra những góp ý, chỉnh sửa vô cùng quý báu cho em trong quá trình làm luận văn này

Cuối cùng, xin chân thành cảm ơn gia đình, bạn bè đã giúp đỡ, chia sẻ với

em trong quá trình học tập và nghiên cứu làm luận văn

Trang 4

DANH MỤC CÁC HÌNH VẼ

Hình 1.1 Kết quả thực hiện chương trình với ví dụ 1.1……….……… 5

Hình 1.2 Kết quả thực hiện chương trình với ví dụ 1.2……….……… 9

Hình 1.3 Kết quả thực hiện chương trình với ví dụ 1.2……….………10

Hình 1.4 Thứ tự ưu tiên hàng và cột cho bảng chữ nhật ……….………11

Hình 1.5 Mảng truy xuất cho bảng chữ nhật ……….….… 13

Hình 1.6 Các bảng tam giác với nhiều dạng khác nhau ……… ….……14

Hình 1.7 Hiện thực liên tục của bảng tam giác ……….…… 15

Hình 1.8 Mảng truy xuất cho bảng lồi lõm ……… 16

Hình 1.9 Mảng truy xuất cho nhiều khóa bảng chuyển đổi ………18

Hình 1.10 Mô tả hàm băm ……….………19

Hình 1.11 Hàm băm dạng bảng tra được tổ chức dưới dạng danh sách kề 21

Hình 1.12 Kết quả thực hiện chương trình chèn khóa k vào bảng ………….… 30

Hình 1.13 Kết quả thực hiện chương trình trường hợp không tìm thấy khóa k trong bảng ………32

Hình 1.14 Kết quả thực hiện chương trình trường hợp không tìm thấy khóa k trong bảng ……… …… 33

Hình 2.1 Cây nhị phân đầy đủ ……….………36

Hình 2.2 Cây nhị phân không đầy đủ ……… 36

Hình 2.3 Các cây nhị phân suy biến ……… …… 37

Hình 2.4 Đánh số các nút của cây nhị phân đầy đủ biểu diễn bằng mảng ….….38

Hình 2.5 Biểu diễn cây nhị phân bằng cấu trúc liên kết ……….40

Hình 2.6 Cây nhị phân tìm kiếm ……….……… 43

Hình 2.7 Kết quả thực hiện chương trình tìm kiếm trên cây nhị phân……… 46

Hình 2.8 Sau khi thêm nút 6 vào cây nhị phân tìm kiếm ……….………… 48

Trang 5

Hình 2.9 Kết quả thực hiện chương trình chèn thêm nút trên cây nhị phân… 50

Hình 2.10 Sau khi xóa nút 9 trên cây nhị phân tìm kiếm ……… … 51

Hình 2.11 Xóa nút có một nút con ……….……….… 52

Hình 2.12 Xóa nút có hai con ……….……….… 52

Hình 2.13 Kết quả thực hiện chương trình xóa nút lá trên cây nhị phân.…… 57

Hình 2.14 Kết quả thực hiện chương trình xóa nút có một cây con trên cây nhị phân ……… ….58

Hình 2.15 Kết quả thực hiện chương trình xóa nút có hai cây con trái và phải trên cây nhị phân ……… 58

Hình 2.16 Cây nhị phân cân bằng AVL……… … 59

Hình 3.1 Cấu trúc kiểu thứ bậc ……….……… ….64

Hình 3.2 Kiến trúc Lucene ……….……….…… … 69

Hình 3.3 Kiến trúc file Index ……….……… 70

Hình 3.4 Chỉ mục đảo ngược ….……….……… … 72

Hình 4.1 Ý nghĩa của mảng next ……….….……….….76

Hình 4.2 Ý nghĩa của mảng next tại vị trí m+1 ………….……….……76

Hình 4.3 Kết quả thực hiện thuật toán KMP_trường hợp tìm thấy chuỗi……….81

Hình 4.4 Kết quả thực hiện thuật toán KMPtrường hợp không tìm thấy chuỗi…82 Hình 4.5 Giao diện sử dụng của phần mềm ……… ……… 92

Hình 4.6 Kết quả tìm kiếm có giá trị là “Anh” ……… ……… 98

Hình 4.7 Kết quả tìm kiếm có giá trị là “Vân” ……… ……… 99

Hình 4.8 Kết quả tìm kiếm theo số điện thoại……… 100

Trang 6

MỤC LỤC

MỞ ĐẦU 1

CHƯƠNG 1 TỔNG QUAN VỀ CÁC GIẢI THUẬT TÌM KIẾM CƠ BẢN 3

1.1.Tìm kiếm tuyến tính 3

1.2 Tìm kiếm nhị phân 5

1.3 Tìm kiếm thông tin trên bảng 10

1.3.1 Bảng chữ nhật 11

1.3.2 Các bảng tam giác 14

1.3.3 Các bảng lồi lõm 16

1.3.4 Các bảng chuyển đổi 17

1.4 Tìm kiếm theo phương pháp băm 18

1.4.1 Bảng băm 19

1.4.2 Hàm băm 20

1.4.3 Bảng băm mở 23

1.4.4 Bảng băm đóng 25

1.5 Phương pháp địa chỉ mở 27

1.6.Tìm kiếm xâu 34

CHƯƠNG 2 CÂY NHỊ PHÂN TÌM KIẾM 36

2.1 Cây nhị phân 36

2.1.1 Khái niệm cây 36

2.1.2 Khái niệm cây nhị phân 36

2.1.3 Biểu diễn cây nhị phân 38

2.2 Cấu trúc dữ liệu cây nhị phân tìm kiếm 43

2.2.1 Khái niệm cây nhị phân tìm kiếm 43

2.2.2 Các thao tác trên cây nhị phân tìm kiếm 43

2.3 Cây nhị phân cân bằng AVL 59

2.3.1 Khái niệm cây cân bằng 59

2.3.2 Cấu trúc dữ liệu biểu diễn cây nhị phân cân bằng 60

Trang 7

2.3.3 Các thao tác trên cây nhị phân cân bằng 60

2.4 Cây nhị phân tìm kiếm tối ưu 61

CHƯƠNG 3 TÌM KIẾM INDEX TRONG CƠ SỞ DỮ LIỆU 63

3.1 Khái niệm index 63

3.2 Index trong SQL Server 63

3.2.1 Giới thiệu 63

3.2.2 Các kiểu index 65

3.2.3.Phương pháp thiết kế index 67

3.2.4 Truy vấn với cấu trúc index 68

3.3 Index Lucene 69

3.3.1 Giới thiệu về Lucene 69

3.3.2 Kiến trúc Lucene 69

3.3.3 Kiến trúc File Index 70

3.3.4 Chỉ mục đảo ngược 72

CHƯƠNG 4 TÌM KIẾM XÂU MẪU 73

4.1 Bài toán đối sánh mẫu trong vấn đề tìm kiếm 73

4.1.1 Giới thiệu tổng quan về bài toán đối sánh mẫu trong vấn đề tìm kiếm 73

4.1.2 Bài toán đối sánh mẫu 74

4.1.3 So đơn mẫu 75

4.2 Thuật toán đối sánh mẫu KMP (Knuth Morris Pratt) 75

4.3 Thuật toán đối sánh mẫu BM (Boyer-Moore) 82

4.4 Thuật toán KMP mờ 85

4.4.1 Khái niệm tập mờ 85

4.4.2 Tiếp cận mờ cho bài toán tìm kiếm 87

4.4.3 Mô hình Otomat mờ so mẫu 87

4.4.4 Thuật toán KMP mờ 89

4.5 Ứng dụng thuật toán tìm kiếm xâu 92

4.5.1 Cài đặt ứng dụng 93

4.5.2 Kết quả tìm kiếm 98

Trang 8

KẾT LUẬN 101 TÀI LIỆU THAM KHẢO 102

Trang 9

MỞ ĐẦU

1 Lý do chọn đề tài

Máy tính ngày nay đã được sử dụng trong hầu hết tất cả các lĩnh vực và đã góp phần quan trọng vào việc thúc đẩy sự phát triển kinh tế, xã hội, khoa học kỹ thuật, … Máy tính ra đời nhằm phục vụ cho những mục đích nhất định của con người Từ thu thập thông tin đến xử lý thông tin, đặc biệt giúp con người trong việc tìm kiếm thông tin với khối lượng lớn, độ chính xác cao trong thời gian nhanh nhất

Ngày nay, kích thước của các hệ thống thông tin ngày càng lớn, trong khi nhu cầu tìm kiếm của người dùng đòi hỏi ngày càng cao và phức tạp Người dùng luôn mong muốn nhận được kết quả trả về trong thời gian nhanh, đáp ứng linh hoạt,

đa dạng các yêu cầu tìm kiếm Vậy nghiên cứu và ứng dụng Các cấu trúc dữ liệu

và giải thuật hiệu quả cho bài toán tìm kiếm là rất cần thiết

2 Mục đích nghiên cứu

- Nghiên cứu cấu trúc dữ liệu lưu trữ hiệu quả cho việc tìm kiếm

- Tìm hiểu các bài toán về tìm kiếm, nghiên cứu, cài đặt một số thuật toán tìm kiếm

3 Phạm vi nghiên cứu

Luận văn tập trung nghiên cứu các kỹ thuật cơ bản cho bài toán tìm kiếm, cấu trúc biểu diễn, các thao tác trên cây nhị phân tìm kiếm, tìm kiếm theo phương pháp băm, kỹ thuật index trong cơ sở dữ liệu, tìm kiếm xâu

Nội dung luận văn gồm có phần mở đầu, 4 chương, phần kết luận, tài liệu tham khảo và phụ lục

Chương 1 Tổng quan về các giải thuật tìm kiếm cơ bản Chương này trình

bày: Tìm kiếm tuyến tính, Tìm kiếm nhị phân, Tìm kiếm thông tin trên bảng, Tìm kiếm theo phương pháp băm, Phương pháp địa chỉ mở, Tìm kiếm xâu

Chương 2 Cây nhị phân tìm kiếm Chương này trình bày: khái niệm về cây,

cây nhị phân tìm kiếm, cấu trúc dữ liệu biểu diễn cây nhị phân tìm kiếm, các thao

Trang 10

tác trên cây nhị phân tìm kiếm, khái niệm cây cân bằng AVL, cấu trúc dữ liệu biểu diễn cây nhị phân cân bằng, các thao tác trên cây nhị phân cân bằng và cây nhị phân tìm kiếm tối ưu

Chương 3 Tìm kiếm index trong cơ sở dữ liệu Chương này trình bày: về

khái niệm index, phương pháp thiết kế index và truy vấn với cấu trúc index Giới thiệu về Index Lucene, kiến trúc Lucene, kiến trúc File Index và chỉ mục đảo ngược

Chương 4 Tìm kiếm xâu mẫu Chương này trình bày: về tổng quan vấn đề

tìm kiếm, bài toán đối sánh mẫu trong vấn đề tìm kiếm - so đơn mẫu, một số thuật toán đối sánh mẫu điển hình: KMP (Knuth Morris Pratt), BM (Boyer-Moore), khái niệm tập mờ, tiếp cận mờ cho bài toán tìm kiếm, mô hình Otomat mờ so mẫu và thuật toán KMP mờ Luận văn cài đặt thuật toán KMP thử nghiệm xây dựng một ứng dụng tìm kiếm trên danh bạ điện thoại

Trang 11

CHƯƠNG 1 TỔNG QUAN VỀ CÁC GIẢI THUẬT TÌM KIẾM CƠ BẢN

1.1.Tìm kiếm tuyến tính

Tìm kiếm tuyến tính([2], [3], [4], [9]) hay tìm kiếm tuần tự là phương pháp tìm kiếm một phần tử cho trước trong một danh sách bằng cách duyệt lần lượt từng phần tử của danh sách đó cho đến lúc tìm thấy giá trị mong muốn hoặc đã duyệt qua toàn bộ danh sách mà chưa thấy giá trị mong muốn

Bài toán Cho mảng a gồm n phần tử khác nhau: a1, a2, a3, , an và một phần tử X,

ta cần tìm vị trí i (1 ≤ i ≤ n) sao cho ai = X hoặc trả lại giá trị -1 nếu không có

phần tử như vậy trong mảng đã cho

Ý tưởng thuật toán

Thuật toán tiến hành so sánh phần tử đã cho trước với các phần tử thứ nhất, thứ hai, … của mảng cho đến khi thấy phần tử cần tìm hoặc đã tìm hết mảng mà không thấy phần tử

Thuật toán 1.1

Bước 1: i := 1; { Bắt đầu phần tử đầu tiên của dãy}

Bước 2: So sánh a[i] với x:

+ Nếu a[i] = x: Tìm thấy Dừng - trả về giá trị i

+ Ngược lại a[i] ≠ x: chuyển sang bước 3

Bước 3: i := i+1; {xét phần tử kế tiếp trong mảng}

Nếu i > N: Hết mảng, không tìm thấy Dừng - trả về giá trị -1 Ngược lại: Lặp lại Bước 2

Ví dụ 1.1 Cho dãy số a : 10, 6, 2, 14, 9, 15 Tìm x = 9

Trang 12

Tìm thấy x = 9 tại vị trí i = 5 Dừng thuật toán

Độ phức tạp của thuật toán

Giải thuật tìm kiếm tuyến tính có độ phức tạp tính toán cấp n: T(n) = O(n)

Cài đặt thuật toán

int TimkiemTT(int x, int n, int a[])

Trang 13

Bài toán Cho mảng a gồm n phần tử khác nhau đã đƣợc sắp xếp theo thứ tự tăng:

a1, a2, a3, …, an và một phần tử X, ta cần tìm vị trí i (1 ≤ i ≤ n) sao cho ai = X hoặc trả lại giá trị -1 nếu không có phần tử nhƣ vậy trong mảng đã cho

Trang 14

Ý tưởng thuật toán

Trong mỗi bước, so sánh phần tử cần tìm với phần tử nằm ở chính giữa danh

sách Nếu hai phần tử bằng nhau thì phép tìm kiếm thành công và thuật toán kết

thúc Nếu chúng không bằng nhau thì tùy vào phần tử nào lớn hơn, thuật toán lặp lại

bước so sánh trên với nửa đầu hoặc nửa sau của danh sách Số lượng phần tử trong

danh sách cần xem xét sẽ giảm đi một nửa sau mỗi bước

Giả sử, dãy khóa đang xét là a1, a2, …, ar thì khóa ở giữa dãy sẽ là ai với

i = [ ] Tìm kiếm sẽ kết thúc nếu X = ai Nếu X < ai tìm kiếm sẽ được thực hiện

tiếp với a1, a2, …, ai-1; còn nếu X > ai tìm kiếm lại được làm với ai+1, …, ar Tiếp tục

sử dụng kỹ thuật tìm kiếm tương tự trên dãy sau Quá trình tìm kiếm được tiếp tục

cho đến khi tìm thấy khóa mong muốn hoặc không còn dãy khóa để xét

Thuật toán 1.2

Bước 1: Nhập N, các số hạng a1, a2, an và khóa X

Bước 2: left := 1; right := N; { tìm kiếm trên tất cả các phần tử}

Bước 3: mid := (left+right)/2; {lấy mốc so sánh}

{ So sánh a[mid] với x:}

+ Nếu a[mid] = X: Tìm thấy Dừng lại

+ Nếu a[mid] > X: { tìm tiếp x trong dãy con a[left] a[mid-1]:}

Trang 15

Ở ví dụ trên thì lần duyệt thứ ba a[mid] = x Vậy chỉ số i cần tìm là i = mid = 6

- Trường hợp không tìm thấy khóa: Giả sử với n = 10, x = 25

Trang 16

Cài đặt thuật toán

int TimkiemNP(int x, int n, int a[])

{ int left, right, mid;

} else { if (x > a[mid])

{

left = mid + 1; }

else {

right = mid - 1; }

} }

if (Found)

Trang 17

{ return mid;

} else

{ return -1;

} }

Độ phức tạp của thuật toán

Giải thuật tìm kiếm nhị phân có độ phức tạp tính toán cấp log2n: T(n) = O(log 2 n)

Kết quả thử nghiệm

- Trường hợp tìm thấy khóa

Hình 1.2 Kết quả thực hiện chương trình với ví dụ 1.2

Trang 18

- Trường hợp không tìm thấy khóa

Hình 1.3 Kết quả thực hiện chương trình với ví dụ 1.2

1.3 Tìm kiếm thông tin trên bảng

Tìm kiếm thông tin trên bảng([6]) là một phương pháp tìm kiếm bắt đầu từ một khóa và tìm một phần tử chứa khóa này Cách thực hiện và truy xuất các bảng trong vùng nhớ liên tục, bắt đầu từ các bảng hình chữ nhật thông thường, sau đó đến các bảng tam giác, bảng lồi lõm… Việc tra cứu bảng có thể đạt hiệu quả hơn nhiều so với bất kỳ phương pháp tìm kiếm nào do thời gian cần thiết là O(1) - có nghĩa là thời gian có giới hạn là một hằng số và độc lập với kích thước của bảng

Các phần tử của bảng mà chúng ta xem xét được đánh chỉ số bằng một mảng các số nguyên, tương tự cách đánh chỉ số của mảng

Trang 19

1.3.1 Bảng chữ nhật

- Thứ tự ưu tiên hàng và thứ tự ưu tiên cột:

Thứ tự ưu tiên hàng: Là đọc các phần tử ở hàng thứ nhất trước, từ trái sang phải, sau đó đến các phần tử hàng thứ hai và cứ thế tiếp tục cho đến đọc hàng cuối cùng

Thứ tự ưu tiên cột: Là đọc các phần tử ở cột thứ nhất trước từ trên xuống, sau đó đến các phần tử cột thứ hai và cứ thế tiếp tục cho đến đọc cột cuối cùng

Ví dụ 1.3 Giả sử có một bảng trừu tượng gồm 3 hàng, 4 cột và hàng được

đánh số là từ 1 đến 3 và cột được đánh số từ 6 đến 9 thì thứ tự của các phần tử theo thứ tự ưu tiên hàng như sau: (1,6) (1,7) (1,8) (1,9) (2,6) (2,7) (2,8) (2,9) (3,6) (3,7) (3,8) (3,9); thứ tự của các phần tử theo thứ tự ưu tiên cột như sau: (1,6) (2,6) (3,6) (1,7) (2,7) (3,7) (1,8) (2,8) (3,8)

Trang 20

- Đánh chỉ số cho bảng chữ nhật:

Giả sử có bảng chữ nhật gồm m hàng, n cột và thứ tự hàng được đánh số từ 0 đến m – 1, và cột từ 0 đến n – 1 Số phần tử của bảng là m*n, đó cũng là số phần tử thực hiện liên tục trong mảng và được đánh số các phần tử trong mảng từ 0 đến m*n-1 Phần tử (0, 0) nằm tại vị trí 0, các phần tử thuộc hàng đầu tiên trong bảng (0, j) nằm tại vị trí j Phần tử đầu của hàng thứ hai (1, 0) nằm ngay sau phần tử (0, n – 1), đó là vị trí n Tiếp theo, phần tử (1, j) nằm tại vị trí n + j Các phần tử của hàng

kế tiếp cũng sẽ nằm sau số phần tử của hai hàng trước đó (2*n phần tử) Do đó phần

tử (2, j) nằm tại vị trí 2*n + j Tổng quát, các phần tử thuộc hàng i có n*i phần tử phía trước, nên suy ra công thức tính vị trí trong mảng nối tiếp mà một phần tử trong bảng chữ nhật được lưu trữ (hàm chỉ số) là: Phần tử (i, j) trong bảng chữ nhật nằm tại vị trí n*i + j trong mảng nối tiếp

- Mảng truy xuất:

Tính toán cho các hàm chỉ số của các bảng chữ nhật, các trình biên dịch của hầu hết các ngôn ngữ bậc cao sẽ dịch hàm này sang ngôn ngữ máy thành một số bước tính toán cần thiết Vì trên các máy tính nhỏ, phép nhân thường thực hiện rất chậm nên có thể sử dụng phương pháp khác để tránh phép nhân Phương pháp này lưu một mảng phụ chứa một phần của bảng nhân với thừa số là n:

0, n, 2*n, 3*n, … , (m-1)*n

Lưu ý, mảng này nhỏ hơn bảng chữ nhật rất nhiều nên nó có thể được lưu thường trực trong bộ nhớ Các phần tử của nó chỉ phải tính một lần (và chúng có thể được tính chỉ bằng phép cộng) Khi gặp một yêu cầu tham chiếu đến bảng chữ nhật, trình biên dịch có thể tìm vị trí của phần tử (i, j) bằng cách lấy phần tử thứ i trong mảng phụ cộng thêm j để đến vị trí cần có

Trang 22

1.3.2 Các bảng tam giác

Một bảng tam giác chỉ cần các địa chỉ (i, j) với i j

Cách biểu diễn bảng tam giác như Hình 1.6

Hình 1.6 Các bảng tam giác với nhiều dạng khác nhau

Để xây dựng hàm chỉ số mô tả cách ánh xạ này, giả sử các hàng, cột đều được đánh số bắt đầu từ 0 Để tìm vị trí của phần tử (i, j) trong mảng liên tục ta cần tìm vị trí bắt đầu của hàng i, sau đó để tìm cột j ta chỉ việc cộng thêm j vào điểm bắt đầu hàng i Nếu các phần tử của mảng liên tục được đánh số bắt đầu từ 0 thì chỉ số của điểm bắt đầu của hàng thứ i cũng chính là số phần tử nằm ở các hàng trên hàng

i Vậy trên hàng thứ 0 có 0 phần tử và chỉ có một phần tử của hàng 0 là xuất hiện trước hàng 1 Đối với hàng 2, có 1 + 2 = 3 phần tử đi trước và trường hợp tổng quát

ta thấy số phần tử có trước hàng i là: 1 + 2 + … + i = i *(i+1) Vậy phần tử (i, j) trong bảng tam giác tương ứng phần tử i*(i+1) + j của mảng liên tục

Trang 23

Ví dụ 1.5 Giả sử có bảng tam giác sau:

Trang 24

Tương tự như bảng chữ nhật, tránh mọi phép nhân và chia bằng cách tạo một mảng truy xuất chứa các phần tử tương ứng với các chỉ số của các hàng trong bảng tam giác Vị trí i trong mảng truy xuất là

i*(i + 1) Mảng truy xuất được tính toán một lần khi bắt đầu chương trình và được sử dụng lặp lại cho mỗi truy xuất đến bảng tam giác

1.3.3 Các bảng lồi lõm

Để tạo mảng truy xuất, ta phải xây dựng bảng lồi lõm theo thứ tự bắt đầu từ hàng đầu tiên Phần tử 0 của mảng truy xuất, là bắt đầu của mảng liên tục Sau khi mỗi hàng của bảng lồi lõm được xây dựng xong, chỉ số của vị trí đầu tiên chưa sử dụng tới của vùng nhớ liên tục chính là giá trị của phần tử kế tiếp trong mảng truy xuất và được sử dụng để bắt đầu xây dựng hàng kế của bảng lồi lõm

Bảng lồi lõm không có một quan hệ có thể đoán trước nào giữa vị trí của một hàng và chiều dài của nó Ví dụ như Hình 1.8 dưới đây

Trang 25

1.3.4 Các bảng chuyển đổi

Các bảng chuyển đổi là việc sử dụng nhiều mảng truy xuất để tham chiếu cùng lúc đến một bảng các phần tử qua một vài khóa khác nhau Với phương pháp này các thành phần dữ liệu được xem như là khóa đều được xử lý cùng một cách Các phần tử có thể lưu trữ theo một thứ tự tùy ý (thứ tự mà các phần tử được nhập

từ hệ thống) Các phần tử thuộc danh sách liên kết (các phần tử của các mảng truy xuất chứa các địa chỉ đến từng phần tử riêng)

Ví dụ như Hình 1.9

Trang 26

Index Name Address Phone

2 Nguyễn Bảo Anh Cửa Lò, Nghệ An 2884285

3 Hồ Thị An Nghi Xuân, Hà Tĩnh 4372296

4 Nguyễn Thị Thủy Diễn Châu, Nghệ An 2863386

5 Nguyễn Thị Xuân Bỉm Sơn, Thanh Hóa 2495723

Hình 1.9 Mảng truy xuất cho nhiều khóa bảng chuyển đổi

1.4 Tìm kiếm theo phương pháp băm

Các phép toán trên các cấu trúc dữ liệu như danh sách, cây nhị phân,… phần lớn được thực hiện bằng cách so sánh các phần tử của cấu trúc, do vậy thời gian truy xuất không nhanh và phụ thuộc vào kích thước của cấu trúc Phần tìm kiếm theo phương pháp băm([3], [4], [9])

này sẽ giúp hạn chế số lần so sánh, và vì vậy sẽ giảm thiểu được thời gian truy xuất thông tin Độ phức tạp của các phép toán trên bảng băm thường có bậc là O(1) và không phụ thuộc vào kích thước của bảng băm Bảng băm là một cấu trúc dữ liệu hiệu quả để cài đặt các từ điển, sử dụng hàm băm

Trang 27

để ánh xạ từ giá trị xác định, được gọi là khóa Do đó, bảng băm là một mảng kết hợp Hàm băm được sử dụng chuyển đổi từ khóa thành chỉ số (giá trị băm) trong mảng lưu trữ các giá trị tìm kiếm

1.4.1 Bảng băm

Sau đây là dạng bảng băm cơ bản

Giả sử ta có một tập phần tử gồm các giá trị khoá bất kỳ được tổ chức lưu trữ dưới dạng bảng chỉ mục m phần tử như sau gọi là bảng truy xuất trực tiếp

- Phần tử có giá trị khoá k được lưu trữ tương ứng tại vị trí thứ k trong bảng chỉ mục

- Để tìm kiếm một phần tử nào đó ta sẽ dựa vào khoá của nó và tra trong bảng chỉ mục, nếu tại vị trí đó có phần tử thì chính là phần tử cần tìm, nếu không

có phần tử nào có nghĩa là phần tử cần tìm không có trong bảng chỉ mục

- Thời gian tìm kiếm là hằng số O(1)

Mô tả dữ liệu Bảng băm được mô tả bằng các thành phần sau:

- K: tập các khoá (set of keys)

- M: tập các địa chỉ (set of addresses)

- HF(k): hàm băm dùng để ánh xạ một khoá k từ tập các khoá K thành một địa chỉ tương ứng trong tập M

Trang 28

Các phép toán trên bảng băm

Các phép toán trên bảng băm gồm: Khởi tạo, Kiểm tra rỗng, Lấy kích thước của bảng băm, Tìm kiếm, Thêm mới phần tử, Loại bỏ, Sao chép, Duyệt

Các bảng băm thông dụng

- Bảng băm với phương pháp nối kết trực tiếp: mỗi địa chỉ bảng băm tương ứng với một danh sách liên kết Các nút bị xung đột được nối kết với nhau trên một danh sách liên kết

- Bảng băm với phương pháp nối kết hợp nhất: Bảng băm loại này được cài đặt bằng danh sách kề, mỗi nút có hai trường: trường key chứa khóa của nút

và trường next chỉ nút kế bị xung đột Các nút bị xung đột được nối kết với nhau qua trường liên kết next

- Bảng băm với phương pháp dò tuyến tính: ví dụ như khi thêm nút vào bảng băm loại này nếu băm lần đầu bị xung đột thì lần lượt dò địa chỉ kế… cho đến khi gặp địa chỉ trống đầu tiên thì thêm nút vào địa chỉ này

1.4.2 Hàm băm

Hàm băm là hàm biến đổi khóa của nút thành địa chỉ trên bảng băm

Trong đó:

- Khóa có thể là khóa ở dạng số hay dạng chuỗi

- Địa chỉ được tính ra là các số nguyên trong khoảng 0 đến M – 1 với M là địa chỉ trên bảng băm

- Hàm băm thường được dùng ở dạng công thức:

Ví dụ như công thức f(key) = key%M với M là độ lớn của bảng băm

 Khi hàm băm hai khoá vào cùng một địa chỉ thì gọi là đụng độ

Một hàm băm tốt thỏa mãn các điều kiện sau

- Tính toán nhanh

- Các khoá được phân bố đều trong bảng băm

- Ít xảy ra đụng độ

Trang 29

Một số phương pháp xây dựng hàm băm

Hình 1.11 Hàm băm dạng bảng tra được tổ chức dưới dạng danh sách kề

Hàm băm sử dụng phương pháp chia

Hàm băm sử dụng phương pháp chia theo công thức dùng số dư:

h(k) = k mod m

Nghĩa là gắn k vào bảng có m ô nhờ sử dụng ô xác định bởi phần dư của phép chia

k cho m Trong đó k là khoá, m là kích thước của bảng

Trang 30

Ta có tập khoá là các giá trị số gồm 3 chữ số và vùng nhớ cho bảng địa chỉ

có khoảng 100 mục, nhƣ vậy ta sẽ lấy hai số cuối của khoá để làm địa chỉ theo phép chia lấy dƣ cho 100: chẳng hạn 625 mod 100 = 25

Tuy nhiên ta nhận thấy nếu hàm băm dùng công thức nhƣ trên thì địa chỉ của khoá tính đƣợc chỉ căn cứ và hai ký tự cuối Vì thế, để hàm băm có thể tính địa chỉ khoá một cách ngẫu nhiên ta nên chọn m = 97 thay vì 100

M = 100 Khoá Địa chỉ

Trang 31

Ví dụ 1.9

Ta có tập khoá là các giá trị số gồm 3 chữ số và vùng nhớ cho bảng địa chỉ

có khoảng 100 mục sử dụng trên hàm băm có hai giá trị A khác nhau: A = 0.52173,

A = 0.61803 Nhƣ vậy dựa vào công thức trên ta sẽ lấy đƣợc địa chỉ, chẳng hạn: 100*(625*0.52173 Mod 1) = 8

1.4.3 Bảng băm mở

Bảng băm mở là một số khóa có cùng địa chỉ, lúc này mỗi mục địa chỉ sẽ là một danh sách liên kết các phần tử có cùng địa chỉ, thời gian truy xuất có thể bị suy giảm đôi chút

Trang 32

Bảng băm mở là phân chia tập hợp đã cho thành một số cố định các lớp Chẳng hạn, ta phân tập các phần tử cần quản lí thành N lớp, đánh số từ 0 N-1 Ta

sử dụng một mảng T với các chỉ số từ 0 đến N – 1, mỗi phần tử của mảng có thể lưu được các phần tử thuộc một lớp Các phần tử thuộc một lớp được tổ chức dưới dạng một danh sách liên kết Như vậy bảng T là bảng các con trỏ trong đó T[i] là con trỏ đến danh sách các phần tử thuộc lớp thứ i

Việc phân bố các phần tử của tập hợp A, với tập khóa K vào các lớp được thực hiện bởi một hàm h: K  {0, 1, …, N-1}, gọi là hàm băm (hash function) Nếu

k là khóa một phần tử nào đó trong tập A, thì h(k) là chỉ số lưu phần tử này trong bảng T Ta gọi h(k) là giá trị băm của phần tử có khóa k Một trong các điều kiện bắt buộc của bảng băm lưu các phần tử là phải xây dựng được hàm băm hiệu quả

Có hai tiêu chuẩn chính để lựa chọn một hàm băm, trước hết phải đơn giản trong tính toán Thứ hai là phải phân bố đều các phần tử vào các lớp Trên thực tế tiêu chuẩn thứ hai khó đạt được Sau đây là một số phương pháp thiết kế hàm băm

a Phương pháp cắt bỏ

Giả sử khóa của các phần tử là những số nguyên Ta sẽ bỏ đi một phần nào

đó của khóa và lấy phần còn lại làm giá trị băm của khóa Chẳng hạn, khóa là các số nguyên 10 chữ số và bảng băm gồm 1000 thành phần, khi đó ta có thể lấy ba chữ số

Trang 33

Ví dụ, với khóa k = 1234567890 được biến đổi thành 123 + 456 + 78 + 90 =

774 Với khóa 9876543210 được biến đổi thành 987 + 654 + 32 + 10 = 1683, sau khi cắt bỏ phần đầu còn lại giá trị băm là 683

Vì mọi thông tin trong khóa đều được phản ánh vào giá trị băm, nên phương pháp gấp cho phân bố các khóa đều hơn phương pháp cắt bỏ

c Phương pháp lấy phần dư

Với khóa là các số nguyên, giả sử cần chia tập hợp các phần tử thành M lớp

Ta lấy khóa chia cho M lấy phần dư làm giá trị băm Hàm băm được xác định h(k)

= k mod M Tính phân bố đều của các khóa phụ thuộc nhiều vào việc chọn số N Tốt nhất chọn N là các số nguyên tố

1.4.4 Bảng băm đóng

Khác với bảng băm mở, mỗi thành phần T[i] của bảng lưu giữ con trỏ tới danh sách các phần tử của tập hợp được đưa vào lớp thứ i (i = 0 N-1); trong bảng băm đóng, mỗi phần tử của tập hợp được lưu trữ trong chính các thành phần T[i] của mảng Do đó bảng băm đóng là một mảng các phần tử

Với cách tổ chức lưu trữ các phần tử như trên thì sẽ xảy ra trường hợp đụng

độ khi có hai phần tử e1, e2 có khóa tương ứng là k1 và k2 mà h(k1) = h(k2) =i, vì khi

đó hai phần tử e1, e2 đều lưu vị trí i trong mảng Để giải quyết đụng độ thường dùng phương pháp băm lại Phương pháp băm lại như sau: lần lượt xét các vị trí h(k1), h(k2), … cho tới khi tìm được một vị trí trống để đặt phần tử k vào đó Nếu không tìm được vị trí nào trống thì bảng đã đầy và không thể đưa vào bảng Trong đó hi(k) (i= 1, 2, …) là các giá trị băm lại lần thứ i, nó chỉ phụ thuộc vào khóa k Sau đây là một số phương pháp băm lại

a Băm lại tuyến tính

Các hàm hi(k) được xác định như sau:

hi(k) = (h(k) + i) mod N

Trang 34

Với cách băm như trên, mảng lưu các phần tử được xem như một mảng vòng tròn Mỗi khi cần băm lại của khóa k sẽ xét các vị trí h(k) + 1, h(k) + 2, …

Chẳng hạn, N = 10 và các khóa a, b, c, d, e có các giá trị như sau:

Hạn chế của phương pháp băm lại tuyến tính là các giá trị khóa sẽ được xếp liền vào sau các giá trị khóa ban đầu đã đưa vào bảng mà không có đụng độ Do đó, càng ngày các giá trị khóa càng tụ lại thành các đoạn dài và giữa các đoạn lấp đầy là các khoảng trống Vì vậy, việc tìm một vị trí trống trong bảng để đưa giá trị mới vào, càng về sau càng chậm

b Băm lại bình phương

Băm lại bình phương là một cách tốt hơn băm lại tuyến tính, tránh được sự tập trung của các giá trị khóa cùng giá trị băm, hàm băm lại được xác định như sau:

hi(k) = (h(k)+i2) mod N

Cách băm lại này có một hạn chế là các giá trị băm lại không lấp đầy tất cả các chỉ số của mảng Do đó khi cần đưa vào bảng một giá trị mới, có thể không tìm được vị trí trống mặc dù trong bảng vẫn còn các vị trí trống

Trang 35

c Các phép toán trên bảng băm đóng

Để kiểm tra một khóa x trong bảng băm đóng T ta phải duyệt lần lượt các vị trí h(k), h1(k), h2(k), … Giả sử các phần tử của bảng chưa bị xóa Khi đó hoặc tìm được một vị trí trong bảng chứa khóa k, hoặc tìm được một vị trí trống đầu tiên

ht(k) Trong trường hợp này kết luận rằng khóa k không có trong bảng Tuy nhiên,

sẽ phức tạp hơn nếu trong bảng đã thực hiện một số thao tác xóa Trong trường hợp này, nếu tìm được một vị trí trống đầu tiên ht(k) thì chưa thể kết luận được k không

có trong bảng vì có thể vị trí này lúc thêm phần tử khóa k đã có nhưng sau đó đã bị xóa Do đó hoàn toàn có thể k nằm trong các vị trí ht+1(k), ht+2(k),…

Để đảm bảo rằng khi tìm ra vị trí trống đầu tiên ht(k) mà chắc chắn bảng không chứa k, ta đưa vào bảng hai loại hằng deleted để gán cho vị trí của phần tử bị xóa và hằng empty dùng cho những vị trí trống thực sự Mỗi khi xóa một phần tử thì vị trí này được gán hằng deleted Khi cần thêm một phần tử mới vào bảng, có thể thêm vào vị trí đã xóa Với mỗi khóa k, các thao tác insert, delete, member trên bảng băm đóng đều thực hiện theo cách chung là giá trị băm h(k), nếu tại vị trí này không đúng yêu cầu thì thăm dò lần lượt tại các vị trí h1(k), h2(k), …

1.5 Phương pháp địa chỉ mở

Phương pháp địa chỉ mở ([3], [4], [9]) là phương pháp mà tất cả các phần tử đều được cất giữ vào bảng Do đó mỗi ô của bảng hoặc là chứa khóa hoặc là nil

Ý tưởng thuật toán

- Để thực hiện bổ sung, nếu ô tìm được là bận, ta sẽ tiến hành khảo sát lần lượt (hay còn gọi là dò thử) các ô của bảng cho đến khi tìm được ô rỗng để nạp khóa vào Thay vì tìm tuần tự theo thứ tự 0, 1, 2, …, m-1 (sẽ đòi hỏi thời gian Θ(n)), dãy các vị trí thử sẽ phụ thuộc vào khóa được bổ sung Để xác định các ô dò thử ta sẽ mở rộng định nghĩa hàm băm

- Khi tìm kiếm, ta sẽ tìm dọc theo dãy các phép dò thử giống như dãy dò thử khi thực hiện chèn phần tử vào bảng

*Nếu tìm được phần tử giống với khóa đã cho thì trả lại phần tử đó

Trang 36

*Nếu tìm đƣợc con trỏ nil thì phần tử cần tìm không có trong bảng

Ta mở rộng định nghĩa hàm băm nhƣ sau:

j:= h(k,i)

if T[j]= nil Then T[j] := k Return j Else i := i+1 End

if i = m then

Error “hash table overflow”

Cài đặt thuật toán

int M;

struct hash_table{

int data;

Trang 38

j:= h(k,i)

if T[j] = j Then return j

Chèn khóa k vào bảng thành công

Chèn khóa k vào bảng không thành công

Trang 39

i := i+1 end

return -1;

Cài đặt thuật toán

int hash_search(struct hash_table T[], int k ) {

Trang 40

Kết quả thử nghiệm

Trường hợp không tìm thấy :

Hình 1.13 Kết quả thực hiện chương trình trường hợp không tìm thấy khóa k

trong bảng

Ngày đăng: 26/07/2017, 20:58

Nguồn tham khảo

Tài liệu tham khảo Loại Chi tiết
[5]. Cơ bản về index trong SQL Server, http://www.bigdata.com.vn/2013/07/co-ban-ve-index-trong-sql-server.html Link
[6]. Chương 12- bảng và truy xuất thông tin – Giáo trình cấu trúc dữ liệu và giải thuậthttp://m.123doc.org/document/629869-bang-va-truy-xuat-thong-tin.htm Link
[7].Lucenne.Net document, http://incubator.apache.org/lucene.net/docs/2.1/Lucene.Net.Documents.html [8]. Lucene.Net overview, http://incubator.apache.org/lucene.net/ Link
[1]. Nguyễn Thị Thanh Huyền, Đối sánh mẫu theo tiếp cận otomat mờ và ứng dụng, Luận án tiến sĩ, Viện Toán ứng dụng và Tin học, trường Đại học Bách khoa Hà Nội, 2007 Khác
[2]. Đỗ Xuân Lôi, Cấu trúc dữ liệu và giải thuật, NXB ĐHQGHN, 2008 Khác
[3]. PGS.TS. Nguyễn Đức Nghĩa, Cấu trúc và giải thuật, NXB Bách Khoa Hà Nội, 2008 Khác
[4]. Hồ Thuần, Hồ Cẩm Hà, Trần Thiên Thanh, Cấu trúc dữ liệu, Phân tích thuật toán và phát triển phần mềm, NXBGD, 2008 Khác
[9]. Shou-chuan-Yang, A search algorithm and data structure for an efficient information system, International conference on Computational linguistics coling, 1969 Khác

TỪ KHÓA LIÊN QUAN

TRÍCH ĐOẠN

TÀI LIỆU CÙNG NGƯỜI DÙNG

TÀI LIỆU LIÊN QUAN

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