NGƯỜI SO N: ẠPHAN ĐẦUThêm một phân tử x vào tập hợp Procedure Insertionx:elementtype; Var A:Set; End;... NGƯỜI SO N: ẠPHAN ĐẦUPhép toán tìm phần tử nhỏ nhất của tập hợp Function MinA:set
Trang 1NGƯỜI SO N: Ạ
PHAN ĐẦU
CHƯƠNG III: TẬP HỢP
Trang 2NGƯỜI SO N: ẠPHAN ĐẦU
1 TẬP HỢP & MÔ HÌNH DỮ LIỆU TẬP HỢP
Trang 3NGƯỜI SO N: ẠPHAN ĐẦU
MÔ HÌNH DỮ LIỆU TẬP HỢP
Các phép toán trên mô hình dữ liệu tập hợp
Trang 4NGƯỜI SO N: ẠPHAN ĐẦU
Mô hình dữ liệu tập hợp
Các phép toán trên mô hình dữ liệu tập hợp
4 Xác định một phần tử có thuộc tập hợp hay không
Function Member(x:element; A : set) : boolean;
5 Phép xen vào
Procedure Insert(x:element; var A : set);
6 Phép loại bỏ
Procedure Delete(x : element; var A : set);
7 Tìm phần tử nhỏ nhất (phần tử lớn nhất)
Procedure Min (A : set; var x: element);
Trang 5NGƯỜI SO N: ẠPHAN ĐẦU
3 CÀI ĐẶT TẬP HỢP
Bằng vecto bit
Bằng danh sách (mảng, con trỏ)
Bằng danh sách được sắp thứ tự
Trang 6NGƯỜI SO N: ẠPHAN ĐẦU
Cài đặt tập hợp bởi vectơ bit
Const n= 100;
Type set = array[1 n] of boolean;
x: 1 n;
Trang 7NGƯỜI SO N: ẠPHAN ĐẦU
Khởi tạo tập hợp
Procedure Initialize ( var A: Set);
Trang 8NGƯỜI SO N: ẠPHAN ĐẦU
Phép lấy hợp của hai tập Avà B.
Procedure Union(A, B:set; var C : set);
Var i:integer;
Begin
For i:=1 to n do C [i]:=A[i] or B[i];
End;
Trang 9NGƯỜI SO N: ẠPHAN ĐẦU
Procedure Intersection(A, B : set; var C : set);
Procedure Intersection(A, B:set; var C : set);
Var i:integer;
Begin
For i:=1 to n do C [i]:=A[i] and B[i];
End;
Trang 10NGƯỜI SO N: ẠPHAN ĐẦU
Phép toán tìm hiệu của tập hợp A và B
Procedure Diference(A, B:set; var C : set);
Var i:integer;
Begin
For i:=1 to n do C [i]:=(A[i] and not B[i]); End;
Trang 11NGƯỜI SO N: ẠPHAN ĐẦU
Function Member(x:element; A : set) : boolean;
Function Member(x:element; A : set) : boolean;
Begin
Menber:=a[x];
End;
Trang 12NGƯỜI SO N: ẠPHAN ĐẦU
Procedure Insert(x:element; var A : set);
Procedure Insert(x:element; var A : set);
Begin
A[x]:=true;
End;
Trang 13NGƯỜI SO N: ẠPHAN ĐẦU
7 Tìm phần tử nhỏ nhất
Function Min (A : set; x: element):element;
Var i:integer; ok:boolean;
Begin
i:=1;
ok:=true;
While (i<=n) and not ok do
If a[i]=true then ok:=true Else i:=i+1;
if i<=n then Min:=i else Min:=0;
End;
Trang 14NGƯỜI SO N: ẠPHAN ĐẦU
Cài đặt tập hợp bởi danh sách
1 Cài đặt tập hợp bởi mảng:
Trang 15NGƯỜI SO N: ẠPHAN ĐẦU
Khởi tạo tập hợp rỗng
Procedure Initialize(Var A:Set);
Begin
a.last := 0;
End;
Trang 16NGƯỜI SO N: ẠPHAN ĐẦU
Kiểm tra một phần tử x có trong tập hợp không?
Function Member(x:elementtype; A : set) : boolean;
Var i:integer; ok:boolean;
Begin
i:=1; ok:=false;
while (i<=a.last) and not ok do
if a.element[i]=x then ok:=true Else i:=i+1;
Member:=ok;
End;
Trang 17NGƯỜI SO N: ẠPHAN ĐẦU
Thêm một phân tử x vào tập hợp
Procedure Insertion(x:elementtype; Var A:Set);
End;
Trang 18NGƯỜI SO N: ẠPHAN ĐẦU
Phép lấy hợp của hai tập Avà B.
Procedure Union(A, B:set; var C : set);
Trang 19NGƯỜI SO N: ẠPHAN ĐẦU
Phép toán tìm giao của hai tập hợp
Procedure Intersection(A, B:set; var C : set);
Trang 20NGƯỜI SO N: ẠPHAN ĐẦU
Phép toán tìm hiệu của tập hợp A và B
Procedure Diference(A, B:set; var C : set);
Var i:integer;
Begin
Initialize(C);
For i:=1 to a.last do
If not member(a.element[i], B) then
Insertion(a.element[i], C);
End;
Trang 21NGƯỜI SO N: ẠPHAN ĐẦU
Phép toán tìm phần tử nhỏ nhất của tập hợp
Function Min(A:set):elementtype;
Var i:integer;
Begin
Min:=0;
For i:=1 to a.last do
If min >a.element[i] then Min:=a.element[i];End;
Trang 22NGƯỜI SO N: ẠPHAN ĐẦU
2 Cài đặt tập hợp bởi danh sách liên kết.
element : elementtype;
Next : pointer;
End;
Trang 23NGƯỜI SO N: ẠPHAN ĐẦU
Khởi tạo tập hợp rỗng
Procedure Initialize(var S: pointer);
Begin
S := nil;
End;
Trang 24NGƯỜI SO N: ẠPHAN ĐẦU
Kiểm tra một phần tử x có trong tập hợp không?
Function Member(x:elementtype; S: Pointer) : boolean;
Var p: pointer; ok:boolean;
Begin
p: = s; ok:=false;
while (p<> nil) and not ok do
if p^.element=x then ok:=true Else p:= p^.next;
Member:=ok;
End;
Trang 25NGƯỜI SO N: ẠPHAN ĐẦU
Thêm một phân tử x vào tập hợp
Procedure Insertion(x:elementtype; Var S: pointer);Var p: pointer;
End;
Trang 26NGƯỜI SO N: ẠPHAN ĐẦU
Phép lấy hợp của hai tập Avà B
Procedure Union(A, B: Pointer; var C : Pointer);Var p, q: pointer;
Trang 27NGƯỜI SO N: ẠPHAN ĐẦU
Phép toán tìm giao của hai tập hợp
Procedure Intersection(A, B: Pointer; var C : Pointer);Var p: pointer;
Trang 28NGƯỜI SO N: ẠPHAN ĐẦU
Phép toán tìm hiệu của tập hợp A và B
Procedure Diference(A, B: Pointer; var C : Pointer);Var p, q: pointer;
Trang 29NGƯỜI SO N: ẠPHAN ĐẦU
4 TỪ ĐIỂN
Từ điển:
Mô hình dữ liệu tập hợp, nhưng chỉ xét đến những phép toán Insert, Delete và Member được gọi là kiểu dữ liệu trừu tượng từ điển (Dictionary)
Trang 30NGƯỜI SO N: ẠPHAN ĐẦU
Các phương pháp đơn giản để cài đặt từ điển
Từ điển là một tập hợp, do đó đương nhiên ta có thể sử dụng các phương pháp cài đặt tập hợp để cài đặt từ điển
Trang 31NGƯỜI SO N: ẠPHAN ĐẦU
Cài đặt từ điển bởi vectơ bit.
Các phép toán được cài đặt đơn giản với thời gian hằng
Tuy nhiên, ta chỉ có thể áp dụng được nếu từ điển là một tập hợp có thể dùng làm tập chỉ số cho mảng
Trang 32NGƯỜI SO N: ẠPHAN ĐẦU
Cài đặt từ điển bằng danh sách
Cài đặt các phép toán tương đối đơn giản
Thời gian thực hiện các phép toán Insert, Delete, Member nói chung là O(n) với từ điển có n phần tử
Trang 33NGƯỜI SO N: ẠPHAN ĐẦU
5 CẤU TRÚC DỮ LIỆU BẢNG BĂM
CÀI ĐẶT TỬ ĐIỂN BẰNG BẢNG BĂM
Có hai phương pháp băm: băm đóng và băm mở
Băm mở (open hashing) cho phép sử dụng một không gian không hạn chế để lưu giữ các phần tử của tập hợp
Băm đóng (closed hashing) sử dụng một không gian cố định và do đó tập hợp được cài đặt phải có cỡ không vượt quá không gian cho phép
Băm là phương pháp rất thích hợp để cài đặt tập hợp có số phần tử lớn
Trang 34NGƯỜI SO N: ẠPHAN ĐẦU
5.1 BẢNG BĂM MỞ
Trang 35NGƯỜI SO N: ẠPHAN ĐẦU
Hàm băm (hash function) h
Hàm băm sẽ phân chia các phần tử vào các lớp
Nếu x là giá trị khoá của phần tử nào đó của tập hợp thì h(x) là một chỉ số của mảng T và ta gọi h(x) là giá trị băm (hash value) của x
Như vậy h là ánh xạ của tập hợp các khoá K vào tập hợp {0, 1, , …N-1}
Trang 36NGƯỜI SO N: ẠPHAN ĐẦU
Tiêu chuẩn để đánh giá một hàm băm
Một, cho phép tính được dễ dàng và nhanh chóng giá trị băm của mỗi khoá
Hai, phải phân bố đều các khoá vào các rổ
Trang 37NGƯỜI SO N: ẠPHAN ĐẦU
1 Phương pháp cắt bỏ
Giả sử khoá là số nguyên, ta sẽ bỏ đi một phần nào đó của khoá và lấy phần còn lại làm giá trị băm của khoá
Ví dụ: Nếu khoá 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 chữ số thứ nhất, thứ ba và thứ bảy từ bên trái làm giá trị băm Chẳng hạnï: h(7103592810)=702
Trang 38NGƯỜI SO N: ẠPHAN ĐẦU
1 Phương pháp cắt bỏ
Phương pháp cắt bỏ rất đơn giản, nhưng nó thường không phân bố đều các khoá
Trang 39NGƯỜI SO N: ẠPHAN ĐẦU
2 Phương pháp gấp
Giả sử khoá là số nguyên Ta phân chia khoá thành một số phần, sau đó kết hợp các phần lại bằng một cách nào đó (chẳng hạn, dùng phép cộng hoặc phép nhân) để nhận giá trị băm
Trang 40NGƯỜI SO N: ẠPHAN ĐẦU
Ví dụ:
Nếu khoá là số nguyên 10 chữ số ta phân thành các nhóm
ba , ba, hai và hai chữ số từ bên trái
Cộng các nhóm với nhau, sau đó cắt cụt nếu cần thiết, ta sẽ nhận được giá trị của hàm băm
Chẳng hạn: 7103592810 được biến đổi thành 710+359+28+10 =1107, do đó ta có giá trị băm là 107
Trang 41NGƯỜI SO N: ẠPHAN ĐẦU
2 Phương pháp gấp
Vì mọi thông tin trong khoá đều được phản ánh vào giá trị băm, nên phương pháp gấp cho phân bố đều các khoá tốt hơn phương pháp cắt bỏ
Trang 42NGƯỜI SO N: ẠPHAN ĐẦU
3 Phưiơng pháp sử dụng phép toán lấy phần dư
Giả sử khoá là số nguyên, và giả sử ta muốn chia tập hợp các khoá thành N lớp Chia số nguyên cho N (tốt nhất chọn
n là số nguyên tố) rồi lấy phần dư làm giá trị băm
Trang 43NGƯỜI SO N: ẠPHAN ĐẦU
Cài đặt hàm băm với khóa là một chuỗi có 10 ký tự
Type keytype = string[10];
Trang 44NGƯỜI SO N: ẠPHAN ĐẦU
Cấu trúc dữ liệu bảng băm mở
Trang 45NGƯỜI SO N: ẠPHAN ĐẦU
Khai báo bảng băm mở biểu diễn từ điển
Trang 46NGƯỜI SO N: ẠPHAN ĐẦU
Khởi tạo một từ điển rỗng
Procedure Initialize(var T: Dictionary);
Begin
For i:=0 to N -1 do T[i]= nil;
End;
Trang 47NGƯỜI SO N: ẠPHAN ĐẦU
Kiểm tra một phần tử có thuộc từ điển hay không?
Function Member(x : keytype; Var T : Dictionary): boolean;
Var p : pointer; found :boolean;
Begin
P:=T[h(x)];
Found:=false;
While (P<> nil) and (not found ) do
If P^.key =x then found :=trueElse P:=P^.next;
Member :=found;
End;
Trang 48NGƯỜI SO N: ẠPHAN ĐẦU
Thêm một phần tử vào từ điển
Procedure Insert (x : keytype; Var T : Dictionary);
Trang 49NGƯỜI SO N: ẠPHAN ĐẦU
Xóa một phần tử khỏi từ điển
Procedure Delete(x : keytype; var T : Dictionary);Var i : 0 N-1; P, Q : pointer; Found :boolean;Begin
i:=h(x);
If T[i]<> nil then
If T[i]^.key = x then {loai x khoi danh sach}
Trang 50NGƯỜI SO N: ẠPHAN ĐẦU
Xóa một phần tử khỏi từ điển
While (P<> nil) and (not found) do
Trang 51NGƯỜI SO N: ẠPHAN ĐẦU
5.2 BẢNG BĂM ĐÓNG
Mỗi phần tử của tập hợp đựơc lưu giữ trong chính các thành phần T[i] của mảng
Khai báo kiểu dữ liệu từ điển được cài đặt bởi bảng băm đóng:
Type Dictionary = array[0 N-1] of keytype;
Hàm băm là một ánh xạ
H : K → {0,1, …., N-1}
Trang 52NGƯỜI SO N: ẠPHAN ĐẦU
BẢNG BĂM ĐÓNG
Hàm băm là ánh xạ từ tập hợp các khoá K vào tập hợp các chỉ số 0,1 ,…, N-1 của mảng
Đây là một ánh xạ nhiều – vào - một nên có thể xảy ra một số khoá khác nhau được ánh xạ vào cùng một chỉ số
Tình huống này được gọi là sự va chạm (collision). Để giải quyết vấn đề bằng cách băm lại (rehasing)
Trang 53NGƯỜI SO N: ẠPHAN ĐẦU
Băm lại tuyến tính
Đây là phương pháp đơn giản nhất Các hàm hi(x) được xác định: hi(x) =(h(x) +i) mod N
Tức là ta xem mảng là mảng vòng tròn và lần lượt xem xét các vị trí h(x)+1, h(x) +2, …
Chẳng hạn, N=10 và các khoá a, b, c, d, e có các giá trị băm như sau: h(a)=7, h(b)=1, h(c)=4, h(d)=3, h(e)=3
0 1 2 3 4 5 6 7 8 9
Trang 54NGƯỜI SO N: ẠPHAN ĐẦU
Băm lại bình phương
Phương pháp này tốt hơn, tránh được sự tích tụ trong bảng các giá trị xung quanh các giá trị đưa vào bảng ban đầu, hàm băm lại được là:
Trang 55NGƯỜI SO N: ẠPHAN ĐẦU
Khai báo cấu trúc dữ liệu bảng băm đóng biểu diễn
Trang 56NGƯỜI SO N: ẠPHAN ĐẦU
Thủ tục location
Xuất phát từ h(x) dò tìm lần lượt qua các h1(x), h2(x)… cho đến khi tìm được vị trí chứa x hoặc vị trí trống đầu tiên
k là vị trí mà tại đó quá trình tìm kiếm dừng lại
j là vị trí bị xóa hay trống đầu tiên
Trang 57NGƯỜI SO N: ẠPHAN ĐẦU
Procedure Location (x: keytype; var k, j : integer);
if (T[k]= deleted) and(T[j]<> deleted) then j:=k; k:=(k+1) mod N;
End;
if (T[k] = empty) and (T[j]<> deleted) then j:=k;
End;
End;
Trang 58NGƯỜI SO N: ẠPHAN ĐẦU
Xác định xem một phần tử có trong từ điển
End;
Trang 59NGƯỜI SO N: ẠPHAN ĐẦU
Thêm một phần tử vào từ điển
Procedure Insert(x : keytype; var T : Dictionary);
Trang 60NGƯỜI SO N: ẠPHAN ĐẦU
Xóa một phần tử khỏi từ điển
Procedure Delete (x : keytype; var T : Dictionary);Var k, j : integer;
Begin
Location (x, k, j);
If T [k]=x then T[k]=deleted;
End;
Trang 61NGƯỜI SO N: ẠPHAN ĐẦU
6 HÀNG ƯU TIÊN
Hàng ưu tiên là tập hợp cùng với hai phép toán Insert
và DeleteMin
Phép toán Insert có ý nghĩ thông thường xen phần tử mới vào tập hợp
Phép toán DeleteMin trên tập hợp A là tìm trên tập hợp
A phần tử a có Pri nhỏ nhất và loại nó khỏi tập A
Trang 62NGƯỜI SO N: ẠPHAN ĐẦU
Cài đặt hàng ưu tiên
Ta có thể biểu diễn hàng ưu tiên bởi danh sách được sắp tăng dần theo giá trị ưu tiên của các phần tử hoặc không được sắp
Nếu cài đặt hàng ưu tiên bởi danh sách được sắp xếp thì phép toán DeleteMin chỉ là xóa phần tử đầu tiên trong danh sách => thời gian là O(1) Nhưng phép toán Insert đòi hỏi phải có thời gian 0(n)
Nếu ta cài đặt hàng ưu tiên bởi danh sách không được sắp xếp, thì khi xen phần tử mới vào hàng, ta chỉ cần đưa nó vào đầu danh sách Nhưng việc thực hiện phép toán DeleteMin lại chậm
Trang 63NGƯỜI SO N: ẠPHAN ĐẦU
7 CÂY THỨ TỰ BỘ PHẬN VÀ CÀI ĐẶT HÀNG ƯU
TIÊN BỞI CÂY THỨ TỰ BỘ PHẬN
Cây thứ tự bộ phận là một cây nhị phân thỏa các điều kiện sau:
1 Tất cả các mức của cây đều đầy, trừ mức thấp nhất có thể thiếu
2 Ở mức thấp nhất, tất cả các lá đều xuất hiện liên tiếp từ bên trái
3 Giá trị của mỗi đỉnh không lớn hơn giá trị của các đỉnh con của nó
Trang 64NGƯỜI SO N: ẠPHAN ĐẦU
Ví duï:2
9 7
10
Trang 65NGƯỜI SO N: ẠPHAN ĐẦU
Phép toán Insert
Thêm một lá mới liền kề với các lá ở mức thấp nhất, nếu mức thấp nhất chưa đầy; ngược lại, thì ta thêm vào một lá ở mức mới sao cho các điều kiện của 1 và 2
Nếu sau khi thêm vào lá mới cây không còn là cây thứ tự bộ phận, thì ta theo đường từ lá mới tới gốc cây Nếu một đỉnh có giá trị ưu tiên nhỏ hơn đỉnh cha của nó, thì ta trao đổi đỉnh đó
với cha của nó
Trang 66NGƯỜI SO N: ẠPHAN ĐẦU
Ví duï:2
9 7
10
Trang 67NGƯỜI SO N: ẠPHAN ĐẦU
Ví duï:2
9 7
10
3
Trang 68NGƯỜI SO N: ẠPHAN ĐẦU
Ví duï:2
5 7
10
9
Trang 69NGƯỜI SO N: ẠPHAN ĐẦU
Ví duï:2
3 7
10
9
Trang 70NGƯỜI SO N: ẠPHAN ĐẦU
Phép toán DeleteMin
Thay giá trị của gốc bởi giá trị nút lá ngoài cùng bên phải ở mức thấp nhất
Loại bỏ lá này khỏi cây
Đi từ gốc xuống Giả sử tại một bước nào đó ta đang ở đỉnh
a và hai con của nó là b và c Thì hoán vị pri(a) và pri(d), đi xuống đỉnh d (với pri(d)=min (pri(a), pri(b))…
Quá trình cho đến khi gặp nút lá hay đỉnh được xét thỏa điều kiện 3
Trang 71NGƯỜI SO N: ẠPHAN ĐẦU
Ví duï:2
9 7
10
Trang 72NGƯỜI SO N: ẠPHAN ĐẦU
Ví duï:10
9 7
10 11
Trang 73NGƯỜI SO N: ẠPHAN ĐẦU
Ví duï:5
9 7
10 11
Trang 74NGƯỜI SO N: ẠPHAN ĐẦU
Ví duï:5
9 10
10 11
Trang 75NGƯỜI SO N: ẠPHAN ĐẦU
Cài đặt cây thứ tự bộ phận bởi mảng
Giả sử ta đánh số các đỉnh của cây thứ tự bộ phận từ trên xuống dưới và từ trái qua phải (trong cùng một mức ), bắt đầu từ gốc có số hiệu là 1 1
5 4
9 8
11 10
Trang 76NGƯỜI SO N: ẠPHAN ĐẦU
Const N = ;
Type PriQueue =Record
Element : array [1 N] of item; Last : integer;
End;
Var H : PriQueue;
Trang 77NGƯỜI SO N: ẠPHAN ĐẦU
Việc khởi tạo một hàng rỗng được thực hiện bởi lệnh:
H.last:= 0 ;
Trang 78NGƯỜI SO N: ẠPHAN ĐẦU
Xem tài liệu
Procedure Insert(x:item; Var H : PriQueue );
Procedure DeleteMin(Var H : PriQueue; Var x: item);