29
1 KIU DLIU TRU TƯỢNG Bài ging Cu trúc dliu và Gii thut

Bai_2-ADT

Embed Size (px)

Citation preview

Page 1: Bai_2-ADT

1

KIỂU DỮ LIỆU TRỪU

TƯỢNG

Bài giảng Cấu trúc dữ liệu và Giải thuật

Page 2: Bai_2-ADT

Nội dung

� Kiểu Dữ liệu (Data Type)

� Kiểu Dữ liệu Trừu tượng (ADT)

� Các hướng cài đặt

� Ví dụ minh hoạ: Kiểu dữ liệu Danh sách

2

� Ví dụ minh hoạ: Kiểu dữ liệu Danh sách

� Xây dựng kiểu dữ liệu tổng quát

Page 3: Bai_2-ADT

3

Kiểu dữ liệu (Data Type)

� Kiểu dữ liệu: T = <V, O>� V (Values - miền giá trị): tập hợp các giá trị mà kiểu T

có thể nhận

� O (Operators – các thao tác): tập hợp các thao tác cơ bản được định nghĩa trên V

� Ví dụ: kiểu short int

� V = [-32,768 …+32,767 ];

� O = {+, -, *, div, mod, >, >=, <, <=, ==, !=,…}

Page 4: Bai_2-ADT

Kiểu dữ liệu

� Vô hướng: kiểu dữ liệu được xem như không có các bộ phận thành phần

� Biểu diễn một đối tượng riêng lẻ, nghĩa là chỉ có một giá trị có thể rút ra từ kiểu vô hướng.

� Thường phụ thuộc vào kiến trúc phần cứng của máy.

4

� Thường phụ thuộc vào kiến trúc phần cứng của máy.� Kiểu dữ liệu số học: số nguyên, khoảng nguyên, số thực...� Các kiểu khác: Kiểu liệt kê, Boolean, Char

� Cấu trúc: kiểu dữ liệu được xem như có các bộ phận thành phần� Phải xác định mối liên kết giữa các thành phần

� Các thao tác phải bao gồm các thao tác trên các thành phần

Page 5: Bai_2-ADT

“Mức tồn tại” của kiểu dữ liệu…

Physical (vật lý)Physical (vật lý)

� một kiểu dữ liệu tồn tại ở mức phần cứng

� được cài đặt bởi những người thiết kế phần cứng

� hầu như luôn là kiểu vô hướng

� ví dụ:

5

� ví dụ:bit, byte, word, page, address

Page 6: Bai_2-ADT

“Mức tồn tại” của kiểu dữ liệu…

Native (Tự nhiên)Native (Tự nhiên)

� một kiểu dữ liệu không thực sự tồn tại trong phần cứng nhưng được giả lập trong một ngôn ngữ lập trình

� được cài đặt bằng cách kết hợp kiểu dữ liệu vật lý hay các kiểu dữ liệu tự nhiên khác

6

hay các kiểu dữ liệu tự nhiên khác� được “đóng gói” với trình biên dịch� ví dụ:

char, int, float, string, array, struct

Page 7: Bai_2-ADT

“Mức tồn tại” của kiểu dữ liệu…

Virtual (Ảo)Virtual (Ảo)

� một kiểu dữ liệu mà lập trình viên giả lập bằng cách viết trong chương trình (vd, các lớp C++)� không được cung cấp bởi phần cứng� không được cung cấp bởi ngôn ngữ lập trình

được cài đặt bằng cách kết hợp các kiểu vật lý, tự

7

� được cài đặt bằng cách kết hợp các kiểu vật lý, tự nhiên hay các kiểu ảo khác

� ví dụ:stack, queue, tree, list, table, vector

Page 8: Bai_2-ADT

“Mức tồn tại” của kiểu dữ liệu…Abstract (Trừu tượng Abstract (Trừu tượng -- ADT)ADT)

� kiểu dữ liệu đơn thuần tồn tại theo logic trong suy nghĩ của chúng ta

� một mô hình lý thuyết hoàn chỉnh theo dạng nguyên mẫu

8

nguyên mẫu� đóng vai trò là mẫu thiết kế cho các dữ liệu ảo

� việc cài đặt không bao giờ trung thực 100% với mô hình trong suy nghĩ của chúng ta

Page 9: Bai_2-ADT

Tạo một kiểu dữ liệu

1. Trừu tượng hoá (mô hình hoá bằng suy nghĩ)

2. Đặc tả

9

2. Đặc tả

3. Biểu diễn

4. Cài đặt

Page 10: Bai_2-ADT

Tại sao trừu tượng?10

� Mô tả các thao tác của cấu trúc dữ liệu và để việc cài đặt chi tiết lại sau� Có nhiều cách cài đặt khác nhau cho một ADT

� Có nhiều ADT khác nhau� lựa chọn kiểu dữ liệu đúng cho việc cần làm là một bước � lựa chọn kiểu dữ liệu đúng cho việc cần làm là một bước

quan trọng khi thiết kế� "Get your data structures correct first, and the rest of the

program will write itself."-Davids Johnson

� Các ngôn ngữ lập trình cấp cao thường cài đặt sẵn các ADT,� C++ Standard Template Library (STL), Java standard library

Page 11: Bai_2-ADT

Câu hỏi11

� Tại sao cần học ADT?

� Tại sao cần cài đặt lại một số ADT?

� Có bao nhiêu trong chúng ta ra ngoài và cài đặt lại danh sách liên kết ADT từ đầu?danh sách liên kết ADT từ đầu?

� Hãy nhớ, mục tiêu chính của ta là học cách sử dụng và tạo các ADT� và cũng tìm hiểu về hành vi của một số ADT phổ biến

Page 12: Bai_2-ADT

12

Các ADT: Bag, Set và List

� ADT đơn giản nhất là Bag� các phần tử có thể được thêm, xoá và truy cập

� không quan tâm đến thứ tự của các phần tử

� cho phép trùng� cho phép trùng

� Set (Tập hợp)� tương tự bag, nhưng không cho phép phần tử trùng

� hội, giao, hiệu, tập con

� List (Danh sách)� các phần tử có thứ tự và cho phép trùng nhau

Page 13: Bai_2-ADT

13

Các ADT: Ngăn xếp (Stack)

� Tập hợp chỉ cho phép truy cập đến phần tử vừa chèn vào cuối cùng

� Vào sau ra trước(Last in first out - LIFO)

TopData4(Last in first out - LIFO)

� thêm dữ liệu: insert/push

� lấy dữ liệu: remove/pop

� phần tử trên cùng: top

Data3

Data2

Data1

Page 14: Bai_2-ADT

14

Các ADT: Hàng đợi (Queue)

� Tập hợp chỉ cho phép truy cập phần tử được thêm vào sớm nhất

� Vào trước ra trước (first in first out - FIFO)

� Thao tác: enqueue, dequeue� Thao tác: enqueue, dequeue

� chèn và lấy phần tử theo độ ưu tiên (Priority Queue)

Data4Data3Data2Data1

Front Back

Page 15: Bai_2-ADT

15

Các ADT: Cây (Tree)

� Binary Search Tree� các giá trị được sắp xếp

� Heap� được sắp xếp qua các giải thuật khác� được sắp xếp qua các giải thuật khác

� AVL và Red-Black Tree� cây nhị phân cân bằng

� Splay Tree

� B Tree

Page 16: Bai_2-ADT

16

Các ADT: Bảng băm (HashTables)

� Nhận một key, áp dụng một hàm

f(key) = giá trị băm

� lưu dữ liệu hay đối tượng dựa vào giá trị băm

� Sắp xếp O(N), truy cập O(1) nếu có hàm băng hoàn � Sắp xếp O(N), truy cập O(1) nếu có hàm băng hoàn hảo và đủ không gian để lưu trữ bảng

� vấn đề: xử lý đụng độ?

Page 17: Bai_2-ADT

17

Một số ADT khác

� Map� hay Dictionary

� Tập các phần tử gồm khoá và giá trị đi kèm

� tương tự bảng băm, và bảng băm thường được dùng để � tương tự bảng băm, và bảng băm thường được dùng để cài đặt Map

� Graph (Đồ thị)� Các node với số kết nối không giới hạn

� Sparse vector (vector thưa) và sparse matrix (ma trận thưa)

Page 18: Bai_2-ADT

Kiểu dữ liệu Danh sách (List ADT)18

� Một danh sách là gì?� Một chuỗi có thứ tự các thành phần A1, A2, …, AN� Các thành phần có thể tuỳ ý, nhưng phải cùng 1 loại (số

nguyên/ số thực)� Một số thao tác thông thường trên danh sách:

� Insert(ElementType E, Position P)� Delete(Position P)� Find(ElementType E)� IsEmpty() – Trả về true nếu danh sách rỗng� First() – Trả về phần tử đầu tiên� Last() – Trả về phần tử cuối cùng� Kth(Position K) – Trả về phần tử thứ K� Length() – Trả về chiều dài danh sách

Page 19: Bai_2-ADT

Danh sách: Cài đặt19

� Hai kiểu cài đặt:� Dùng mảng – hôm nay

� Danh sách liên kết – tuần tới

� Ta sẽ so sánh thời gian chạy trong trường hợp xấu nhất của các thao tác ADT với những cài đặt khác nhau

Page 20: Bai_2-ADT

Danh sách: Cài đặt dùng mảng

� Ý tưởng cơ bản:� Cấp phát trước một mảng lớn kích thước MAX_SIZE

� Theo dõi số lượng phần tử của danh sách qua biến N

� Danh sách rỗng có N = 0

20

� Danh sách rỗng có N = 0

� Dời phần tử khi phải chèn hay xoá

0 1 2 ……… N-1 MAX_SIZE

A_1 A_2 A_3 ……… A_N-1

3

A_4

Page 21: Bai_2-ADT

Thao tác danh sách: Chèn

� Insert(ElementType E, Position P)� Example: Insert(X, 2): Chèn X vào vị trí 2

� Ý tưởng cơ bản: Dời các thành phần hiện tại sang phải 1 ô và chèn phần tử mới

21

phải 1 ô và chèn phần tử mới

� Đây là danh sách cuối cùng. Thời gian chạy: O(N)

0 1 2 ……… N-1 MAX_SIZE

A_1 A_2 A_3 ……… A_N

3

A_4

0 1 2 ……… N-1 MAX_SIZE

A_1 A_2 X ……… A_N-1

N

A_N

3

A_3

Page 22: Bai_2-ADT

Chèn danh sách – Mảng đầy

� Nếu mảng đã đầy thì phải làm gì?� Có thể báo lỗi

� Không hay lắm

Thông thường, ta nên làm như sau:

22

� Thông thường, ta nên làm như sau:(1) Cấp phát một mảng lớn hơn (thường là gấp đôi sức chứa)(2) Chép tất cả phần tử từ mảng cũ sang mảng mới(3) Giải phóng vùng nhớ dùng bởi mảng cũ(4) Sử dụng mảng mới

� Với cách cài đặt mảng động, ta cũng cần theo dõi thông tin về sức chứa của mảng

Page 23: Bai_2-ADT

Thao tác danh sách: Xoá

� Delete(Position P)� Ví dụ: Delete(1): Xoá phần tử ở vị trí 1

� Ý tưởng cơ bản: Xoá phần tử và dời các phần tử hiện có sang phải 1 ô

23

hiện có sang phải 1 ô

� Đây là danh sách cuối cùng. Thời gian chạy: O(N)

0 1 2 ……… N-1 MAX_SIZE

A_1 A_2 A_3 ……… A_N

3

A_4

0 1 2 ……… N-2 MAX_SIZE

A_1 A_3 A_4 ……… A_N

N-13

A_5

Page 24: Bai_2-ADT

Thao tác danh sách: Tìm kiếm

� Find(ElementType E)� Ví dụ: Find(X): Tìm X trong danh sách

0 1 2 ……… N-1 MAX_SIZE3

24

� Phải thực hiện tìm kiếm tuyến tính� Thời gian chạy: O(N)

0 1 2 ……… N-1 MAX_SIZE

A_1 A_2 A_3 ……… A_N

3

A_4

Page 25: Bai_2-ADT

Thao tác danh sách: isEmpty

� IsEmpty()� Trả về true nếu danh sách rỗng

0 1 2 ……… N-1 MAX_SIZE

A_1 A_2 A_3 ……… A_N

3

A_4

25

� Bình thường – Trả về true nếu N == 0� Thời gian chạy: O(1)

A_1 A_2 A_3 ……… A_NA_4

Page 26: Bai_2-ADT

Thao tác danh sách: First, Last, Kth

� First(): Trả vềA[0]� Last(): Trả về A[N-1]� Kth(Position K): Trả về A[K]

0 1 2 ……… N-1 MAX_SIZE3

26

� First – Thời gian chạy: O(1)� Last – Thời gian chạy: O(1)� Kth – Thời gian chạy: O(1)

0 1 2 ……… N-1 MAX_SIZE

A_1 A_2 A_3 ……… A_N

3

A_4

Page 27: Bai_2-ADT

Ứng dụng của danh sách27

� Kiểu Đa thức ADT: lưu trữ và xử lý đa thức một biến với số mũ không âm� 10X^3 + 4X^2 + 7 = 10X^3 + 4X^2 + 0X^1 + 7X^0� Cấu trúc dữ liệu: lưu trữ các hệ số Ci và số mũ i

� Cài đặt bằng mảng: C[i] = Ci� VD. C[3] = 10, C[2] = 4, C[1] = 0, C[0] = 7

� Thao tác ADT: Đa thức input trong hai mảng A và B, kết quả lưu trong C� Cộng: C[i] = ?� Nhân: C[i] = ?

Page 28: Bai_2-ADT

Ứng dụng của danh sách: Đa thức28

� Add(Poly A, Poly B, Poly C):� C[i] = A[i] + B[i] với 0<=i<=N

� Multiply(Poly A, Poly B, Poly C):� Multiply(Poly A, Poly B, Poly C):� GánC[i] = 0 với 0<=i<=N

� Với mọi (i, j)� C[i+j] = C[i+j] + A[i]*B[j]

� Divide(Poly A, Poly B, Poly C):� Tự thực hiện…

Page 29: Bai_2-ADT

Ứng dụng của danh sách: Đa thức

� Vấn đề khi cài đặt bằng mảng: Đa thức thưa� VD. 10X^3000+ 4X^2+ 7

� Lãng phí không gian và thời gian (hầu hết Ci đều là 0)

29

� Giải pháp?� Dùng danh sách liên kết đơn, sắp xếp theo số mũ giảm

dần

(10, 3000) (4, 2) (7, 0)head