53
Đại Hc Sư Phm Tp. HChí Minh Đại Hc Sư Phm Tp. HChí Minh CU TRÚC DLIU 2 CU TRÚC DLIU 2 Chương 02: BNG BĂM

CTDL2_CH02_BangBam

  • Upload
    itnoi

  • View
    303

  • Download
    2

Embed Size (px)

Citation preview

Page 1: CTDL2_CH02_BangBam

Đại Học Sư Phạm Tp. Hồ Chí MinhĐại Học Sư Phạm Tp. Hồ Chí Minh

CẤU TRÚC DỮ LI ỆU 2 CẤU TRÚC DỮ LI ỆU 2

Chương 02: BẢNG BĂM

Page 2: CTDL2_CH02_BangBam

Đề cương môn học: CTDL2CTDL2

• Chương 1: Sắp xếp ngoại

• Chương 2: Bảng băm (Hash Table)

• Chương 3: B – Cây (B-Tree)

• Chương 4: Cây Đỏ Đen (Red-Black Tree)

22CTDL2 – Lương Trần Hy HiếnLương Trần Hy Hiến

Page 3: CTDL2_CH02_BangBam

Nội dung

• Giới thiệu bài toán

• Hàm băm

• Các phương pháp xử lý đụng độ

• Phân tích phép băm

33CTDL2 – Lương Trần Hy HiếnLương Trần Hy Hiến

• Phân tích phép băm

Page 4: CTDL2_CH02_BangBam

ĐẶT VẤN ĐỀ

• Cho S là tập hợp n phần tử trong 1 cấu trúc dữ liệu được đặc trưng bởi 1 giá trị khóa

• Tìm 1 phần tử có hay không trong S– Tìm tuyến tính (O(n)), chưa được sắp xếp

– Tìm nhị phân (O(log n)), đã được sắp xếp

44CTDL2 – Lương Trần Hy HiếnLương Trần Hy Hiến

– Tìm nhị phân (O(log2n)), đã được sắp xếp

• Có hay chăng 1 thuật toán tìm kiếm với O(1)– Có, song ta phải tổ chức lại dữ liệu

– Dữ liệu được tổ chức lại là Bảng băm

Page 5: CTDL2_CH02_BangBam

Giới thi ệu về Bảng Băm

• Là CTDL trong đó các phần tử của nó được lưu trữsao cho việc tìm kiếm sẽ được thực hiện bằng cáchtruy xuất trực tiếp thông qua từ khóa.

• Bảng băm có M vị trí được đánh chỉ mục từ 0 đến M-1, M là kích thước của bảng băm.

• Các phương pháp băm:

55CTDL2 – Lương Trần Hy HiếnLương Trần Hy Hiến

• Các phương pháp băm:– PP kết nối trực tiếp

– PP kết nối hợp nhất

– PP dò tuyến tính

– PP dò bậc 2

– PP băm kép

Page 6: CTDL2_CH02_BangBam

Hàm băm

• Hàm băm: biến đổi khóa thành chỉ mục trên bảng băm– Khóa có thể là dạng số hay dạng chuỗi– Chỉ mục được tính từ 0..M-1, với M là số chỉ mục

của bảng băm

66CTDL2 – Lương Trần Hy HiếnLương Trần Hy Hiến

– Hàm băm thường dùng: key % Mkey % M, với M là độ lớn của bảng băm

• Hàm băm tốt phải thoả yêu cầu– Giảm thiểu xung đột– Phân bố đều trên M địa chỉ khác nhau của bảng

băm

Page 7: CTDL2_CH02_BangBam

Mô tả dữ liệu

• 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. Thông thường HF(k) = k mod M

77CTDL2 – Lương Trần Hy HiếnLương Trần Hy Hiến

M. Thông thường HF(k) = k mod M

Page 8: CTDL2_CH02_BangBam

Ưu điểm bảng băm

• Dung hòa tốt giữa thời gian truy xuất và dung lượng bộ nhớ– Nếu ko giới hạn bộ nhớ: one-to-one, truy xuất

tức thì

– Nếu dung lượng bộ nhớ có giới hạn thì tổ chức

88CTDL2 – Lương Trần Hy HiếnLương Trần Hy Hiến

– Nếu dung lượng bộ nhớ có giới hạn thì tổ chức khóa cùng địa chỉ

• Bảng băm ứng dụng nhiều trong thực tế, thích hợp tổ chức dữ liệu có kích thước lớn và lưu trữ ngoài.

Page 9: CTDL2_CH02_BangBam

CÁCH XÂY D ỰNG BẢNG BĂM

– Dùng hàm băm để ánh xạ khóa K vào 1 vị trí trong bảng băm. Vị trí này như là 1 địa chỉ khi tìm kiếm.

– Bảng băm thường là mảng, danh sách liên

99CTDL2 – Lương Trần Hy HiếnLương Trần Hy Hiến

– Bảng băm thường là mảng, danh sách liên kết, file(danh sách đặc)

Page 10: CTDL2_CH02_BangBam

Ví dụ một bảng băm đơn giản

Khóa k sẽ được lưu trữ tại vị trí k mod M (M kích thước mảng)

0 1 2 3 4 5 6 7 8 9

1010CTDL2 – Lương Trần Hy HiếnLương Trần Hy Hiến

0 1 2 3 4 5 6 7 8 9

95

Thêm phần tử x = 95 vào mảng 95 mod 10 = 5

Page 11: CTDL2_CH02_BangBam

Ví dụ một bảng băm đơn giản

Với các giá trị: 31, 10, 14, 93, 82, 95,79,18, 27, 46

0 1 2 3 4 5 6 7 8 9

1111CTDL2 – Lương Trần Hy HiếnLương Trần Hy Hiến

0 1 2 3 4 5 6 7 8 9

10 31 82 93 14 95 46 27 18 79

Page 12: CTDL2_CH02_BangBam

Tìm ki ếm trên bảng băm

• Thao tác cơ bản nhất được cung cấp bởi Hashtable là “tìm kiếm”

• Chi phí tìm kiếm trung bình là O(1), không phụ thuộc vào số lượng phần tử của mảng

1212CTDL2 – Lương Trần Hy HiếnLương Trần Hy Hiến

phụ thuộc vào số lượng phần tử của mảng (Bảng)

• Chi phí tìm kiếm xấu nhất (ít gặp) có thể là O(n)

Page 13: CTDL2_CH02_BangBam

Các phép toán trên hàm băm

• Khởi tạo (Initialize)• Kiểm tra rỗng (Empty)• Lấy kích thước bảng băm (size)• Thêm 1 phần tử vào bảng băm (Insert)

1313CTDL2 – Lương Trần Hy HiếnLương Trần Hy Hiến

• Thêm 1 phần tử vào bảng băm (Insert)• Xóa 1 phần tử khỏi bảng băm (Remove)• Duyệt (Traverse)

Page 14: CTDL2_CH02_BangBam

Vấn đề nảy sinh

Giả sử thêm 55vào mảng

0 1 2 3 4 5 6 7 8 982 95 27

1414CTDL2 – Lương Trần Hy HiếnLương Trần Hy Hiến

82 95 27

+ 55phải lưu vào vị trí 5. Tuy nhiên vị trí này đã có chứa 95

k1 ≠ k2 mà f(k1) = f(k2) � Đụng độ=> Cần giải quyết đụng độ (xung đột)đụng độ (xung đột)

Page 15: CTDL2_CH02_BangBam

- Trong thực tế có nhiều trường hợp có nhiềuhơn 2 phần tử sẽ được “băm” vào cùng 1 vị trí

Vấn đề xung đột khi xử lý bảng băm

1515CTDL2 – Lương Trần Hy HiếnLương Trần Hy Hiến

- Hiển nhiên phần tử được “băm” đầu tiên sẽchiếm lĩnh vị trí đó, các phần tử sau cần phảiđược lưu vào các vị trí tr ống khác sao cho vấnđề truy xu ất và tìm kiếm phải dễ dàng

Page 16: CTDL2_CH02_BangBam

a. Làm giảm xung đột

-Hàm băm cần thỏa mãn các điều kiện:�Xác xuất phân bố khoá là đều nhau�Dễ dàng tính toán thao tác�Ít xảy ra đụng độ

1616CTDL2 – Lương Trần Hy HiếnLương Trần Hy Hiến

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

Thông thường, hàm băm sử dụng các số nguyên tố (vì xác suất ngẫu nhiên phân bố các số nguyên tố là đều nhất)

Page 17: CTDL2_CH02_BangBam

b. Giải quyết xung đột

Các phương pháp băm:�PP kết nối trực tiếp�PP kết nối hợp nhất�PP dò tuyến tính

1717CTDL2 – Lương Trần Hy HiếnLương Trần Hy Hiến

�PP dò tuyến tính�PP dò bậc 2�PP băm kép

Page 18: CTDL2_CH02_BangBam

i. Sử dụng DS liên kết (kết nối tr ực tiếp)

-Ý tưởng: “Các phần tử băm vào trùng vị trí k được nối vào danh sách nối kết” tại vị trí đó

0 1 2 3 4Hàm băm:

1818CTDL2 – Lương Trần Hy HiếnLương Trần Hy Hiến

0 1 2 3 421 18

Hàm băm:F(k) = k mod 5

Thêm 6, 16 6

16

Page 19: CTDL2_CH02_BangBam

*Phân tích

PP DSLK có nhiều khuyết điểm:- Khi có quá nhiều khoá vào cùng vị trí,

DSLK thì tại vị trí đó sẽ rất dài => Tăng chi phí tìm kiếm

1919CTDL2 – Lương Trần Hy HiếnLương Trần Hy Hiến

tìm kiếm- Các ô trống còn dư nhiều => lãng phí về

thời gian tìm kiếm và không gian lưu trữ

Page 20: CTDL2_CH02_BangBam

Cài đặt - Coding

- Sử dụng DSLK tại mỗi vị trí lưu trữ- Nếu xảy ra xung đột thì lưu vào cuối DS

tại vị trí trùng

2020CTDL2 – Lương Trần Hy HiếnLương Trần Hy Hiến

0 1 2 3 421 18

Hàm băm:F(k) = k mod 5

Thêm 6, 16 6

16

Page 21: CTDL2_CH02_BangBam

CÀI ĐẶT

• Khai báo cấu trúc dữ liệu• Khởi tạo bảng băm• Tạo 1 nút để thêm vào bảng băm• Xác định hàm băm• Thêm 1 nút vào bảng băm

2121CTDL2 – Lương Trần Hy HiếnLương Trần Hy Hiến

• Thêm 1 nút vào bảng băm• Xóa 1 phần tử trong bảng băm• Tìm 1 phần tử trong bảng băm.

Page 22: CTDL2_CH02_BangBam

Khai báo CTDL

const int M = 101; //Kích thước bảng bămstruct node{

int key;

2222CTDL2 – Lương Trần Hy HiếnLương Trần Hy Hiến

int key;node* next;

};typedef node* LINKLIST ;LINKLIST HashTable[M]; //bảng băm

Page 23: CTDL2_CH02_BangBam

Khởi tạo bảng bămvoid Init_HashTable(){

for (int i = 0 ; i< M; ++ i)HashTable[i] = NULL;

}

2323CTDL2 – Lương Trần Hy HiếnLương Trần Hy Hiến

}//Xác định hàm bămint Hash(int key){

return (key % M);}

Page 24: CTDL2_CH02_BangBam

Tạo 1 nút để thêm

//tạo nút có trường dữ liệu là x, hàm trả về địa chỉ của node mới tạo.

node* GetNode(int x){

node *pnew = new node;

2424CTDL2 – Lương Trần Hy HiếnLương Trần Hy Hiến

node *pnew = new node;pnew->key = x;pnew->next = NULL;return pnew;

}

Page 25: CTDL2_CH02_BangBam

Ki ểm tra bảng băm rỗng?

bool Empty(){

for(int b = 0; b < M; b++)if(HashTable[b] != NULL)

2525CTDL2 – Lương Trần Hy HiếnLương Trần Hy Hiến

if(HashTable[b] != NULL)return false;

return true;}

Page 26: CTDL2_CH02_BangBam

Hàm xuất bảng bămvoid PrintHT(){

node *p;for(int i=0;i<M;i++){

cout<<"Bucket "<<i<<": ";

2626CTDL2 – Lương Trần Hy HiếnLương Trần Hy Hiến

cout<<"Bucket "<<i<<": ";p = HashTable[i];while(p!=NULL){

cout<<“ � “<<p->key;p = p->next;

}cout<<endl;

}}

Page 27: CTDL2_CH02_BangBam

Thêm một khoá vào bảng băm//Chèn một khoá vào bảng bămvoid Insert(int k){

InsertTail_LINKLIST(HashTable[Hash(k)], k);}//Chèn cuối danh sáchvoid InsertTail_LINKLIST(LINKLIST &l, int k){

2727CTDL2 – Lương Trần Hy HiếnLương Trần Hy Hiến

{//Tạo nodenode *add = GetNode(k);if (l == NULL) l = add;else{

node * p = l;while (p->next != NULL) p = p->next;p->next = add;

}}

Page 28: CTDL2_CH02_BangBam

Xoá một khoá trong bảng băm

//Hàm xóa 1 phần tử có khóa keyvoid Delete(int key){

Delete_LINKLIST(HashTable[Hash(key)], key);}

2828CTDL2 – Lương Trần Hy HiếnLương Trần Hy Hiến

}

Page 29: CTDL2_CH02_BangBam

Xoá một khoá trong bảng bămvoid Delete_LINKLIST(LINKLIST &l, int key){

node *p = l, *q = NULL;if(p == NULL) //DS rong

cout<<endl<<"Khong tim thay - DS rong!"<<endl;else //tim thay{

2929CTDL2 – Lương Trần Hy HiếnLương Trần Hy Hiến

{if(p->key==key)//Nam dau danh sach{

l = p->next;delete p;cout<<endl<<"Da xoa!"<<endl;

}

Page 30: CTDL2_CH02_BangBam

Xoá một khoá trong bảng bămelse{

while((p != NULL)&&(p->key != key)){

q = p; p = p->next;}if(p != NULL) //tim thay{

3030CTDL2 – Lương Trần Hy HiếnLương Trần Hy Hiến

{q->next = p->next;delete p;cout<<endl<<"Da xoa!"<<endl<<endl;

}else

cout<<"KQ: Khong tim thay"<<endl;}

}}

Page 31: CTDL2_CH02_BangBam

Tìm một phần tử

// tim 1 phan tu co khoa =key trong bang bamnode* Search(int x){ int i = Hash(x);

node* p = HashTable[i];if(p != NULL){

3131CTDL2 – Lương Trần Hy HiếnLương Trần Hy Hiến

{while((p != NULL)&&(p->key != x))

p = p->next;}return p;

}

Page 32: CTDL2_CH02_BangBam

Hàm tạo menu chương trìnhvoid menu(){

puts("DEMO HASHTABLE dung DSLK");puts("1. Them 1 phan tu vao bang bam");puts("2. Xoa 1 phan tu trong bang bam");

3232CTDL2 – Lương Trần Hy HiếnLương Trần Hy Hiến

puts("2. Xoa 1 phan tu trong bang bam");puts("3. Tim 1 phan tu co khoa x");puts("4. Xuat Hash Table");puts("0. Ket thuc");

}

Page 33: CTDL2_CH02_BangBam

Chương trình chính

int main(){

int chon, x;Init_HashTalbe();//khoi tao bang bamdo

3333CTDL2 – Lương Trần Hy HiếnLương Trần Hy Hiến

do{ menu();

cout<<"Chon chuc nang: ";cin>>chon;cout<<endl;

Page 34: CTDL2_CH02_BangBam

Chương trình chínhswitch(chon){

case 1:do{

cout<<"Nhap khoa can them: "; cin>>x;if(x > 0) Insert(x);

3434CTDL2 – Lương Trần Hy HiếnLương Trần Hy Hiến

if(x > 0) Insert(x);}while(x > 0);break;

case 2:cout<<"Nhap khoa can xoa (key > 0): ";cin>>x;if(x > 0) Delete(x);break;

Page 35: CTDL2_CH02_BangBam

Chương trình chínhcase 3:

cout<<"Nhap khoa can tim (key > 0): ";cin>>x;if(x > 0){

if(Search(x) != NULL)cout<<"Tim thay “<<x;

else

3535CTDL2 – Lương Trần Hy HiếnLương Trần Hy Hiến

elsecout<<"Tim khong thay";

}break;

case 4: PrintHT(); break;}

}while(chon != 0);return 0;

}

Page 36: CTDL2_CH02_BangBam

ii. Sử dụng PP “kết nối hợp nhất”

-Ý tưởng: “Nếu có 1 khóa bị băm vào vị trí đã có phần tử thì nó sẽ được chèn vào ô trống phía cuối mảng”. (Dùng mảng có M phần tử)

0

3636CTDL2 – Lương Trần Hy HiếnLương Trần Hy Hiến

Hàm băm:F(k) = k mod 5Thêm

6, 16

0

1 21

2

3 18

4 6

16

Page 37: CTDL2_CH02_BangBam

iii. Sử dụng PP “Dò tuyến tính”

-Ý tưởng: “Nếu có 1 khóa bị băm vào vị trí đã có phần tử thì nó sẽ được chèn vào ô trống gần nhất” theo phía bên phải (hoặc trái)

0 1 2 3 4Hàm băm:

3737CTDL2 – Lương Trần Hy HiếnLương Trần Hy Hiến

0 1 2 3 421 18

Hàm băm:F(k) = k mod 5

Thêm 6, 16

6 16

f(key)=(f(key)+i) % M với f(key) là hàm băm chính của bảng băm.

Page 38: CTDL2_CH02_BangBam

*Phân tích

- PP này dễ thực hiện- Nếu có nhiều phần tử băm trùng nhau thì

đặc tính bảng băm bị mất đi- Trong trường hợp xấu nhất tìm kiếm trên

3838CTDL2 – Lương Trần Hy HiếnLương Trần Hy Hiến

- Trong trường hợp xấu nhất tìm kiếm trên bảng băm thành tìm kiếm tuyến tính trên mảng

Page 39: CTDL2_CH02_BangBam

Cài đặt

-Khi xảy ra đụng độ thì chèn vào vị trí trống gần nhất- Ví dụ: chèn dãy: 5 16 7 8 2 4 6 3 13 24 vào mãng băm có 11 vị trí

3939CTDL2 – Lương Trần Hy HiếnLương Trần Hy Hiến

vào mãng băm có 11 vị trí

0 1 2 3 4 5 6 7 8 9 10

24 2 3 4 5 16 7 8 6 13

Page 40: CTDL2_CH02_BangBam

code

const int M = 101; //Kich thuoc bảng băm

int HashTable[M]; //bảng băm

4040CTDL2 – Lương Trần Hy HiếnLương Trần Hy Hiến

Page 41: CTDL2_CH02_BangBam

Khởi tạo bảng băm

void Init_HashTalbe(){

for (int i = 0 ; i< M; ++ i)HashTalbe[i] = -1 ;

4141CTDL2 – Lương Trần Hy HiếnLương Trần Hy Hiến

HashTalbe[i] = -1 ;}

Page 42: CTDL2_CH02_BangBam

Ki ểm tra bảng băng rỗng?

bool Empty(){

for(int b = 0; b < M; b++)if(HashTable[i] != -1)

4242CTDL2 – Lương Trần Hy HiếnLương Trần Hy Hiến

if(HashTable[i] != -1)return false;

return true;}

Page 43: CTDL2_CH02_BangBam

Thêm một khoá vào bảng bămvoid Insert(int k){

//Xác định vị trí của khoá kint pos = Hash(key)//Kiểm tra đảm bảo vị trí pos là trốngwhile (HashTable[pos] != -1 )

4343CTDL2 – Lương Trần Hy HiếnLương Trần Hy Hiến

while (HashTable[pos] != -1 ){

pos = Hash (pos + 1);//Kiểm tra full

}

HashTable[pos] = key;}

Page 44: CTDL2_CH02_BangBam

Xoá một khoá trong bảng băm

int Delete(int key){

int pos = Hash(key); count = 1;while (HashTable[pos] != key){

pos = Hash(pos + 1 );count ++;

4444CTDL2 – Lương Trần Hy HiếnLương Trần Hy Hiến

count ++;if (count > M) break;

} if (count <= M){ HashTable[pos] = -1; return 1;}

return 0; //không tìm được khoá

}

Page 45: CTDL2_CH02_BangBam

iv. Sử dụng PP “Dò bậc hai”

0 1 2 3 4Hàm băm:

f(key)=(f(key) + i 2) % Mvới f(key) là hàm băm chính của bảng băm.

4545CTDL2 – Lương Trần Hy HiếnLương Trần Hy Hiến

0 1 2 3 421 18

Hàm băm:F(k) = k mod 5

Thêm 6, 16

616

Page 46: CTDL2_CH02_BangBam

iv. Sử dụng PP “Băm kép”

Ta sử dụng 2 hàm băm:f1(key)= key % Mf2(key)= (M–2) – key % (M-2)

4646CTDL2 – Lương Trần Hy HiếnLương Trần Hy Hiến

f2(key)= (M–2) – key % (M-2)

Page 47: CTDL2_CH02_BangBam

Cài đặt – Băm kép (Double Hashing)

-Dò tuyến tính: pos = (pos + 1) % M

4747CTDL2 – Lương Trần Hy HiếnLương Trần Hy Hiến

-Dò tuyến tính: pos = (pos + 1) % M- Băm kép: pos = (pos + u) % M

u = Hash2 (key)

Page 48: CTDL2_CH02_BangBam

code

const int M = 101; //Kich thuoc bảng băm

int HashTable[M]; //bảng băm

4848CTDL2 – Lương Trần Hy HiếnLương Trần Hy Hiến

Page 49: CTDL2_CH02_BangBam

Khởi tạo bảng băm

void Init_HashTalbe(){

for (int i = 0 ; i< M; ++ i)HashTalbe[i] = -1 ;

4949CTDL2 – Lương Trần Hy HiếnLương Trần Hy Hiến

HashTalbe[i] = -1 ;}

Page 50: CTDL2_CH02_BangBam

2 Hàm băm

int Hash(int key){

return key % M}

5050CTDL2 – Lương Trần Hy HiếnLương Trần Hy Hiến

int Hash2(int key){

return (M-2) – key % (M-2);}

Page 51: CTDL2_CH02_BangBam

Thêm một khoá vào bảng bămvoid Insert(int k){ //Xác định vị trí của khoá k

int pos = Hash(key)//Kiểm tra đảm bảo vị trí pos là trốngwhile (HashTable[pos] != -1 ){

int u = Hash2 (key);

5151CTDL2 – Lương Trần Hy HiếnLương Trần Hy Hiến

int u = Hash2 (key);pos = (pos + u ) % M;//Kiểm tra full

}

HashTable[pos] = key;}

Page 52: CTDL2_CH02_BangBam

Bài tập

Viết chương trình hiện thực từ điển Anh - Việt. Mỗi nút của bảng băm có khai báo các trường sau:– Trường word là khoá 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ế nếu bị xung đột.

Tập khoá là một chuỗi tiếng anh, tập địa chỉ có 26 chữ cái. Chọn hàm băm sau cho khoá bắt đầu bằng ký tự a được băm

5252CTDL2 – Lương Trần Hy HiếnLương Trần Hy Hiến

Chọn hàm băm sau cho khoá bắt đầu bằng ký tự a được băm vào địa chỉ 0, b băm vào địa chỉ 1,…, z băm vào địa chỉ 25. Chương trình có những chức năng như sau:1. Nhập vào một từ2. Xem từ điển theo ký tự đầu.3. Xem toàn bộ từ điển.4. Tra từ điển.5. Xoá một từ, xóa toàn bộ từ điển.

Page 53: CTDL2_CH02_BangBam

Câu hỏi và thảo luận

5353CTDL2 – Lương Trần Hy HiếnLương Trần Hy Hiến