Khai bao mang HASHTABLE chua M con tro dau cua MHASHTABLE

Một phần của tài liệu giáo trình cấu trúc dữ liệu 2 (Trang 30 - 39)

3. CÁC PHƯƠNG PHÁP GIẢI QUYẾT ĐỤNG ĐỘ

khai bao mang HASHTABLE chua M con tro dau cua MHASHTABLE

--- */typedef PHNODE HASHTABLE[M]; typedef PHNODE HASHTABLE[M];

b.Cỏc phộp toỏn

Hàm băm

Giả sử chỳng ta chọn hàm băm dạng %: f(key)=key % M.

int HF (int key) {

return (key % M); }

Chỳng ta cú thể dựng một hàm băm bất kỡ thay cho hàm băm dạng

% trờn.

Phộp toỏn khởi tạo bảng băm

Khởi động cỏc HASHTABLẸ

{

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

Phộp toỏn kiểm tra bảng băm rỗng HASHTABLE[i]

Kiểm tra HASHTABLE[i] cú bị rỗng khụng?

int emptyHASHTABLE (int i) {

return(HASHTABLE[i] ==NULL ?1 :0); }

Phộp toỏn toàn bộ bảng băm rỗng

Kiểm tra bảng băm cú rỗng khụng?

int empty( )

for (int i = 0;i<M;i++)

if(HASHTABLE[i] !=NULL) return 0;

return 1 }

Phộp toỏn thờm vào

Thờm phần tử cú khúa k vào bảng băm.

Giả sử cỏc phần tử trờn cỏc HASHTABLE là cú thứ tự để thờm một

phần tử khúa k vào bảng băm trước tiờn chỳng ta xỏc định

HASHTABLE phự hợp, sau đú dựng phộp toỏn place của danh sỏch

liờn kết để đặt phần tử vào vi trớ phự hợp trờn HASHTABLẸ void insert(int k)

{

int i= HF(k)

InsertList(HASHTABLE[i],k); //phộp toỏn thờm khoỏ k vào danh sach lien ket HASHTABLE[i]

}

Phộp toỏn loại bỏ

Xúa phần tử cú khúa k trong bảng băm.

Giả sử cỏc phần tử trờn cỏc HASHTABLE là cú thứ tự, để xúa một

phần tử khúa k trong bảng băm cần thực hiện:

- Xỏcđịnh HASHTABLE phự hợp

- Tỡm phần tử để xúa trong HASHTABLE đó được xỏc định,

nếu tỡm thấy phần tử cần xúa thỡ loại bỏ phần tử theo cỏc

phộp toỏn tương tự loại bỏ một phần tử trong danh sỏch liờn kết.

void remove ( int k) { int b; PHNODE q, p; b = HF(k); p = hashHASHTABLE(b); q=p;

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

q=p; p=p->next; }

else if (p == HASHTABLE [b]) pop(b);

//Tac vu pop cua danh sach lien ket else

delafter(q);

/*tac vu delafter cua danh sach lien ket*/ }

Phộp toỏn xoỏ HASHTABLE[i]

Xúa tất cả cỏc phần tử trong HASHTABLE b.

void clearHASHTABLE (int b) {

PHNODE p,q;

//q la nut truoc,p la nut sau q = NULL; p = HASHTABLE[b]; while(p !=NULL) { q = p; p=p->next; freenode(q); }

HASHTABLE[b] = NULL; //khoi dong lai butket b }

Phộp toỏn xoỏ toàn bộ bảng băm

Xúa tất cả cỏc phần tử trong bảng băm.

void clear( ) { int b; for (b = 0; b<M ; b++) clearHASHTABLE(b); }

Phộp toỏn duyệt HASHTABLE[i]

Duyệt cỏc phần tử trong HASHTABLE b.

void traverseHASHTABLE (int b) { PHNODE p; p= HASHTABLE[b]; while (p !=NULL) { printf(“%3d”, p->key); p= p->next; } }

Phộp toỏn duyệt toàn bộ bảng băm

Duyệt toàn bộ bảng băm.

void traverse( ) {

int b;

{ printf(“\nButket %d:”,b); printf(“\nButket %d:”,b); traverseHASHTABLE(b); } } Phộp toỏn tỡm kiếm

Tỡm kiếm một phần tử trong bảng băm, nếu khụng tỡm thấy hàm này trả về hàm NULL, nếu tỡm thấy hàm này trả về con trả chỉ tỡm phần

tử tỡm thấỵ

PHNODE p; int b; b = HF (k);

p = HASHTABLE[b];

while(k > p->key && p !=NULL) p=p->next;

if (p == NULL | | k !=p->key) // khong tim thay return(NULL);

else //tim thay return(p); }

Nhận xột bảng băm dựng phương phỏp nối kết trực tiếp

Bảng băm dựng phương phỏp nối kết trực tiếp sẽ ”băm” n phần tử

vào danh sỏch liờn kết (M HASHTABLE).

Để tốc độ thực hiện cỏc phộp toỏn trờn bảng hiệu quả thỡ cần chọn

hàm băm sao cho băm đều n phần tử của bảng băm cho M HASHTABLE, lỳc này trung bỡnh mỗi HASHTABLE sẽ cú n/M

phần tử. Chẳng hạn, phộp toỏn search sẽ thực hiện việc tỡm kiếm

tuyến tớnh trờn HASHTABLE nờn thời gian tỡm kiếm lỳc này cú bậc

0 (n/M) – nghĩa là, nhanh gấp n lần so với việc tỡm kiếm trờn một

danh sỏch liờn kết cú n phần tử.

Nếu chọn M càng lớn thỡ tốc độ thực hiện cỏc phộp toỏn trờn bảng

băm càng nhanh, tuy nhiờn lại càng dựng nhiều bộ nhớ. Do vậy, cần điều chỉnh M để dung hũa giữa tốc độ truy xuất và dung lượng bộ

nhớ.

 Nếu chọn M = n thỡ năng xuất tươngđương với truy xất trờn mảng (cú bậc O(1)), tuy nhiờn tốn nhiều bộ nhớ.

 Nếu chọn M =n /k(k =2,3,4,…) thỡ ớt tốn bộ nhớ hơn k lần,

nhưng tốc độ chậm đi k lần.

Chương trỡnh minh họa

#include <stdiọh> #include <stdlib.h> #include <coniọh> #include <alloc.h> #define TRUE 1 #definr FALSE 0 #define M 10 struct nodes { int key;

struct nodes *next; };

typedef struct nodes *PHNODE; PHNODE HASHTABLE[M];

//tac vu getnode(void) {

PHNODE p;

p = (PHNODE) malloc(siseof(struct nodes)); return(p);

}

//Tac vu freenode: huy nut da cap phat void freenode(PHNODE p)

{

free(p); }

// Ham bam int HF(int key) {

return(key % M); }

//Khoi dong cac HASHTABLE void initHASHTABLE( ) { int b; for (b = 0 ;b < M;b+) HASHTABLE[b] = NULL; }

//Tac vu emptyHASHTABLE; kiem tra butket b co rong khong int emptyHASHTABLE (int b)

{

return(HASHTABLE[b] == NULL? TRUE :FALSE); }

//Tac vu empty: kiem tra bang bam co ranh khong int empty( ) { int b; for (b=0;b<M;b++) if(HASHTABLE[b]!=NULL) return(FALSE); return(TRUE); }

//Tac vu push; them nut moi vao au HASHTABLE b void push(int b,int x)

{ PHNODE p; PHNODE p; p = getnode( ); p-> key = x; p-> next =HASHTABLE[b]; HASHTABLE[b] = p; }

//Tac vu pop: xoa nut o dau HASHTABLE b int pop(int b)

{

PHNODE p; int k;

int (emptyHASHTABLE (b)) {

printf(“\nHASHTABLE%d rong,khong xoa nut duoc “,b); return(0);

}

p = HASHTABLE[b]; //nut can xoa la nut dau butket b k =p->key; //k la noi dung nut bi xoa

HASHTABLE[b] = p->next; freenode(p);

return(k); }

//Tac vu insafter: them nut moi vao HASHTABLE sau nut p void insafter(PHNODE q, int k)

{

PHNODE q; if (p == NULL)

printf(“khong them nut moi duoc”); else { q = getnode( ); q->key = k; q-> key= p->next p->next=q; } }

//Tac vu delafter: Xoa nut trong HASHTABLE trong nut p int delafter(PHNODE q)

{

PHNODE q; int k;

if(p==NULL | | p->next == NULL) {

printf (“khong xoa nut duoc”); return (0); }

q=p->next; // q chi nut can xoa k =q ->key; //k la noi dung nut bi xoa p->next = q =next;

freenode(q); return(k); }

//Tac vu place: tac vu nay chi su dung khi them nut vao HASHTABLE da co thu tu

void place(int b,int k) {

PHNODE p; q; //q la nut truoc, p la nut sau q = NULL;

for(p = HASHTABLE[b]; p!=NULL && k > p->key; p = p->next)

q=p;

if (q == NULL) //them nut vao dau butket push(b,k);

else

insafter (q, k); }

//Tac vu insert; them nut co khoa k vao bang bam void insert(int k)

{

int b; b = HF(k);

place(b, k);//tac vu place cua danh sach lien ket*/ }

//Tac vu remove : xoa nut co khoa k trong bang bam void remove (int k)

{ int b; int b; PHNODE p, q; b=HF(k); p=HASHTABLE[p]; q=p;

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

q=p; p=p->next; }

if (p == NULL)

printf(“\n Khong co nut co khoa %d”, k); else

if(p == HASHTABLE[b]) pop(b);

/*tac vu pop cua dann sach lien ket*/ else

delafter(q);

/*tac vu delafter cua danh sach lien ket*/ }

//Tac vu clearHASHTABLE; xoa tat ca cac nut trong HASHTABLE b void clearHASHTABLE (int b)

{

PHNODE p, q; // q la nut truoc , p la nut sau q=NULL; p=buket[b]; while(p !=NULL) { q=p; p=p->next;

freenode[b] = NULL;//khoi dong HASHTABLE b }

}

//Tac vu clear: xoa tat ca cac nut trong bang bam void clear( ) { int b; for b=0; b<M; b++) clearHASHTABLE(b); }

//Tac vu traverseHASHTABLE: duyet HASHTABLE b void traversebuket(int b) { PHNODE p; p=HASHTABLE[b]; while (p !=NULL) { printf(“%3d”,p->key); p=p->next; } }

//Tac vu traverse: duyet bang ham void traverse( ) { int b; for (b=0;b<M; b++) { printf(“\nHASHTABLE %d:”,b); traverseHASHTABLE(b); } } /* --- Tac vu search: tim kiem mot nut trong bang bam, neu khong tim thay ham nay tra ve tri –1, neu tim thay ham

Tra ve 0 ---*/ int search(int k) { PHNODE p; int b; b = HF(k); p = HASHTABLE[b];

while(k >p->key && p !=NULL) p = =->next;

if(p== NULL || k!=p->key) //khong tim thay return(-1);

else // tim thay }

/*---Chuong trinh chinh Chuong trinh chinh

--- */Void main( ) Void main( ) { intb,key,i,n,chucnang; char c; clrscr();

initHASHTABLE(); //khoi dong M HASHTABLE cua bang bam do

{

//Menu chinh cua chuong trinh

printf(“\n\Cac chuc nang cua chuong trinh:\n”); printf(“\1:Them mot nut vao bang bam\n”);

printf(“\2:Them ngau nhien nhieu nut vao bang bam\n”); printf(“\3: Xoa nut trong bang bam\n”);

printf(“\5: Duyet bang bam\n”);

printf(“\6: Tỡm kiem tren bang bam\n”); printf(“\0:Ket thuc chuong trinh\n”); printf(“\n Chuc nang ban chon:”); scanf(“&d”,& chuc nang);

swhich(chuc nang) { case 1:

{ printf(“\nTHEM MOT NUT VAO BANG BAM”); printf(“\ Khoa cua nut moi:”);

scanf(“%d;,&key); insert(key); break; }

case 2:

{ printf(“\nTHEM NGAU HIEN NHIEU NUT VAO BANG BAM”); printf(“\n Ban muon them bao nhieu nut:”);

scanf(“%d”,&n); for (i=0;i<n;i++) { key = random(100); insert(key); } break; } case 3: {

printf(“\nXoa TREN BANG BAM”); printf(“\n khoa cua nut can xoa:”); scanf(“%d”,&key); remove(key); break; } case 4: {

printf(“\nXoa TOAN BO BANG BAM”); printf(“\nban co chac chan khong (c/k):”); c=getch(); if(c== ‘c’ | | c == ‘c’) clear( ); break; } case 5: {

printf(“\n DUYET BANG BAM”); traverse( );

break; }

case 6: {

printf(“\nTIM KIEM TREN BANG BAM”); pintf(“\n Khao can tim:”);

scanf(“%d”,&key); b=search(key); if(b == -1)

printf(“ khong thay”); else

printf(“ Tim thay trong HASHTABLE d”,b); break;

}} }

while(chucnang !=0);

clear( ); //Xoa tat ca cac nut tren bang bam }

Một phần của tài liệu giáo trình cấu trúc dữ liệu 2 (Trang 30 - 39)