1. Trang chủ
  2. » Giáo án - Bài giảng

Cấu Trúc Dữ Liệu 2

83 405 0
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 đề Các thuật toán trên chuỗi
Tác giả Trần Hữu Quốc Thư
Trường học Đại học Sư Phạm Hà Nội
Chuyên ngành Cấu Trúc Dữ Liệu
Thể loại Chương
Năm xuất bản 2023
Thành phố Hà Nội
Định dạng
Số trang 83
Dung lượng 2,17 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í dụ một bảng băm đơn giảnGV : TRẦN HỮU QUỐC THƯ Khóa k sẽ được lưu trữ tại vị trí k mod M M... Vấn đề xung đột khi xử lý bảng băm- Trong thực tế có nhiều trường hợp có nhiều hơn 2 phần

Trang 1

Chương 1:

Các thuật toán trên chuỗi

GV : TRẦN HỮU QUỐC THƯ

Trang 2

1.3 Thuật toán nén chuỗi

+ Trong thực tế khi biểu diễn thông tin là van bản thì máy tính thường dùng bộ mã ASCII, Unicode , … đây

là các bộ mã mà độ dài dãy bít dành cho ký tự luôn là

Trang 3

1.3Thuật toán nén chuỗi

GV : TRẦN HỮU QUỐC THƯ

Ví dụ: với chuỗi: “This is a book”

Ký tự Dãy bit Ký tự Dãy bit

Trang 4

1.3 Thuật toán nén chuỗi

Trang 5

* Thuật toán xây dựng mã Huffman

GV : TRẦN HỮU QUỐC THƯ

Vdụ: Xét chuỗi sau:

“ a fast runner need never be afraid of the dark”

Thống kê tần suất xuất hiện của các ký tự trong chuỗi

9 5 1 3 7 3 1 1 1 4 1 5 1 1 1 1

Trang 6

* Thuật toán xây dựng mã Huffman

6 4

Trang 8

2.1 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ách truy xuất trực tiếp thông qua từ khóa

Trang 9

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

GV : TRẦN HỮU QUỐC THƯ

Khóa k sẽ được lưu trữ tại vị trí k mod M (M

Trang 10

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

0 1 2 3 4 5 6 7 8 9

10 31 82 93 14 95 46 27 18 79

Trang 11

Vấn đề nảy sinh

GV : TRẦN HỮU QUỐC THƯ

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

Trang 12

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

- Trong thực tế có nhiều trường hợp có nhiều

hơn 2 phần tử sẽ được “băm” vào cùng 1 vị trí

- 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

Trang 13

a Làm giảm xung đột

GV : TRẦN HỮU QUỐC THƯ

-Hàm băm cần được sao cho:

-Xác xuất phân bố khoá là đều nhau

- Dễ dàng tính toán thao tác

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

Trang 14

b Giải quyết xung đột

Trang 15

i Sử dụng danh sách liên kết (nối kết)

GV : TRẦN HỮU QUỐC THƯ

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

Trang 16

*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

- 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ữ

Trang 17

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

GV : TRẦN HỮU QUỐC THƯ

-Ý 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)

Trang 19

c Cài đặt xử lý xung đột

GV : TRẦN HỮU QUỐC THƯ

Trang 20

i Danh sách liên kết

- 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

Trang 21

H

Trang 22

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

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

Trang 23

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

GV : TRẦN HỮU QUỐC THƯ

Trang 24

Thêm một khoá vào bảng băm

//Hàm băm

int Hash(int key)

{

return (key % M)}

Trang 25

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

GV : TRẦN HỮU QUỐC THƯ

Trang 26

ii Dò tuyến tính

-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í

0 1 2 3 4 5 6 7 8 9 10

24 2 3 4 5 16 7 8 6 13

Trang 27

GV : TRẦN HỮU QUỐC THƯ

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

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

Trang 28

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

Trang 29

Thêm một khoá vào bảng băm

GV : TRẦN HỮU QUỐC THƯ

void 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ống

{

pos = Hash (pos + 1);

//Kiểm tra full

}

HashTable[pos] = key;

}

Trang 30

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 ++;

if (count > M) break;

}

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

return 0 ; //không tìm đựơc khoá

}

Trang 31

iii.Băm kép (Duble Hashing)

GV : TRẦN HỮU QUỐC THƯ

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

u = Hash2 (key)

Trang 32

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

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

Trang 33

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

GV : TRẦN HỮU QUỐC THƯ

Trang 34

2 Hàm băm

int Hash(int key)

{

return key % M}

int Hash2(int key)

{

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

}

Trang 35

Thêm một khoá vào bảng băm

GV : TRẦN HỮU QUỐC THƯ

void Insert(int k)

int pos = Hash(key)

//Kiểm tra đảm bảo vị trí pos là trống

Trang 36

Chương 3: Cây đỏ đen

Trang 37

3.1 Cây 2-3-4

GV : TRẦN HỮU QUỐC THƯ

+ cây 2-3-4 là cây nhiều nhánh mà mỗi node của

nó có thể có đến bốn node con và ba mục dữ

liệu

Trang 39

Ví dụ:

GV : TRẦN HỮU QUỐC THƯ

2 -3 -4 tree

Trang 41

Cách chèn nút

GV : TRẦN HỮU QUỐC THƯ

+ Bottom – up: Mở rộng cây về phía gốc,

tách từ dưới lên, tràn node => tách

+ Top – Down: đi từ trên xuống, gặp nút

dầy thì tách, rồi tìm vị trí thích hợp để chèn

Ví dụ: (xem demo)

Trang 42

Đánh giá

+ Cây cân bằng

+ Chi phí tìm kiếm là O(log(n))

Trang 43

2.1 Cây đỏ đen

GV : TRẦN HỮU QUỐC THƯ

Trang 44

a Khái niệm cây đỏ đen

-Là cây nhị phân tìm kiếm => cân bằng

làm cơ sở cho sự cân bằng

Trang 45

2.1 Các tính chất

GV : TRẦN HỮU QUỐC THƯ

(BLACK)

(nghĩa là không có 2 nút đỏ liên tiếp)

-Tại mọi đường đi từ nút gốc đến 1 nút lá

bất kỳ số nút đen trên các đường đi đó luôn

bằng nhau

-Mọi nút NULL đều là nút lá và mang màu

đen

Trang 46

Ví dụ:

Trang 47

Qui ước

GV : TRẦN HỮU QUỐC THƯ

-Nút gốc luôn có màu đen ( không bắt buộc)

Trang 48

b Biểu diễn cây đỏ - đen

typedef struct Node

{

}

Trang 49

c Một số thao tác đơn giản (tự viết)

GV : TRẦN HỮU QUỐC THƯ

+ Khởi tạo

+ Kiểm tra rỗng

Trang 50

d Xuất cây ra màn hình

void Print(RBTree t)

{

if (isEmpty(t)){

cout<<“Cây rỗng”;

return;

}Print(t.root, 0):

}

Trang 51

d Xuất cây ra màn hình (tt)

GV : TRẦN HỮU QUỐC THƯ

void Print(pNode p, int level)

{

if (!p) {

Trang 52

}

Trang 53

e Chèn một nút vào cây đỏ đen

GV : TRẦN HỮU QUỐC THƯ

một nút như trong cây tìm kiếm nhị phân bình

thường và gán cho nó màu đỏ.

B1 Tìm vị trí thích hợp để chèn khoá K

B2 Phát sinh 1 nút mới có khoá K, màu

đỏ (RED) và gắn liên kết tại vị trí tìm

được

B3 Hiệu chỉnh lại cây nếu có vi phạm

tính chất

Trang 54

* Phép quay phải tại y

x

y

γ

Trang 56

Hàm quay trái (tương tự cho quay phải)

void LeftRotate(RBTree t, pNode x) {

pNode y = x->pRight;

x->pRight = y->pLeft; //Bên phải x là

if (p->pLeft !=NULL)

p->pLeft ->pParent = x; //cha là x

p->pParent = x->pParent; // cha của x là cha của y

//nếu x là nút gốc

if (x->pParent == NULL)

t.root = y; //gốc mới sẽ là y

β β

Trang 57

Hàm quay trái (tt)

GV : TRẦN HỮU QUỐC THƯ

//trường hợp else => x không phải là gốc

//Nếu x là con trái của cha nó

if (x == (x->pParent)->pLeft)

x->pParent->pLeft = y else

x->pParent->pRight = y;

y->pLeft = x;

x ->pParent = y;

}

Trang 58

Ví dụ: Chèn một nút vào cây đỏ đen

Lần lượct chèn vào các nút có giá trị:

Trang 59

TH1: Cha, bác x đều có màu đỏ

GV : TRẦN HỮU QUỐC THƯ

- Cho cha và bác thành màu đen

-Ông của x thành màu đỏ

(lưu ý: nút gốc qui ước là màu đen)

Trang 60

TH2: Bác x đều có màu đen

x là con phải của cha x

Quay trái tại ông của x đồng thời đổi màu cha của x và ông của x

50

80 25

Trang 61

GV : TRẦN HỮU QUỐC THƯ

x

Trang 62

TH3: x là con trái, cha x là phải

hoặc x là con phải, cha x là trái

Quay trái (phải) tại cha (không đổi màu)

Trang 63

GV : TRẦN HỮU QUỐC THƯ

void Insert(RBTree &t, int k)

//y là “bác” của x

y = x->pParent->pParent->pRight;

}

Trang 65

//TH2 luôn xảy ra sau đó

X->pParent ->color = BLACK;

X->pParent->pParent->color = RED;

RightRotae(t,x->pParent->pParent);

}

Trang 67

f Huỷ một nút trong cây đỏ đen

GV : TRẦN HỮU QUỐC THƯ

Trang 68

Tiến trình chung

-Tìm nút là nút có khoá k trong cây

-Tiến hành huỷ z (hoặc huỷ phần tử thế mạng) và

tạo liên kết với các nhánh con của z

-Cân bằng lại cây (nếu cần thiết)

Trang 69

Quy ước

GV : TRẦN HỮU QUỐC THƯ

Do khi xoá và cân bằng cây, sẽ có nhiều trường

hợp cần phải xử lý, trong đó có việc kiểm tra nút

là nút NULL?

Giải pháp : thay tất cả các nút NULL bằng 1 nút

đặc biệt, có tên là Null Đây là nút thật sự luôn có

màu đen, các trị của nó (key, trái , phải, cha)

được gán bất kỳ

Trang 70

Quy ước

pNode Null;

Int main()

{

Null -> color = BLACK;

Null ->pParent=

Null->pLeft=Null->pRight = NULL;

Null -> Key = 0;

}

Trang 71

Phân tích

GV : TRẦN HỮU QUỐC THƯ

Khi nào cần cân bằng lại cây?

+ Khi nút bị xoá là nút có màu đen

Khi cân bằng cần để ý đến sự vi phạm t/c nào?

+ t/c chiều cao cây đen

Trang 72

Phân tích

Khi huỷ một nút đen thì chiều cao đen của

nhánh chứa nó sẽ bị sụt giảm 1 đơn vị, ta

có thể:

+ Biến nút đen cùng cấp ở cây con còn lại thành nút đỏ (nếu được)

+ Thực hiện xoay cây để tạo sự cân bằng

=> KL: Kết hợp đổi màu và xoay cây

Trang 73

GV : TRẦN HỮU QUỐC THƯ

void Delete(RBTree &t, int k)

Trang 74

Xác định nút y là nút cần thực sự xoá

If (z->pLeft ==Null !! z->pRight == Null)

y = z; //z không đủ 2 con => xoáelse

//y chỉ có thể có 1 con

y = SearchStandFor(z);

Trang 75

//cha của x là cha của y

//Nếu x là Null vẫn không báo lỗi

x->pParent = y->pParent;

Trang 77

GV : TRẦN HỮU QUỐC THƯ

//Kiểm tra cân bằng

Trang 78

Cân bằng lại cây sau khi xoá một nút đen

x: đang thiếu đenw: là anh của x

Trang 79

γ δ

η ε

Left Rotate Đổi màu

w

mới

Trang 81

TH3: w đen con trái w màu đỏ

GV : TRẦN HỮU QUỐC THƯ

C

x

E E

A

γ

η ε

Quay phải tại W

Đổi màu

w mới

Trang 82

TH3: w đen con phải w màu đỏ

A

η ε

Quay trái tại cha của x

Đổi màuw

Đỏ/đen

C

γ δ

Ngày đăng: 20/09/2013, 13:10

HÌNH ẢNH LIÊN QUAN

Bảng băm - Cấu Trúc Dữ Liệu 2
Bảng b ăm (Trang 7)

TỪ KHÓA LIÊN QUAN

w