You are on page 1of 52

TRƯỜNG ĐẠI HỌC TÀI CHÍNH – MARKETING

KHOA CÔNG NGHỆ THÔNG TIN

Cấu trúc dữ liệu & giải thuật


Tập Slide bài giảng
GV: ThS Nguyễn Quốc Thanh – ThS Nguyễn Huy Khang

Tháng 01 năm 2020


BG CTDL&GT - Trang 1

Bài 1
***
TỔNG QUAN

Giới thiệu

 Vai trò của cấu trúc dữ liệu và giải thuật


 Tổ chức dữ liệu  Cấu trúc dữ liệu
 Xử lý dữ liệu  Giải thuật
 Cấu trúc dữ liệu + Giải thuật = Chương trình

Giới thiệu

 Vai trò của cấu trúc dữ liệu và giải thuật

SBD Môn 1 Môn 2 Môn 3


1 8 7 9
2 9.5 8 8.5
3 5 8 9.5
… … … …

1
BG CTDL&GT - Trang 2

Giới thiệu

 Vai trò của cấu trúc dữ liệu và giải thuật


8 7 9 9.5 8 8.5 5 8 9.5 …

1 2 3

float xuat_diem(float a[ ], int sbd, int mon)


{ int vitri;
vitri = 3*(sbd – 1) + mon;
return a[vitri];
}
4

Giới thiệu

 Vai trò của cấu trúc dữ liệu và giải thuật


ab 1 2 3
1 8 7 9
2 9.5 8 8.5
3 5 8 9.5
… … … …

float xuat_diem(float ab[ ][ ], int sbd, int mon)


{ return ab[sbd][mon];
}
5

Tiêu chuẩn đánh giá cấu trúc dữ liệu

 Phản ánh đúng thực tế

 Dễ dàng cho thao tác

 Tiết kiệm tài nguyên hệ thống

2
BG CTDL&GT - Trang 3

Kiểu dữ liệu

 Kiểu dữ liệu cơ bản

 Kiểu số nguyên

 Kiểu số thực

 Kiểu ký tự

 Kiểu luận lý

Kiểu dữ liệu

 Kiểu dữ liệu cấu trúc


 Kiểu chuỗi

 Kiểu mảng

 Kiểu cấu trúc

Kiểu dữ liệu

 Trừu tượng hóa

 Kiểu dữ liệu trừu tượng là một mô hình toán


học cùng với tập hợp các phép toán được
định nghĩa trên mô hình đó.

 Ví dụ: tập hợp A và các phép toán hợp, giao


hiệu là một kiểu dữ liệu trừu tượng

3
BG CTDL&GT - Trang 4

Độ phức tạp của giải thuật

 Đánh giá độ phức tạp


 Phương pháp thực nghiệm

 Phương pháp xấp xỉ tiệm cận

10

Độ phức tạp của giải thuật

 Cách tính độ phức tạp


 Thời gian thực hiện chương trình T(n)
 Lệnh cơ bản

 Cấu trúc lựa chọn

 Cấu trúc lặp

11

Độ phức tạp của giải thuật

 Cách tính độ phức tạp


 Thời gian thực hiện chương trình T(n)
VD: tính thời gian thực hiện hàm hoán vị
void hoan_vi(int &a, int &b)
{ int t;
t = a;
a = b;
b = t;
}
12

4
BG CTDL&GT - Trang 5

Độ phức tạp của giải thuật

 Cách tính độ phức tạp


 Thời gian thực hiện chương trình T(n)
VD: Tính thời gian của hàm tính n!
int giai_thua(int n)
{ int kq = 1;
for (int i = 1; i <= n; i++)
kq = kq * i;
return kq;
}
13

Độ phức tạp của giải thuật

 Cách tính
 Tỷ suất tăng f(n) = ni
 c, n0 sao cho T(n)  c * f(n) n  n0

Cho T(n) = 4, f(n) = ?


Cho T(n) = 4n, f(n) = ?
Cho T(n) = (n+1)2, f(n) = ?
Cho T(n) = n3 + n2 + 4n + 5, f(n) = ?

14

Độ phức tạp của giải thuật

 Cách tính
 Tỷ suất tăng f(n)
 c, n0 sao cho T(n)  c * f(n) n  n0

Cho hai giải thuật P1 & P2 với thời gian


tương ứng là T1 = 100n2 và T2 = 5n3. Hỏi bài
toán chạy giải thuật nào thì nhanh hơn?

15

5
BG CTDL&GT - Trang 6

Độ phức tạp của giải thuật

 Cách tính
 Độ phức tạp
O(f(n))

 Quy tắc cộng

 Quy tắc nhân

16

Độ phức tạp của giải thuật

 Cách tính
 Độ phức tạp
Tính độ phức tạp của chương trình tính Cnk?

17

Độ phức tạp của giải thuật

 Cách tính
 Độ phức tạp
Tính độ phức tạp của chương trình tìm giá trị
lớn nhất của n số?

18

6
BG CTDL&GT - Trang 7

Độ phức tạp của giải thuật

 Các bước phân tích thuật toán


 Xác định đặc trưng của dữ liệu nhập
 Nhận ra các thao tác trừu tượng của thuật
toán
 Phân tích toán học để tìm ra giá trị trung bình
và giá trị xấu nhất

19

Độ phức tạp của giải thuật

 Phân lớp thuật toán


 Hằng số
 Hàm logarit: logN
 Tuyến tính: N
 NlogN

 Lũy thừa: N2, N3


 Mũ: 2N

20

Bài tập

Cho đa thức
f(x) = a0 + a1x1 + a2x2 + … + anxn
 Chọn cấu trúc dữ liệu có thể lưu trữ đa thức
trên.
 Viếtchương trình con cho phép nhập đa thức.
Tính độ phức tạp.
 Viếtchương trình con cho phép xuất đa thức.
Tính độ phức tạp.

21

7
BG CTDL&GT - Trang 8

Bài 2
***
KỸ THUẬT TÌM KIẾM

Giới thiệu
 Nhu cầu tìm kiếm
 Nhu cầu lớn
 Kết quả tìm kiếm
 Tốc độ tìm kiếm

 Bài toán tìm kiếm


 Phần tử dữ liệu
 Tìm kiếm nội
 Tìm kiếm ngoại
2

Tìm kiếm tuyến tính

 Bài toán
Cho mảng arr có n phần tử lần lượt là arr[0],
arr[1], …, arr[n-1]. Có phần tử nào mang giá trị x
hay không? Nếu có thì đó là phần tử thứ mấy?
 Ý tưởng
Lần lượt so sánh giá trị x với các phần tử trong
mảng arr bắt đầu từ phần tử đầu tiên.
Bài toán kết thúc khi tìm được phần tử có giá trị
bằng x hoặc khi hết mảng.

1
BG CTDL&GT - Trang 9

Tìm kiếm tuyến tính

 Giải thuật

B1: i = 0

B2: Kiểm tra arr[i] = x?


Nếu đúng thì KQ là tìm thấy tại i, kết thúc
Nếu sai thì chuyển qua B3

B3: i = i + 1, kiểm tra i < n?


Nếu đúng thì lặp lại bước 2
Nếu sai thì kết thúc và không tìm thấy
4

Tìm kiếm tuyến tính

 Chương trình
int LinearSearch(int arr[ ], int n, int x)
{ int i = 0;
while (arr[i] != x && i < n)
i++;
if (i < n)
return i;
return (-1);
}

Tìm kiếm tuyến tính

 Đánh giá
 Số phép so sánh
 Số phép gán
 Độ phức tạp

2
BG CTDL&GT - Trang 10

Tìm kiếm tuyến tính


 Cải tiến giải thuật
int LinearSearch1(int arr[ ], int n, int x)
{ int i = 0;
while (arr[i] != x && arr[n-i] != x && i < n/2)
i++;
if (arr[i] == x)
return i;
if (arr[n-i] == x)
return (n-i);
return (-1);
} 7

Tìm kiếm tuyến tính


 Cải tiến giải thuật
 Phần tử lính canh
int LinearSearch2(int arr[ ], int n, int x)
{ int i = 0;
arr[n] = x;
while (arr[i] != x)
i++;
if (i < n)
return (i);
return (-1);
} 8

Tìm kiếm tuyến tính


 Cải tiến giải thuật
int LinearSearch3(int arr[ ], int n, int x)
{ int i = 0; temp = arr[n/2]; arr[n/2] = x;
while (arr[i] != x && arr[n-i] != x)
i++;
arr[n/2] = temp;
if (arr[i] = x)
return i;
if (arr[n-i] = x)
return (n-i);
return (-1);
} 9

3
BG CTDL&GT - Trang 11

Tìm kiếm nhị phân

 Bài toán
Cho mảng arr gồm n phần tử có thứ tự tăng,
nghĩa là arr[0]  arr[1]  …  arr[n-1]. Có phần
tử nào mang giá trị x hay không? Nếu có thì đó
là phần tử thứ mấy?
 Ý tưởng
So sánh giá trị x với phần tử giữa dãy gọi là
arr[mid]. Nếu x = arr[mid] thì tìm thấy, nếu x <
arr[mid] thì nếu có x chỉ có thể ở nửa dãy trái,
nếu x > arr[mid] thì x chỉ có thể ở nửa dãy phải.
10

Tìm kiếm nhị phân


 Giải thuật
B1: Cho first = 0, last = n-1
B2: kiểm tra first > last?
Nếu đúng thì kết thúc
Nếu sai thì mid = (first+last)/2
B3: kiểm tra x = arr[mid]?
Nếu đúng thì kết thúc
B4: kiểm tra x < arr[mid]?
Nếu đúng thì cho last = mid-1 rồi lặp lại B2
Nếu sai thì cho first = mid+1 rồi lặp lại B2 11

Tìm kiếm nhị phân

 Chương trình
int BinarySearch(int arr[], int n, int x)
{ int left = 0; int right = n-1;
int mid = (left+right)/2;
while(left <= right && arr[mid] != x)
{ if(x < arr[mid]) right = mid – 1;
else left = mid + 1;
mid = (left+right)/2;
}
if(left > right) return (-1);
return(mid);
}
12

4
BG CTDL&GT - Trang 12

Tìm kiếm nhị phân

 Đánh giá
 Thời gian chạy: T(n) = T(n/2) + 7 = C * log2n
 Độ phức tạp: O(log2n)

13

Bài tập

 Trình bày giải thuật tìm kiếm tuyến tính?


 Xây dựng chương trình con tìm kiếm phần tử x
trong mảng số nguyên gồm n phần tử.
 Cho mảng 5, 3, 8, 12, 9.
 Nếu tìm phần tử 12 thì kết quả của chương
trình con là gì?
 Nếu tìm phần tử 7 thì kết quả là gì?
 Xây dựng chương trình con tìm kiếm phần tử x
trong mảng ký tự gồm n phần tử.

14

Bài tập

 Chương trình con sau dùng để làm gì?


int abc(int arr[], int n, int x)
{ int kq = -1;
for(int i = 0; i < n; i++)
if (arr[i] == x) kq = i;
return (kq);
}

15

5
BG CTDL&GT - Trang 13

Bài tập

 Trình bày giải thuật tìm kiếm nhị phân?


 Xây dựng chương trình con tìm kiếm phần tử x
trong mảng số nguyên gồm n phần tử đã được
xếp thứ tự.
 Cho mảng 5, 8, 12, 15, 19.
 Nếu tìm phần tử 12 thì kết quả của chương
trình con là gì?
 Nếu tìm phần tử 7 thì kết quả là gì?

16

Bài tập

 Xây dựng chương trình con tìm kiếm phần tử x


trong mảng ký tự gồm n phần tử đã được xếp
thứ tự.
 Giải thích thuật toán tìm kiếm nhị phân trên
mảng 5, 8, 12, 15, 19, 21, 34.

17

Một số bài toán khác

 Bài toán xóa một phần tử x trong mảng arr


Ý tưởng
 Thuật toán
 Chương trình
 Đánh giá
 Bài toán thêm một phần tử x trong mảng arr
 Bài toán cập nhật phần tử x trong mảng arr

18

6
BG CTDL&GT - Trang 14

Bài 3
***
KỸ THUẬT SẮP XẾP

Giới thiệu
 Nhu cầu sắp xếp
 Nhu cầu
 Thứ tự sắp xếp

 Bài toán sắp xếp


 Phần tử dữ liệu
 Nghịch thế
 Sắp xếp nội
 Sắp xếp ngoại
 Phân tích thuật toán 2

Giới thiệu

 Phát biểu bài toán


 Cho mảng arr[ ] gồm n phần tử nguyên chưa
có thứ tự.

 Sắpxếp mảng arr[ ] theo thứ tự tăng dần của


các phần tử.

1
BG CTDL&GT - Trang 15

Giới thiệu

 Giải thuật sắp xếp cơ bản

 Selection Sort (chọn trực tiếp)

 Insertion Sort (chèn trực tiếp)

 Interchange Sort (đổi chỗ trực tiếp)

 Bubble Sort (nổi bọt)

 Shaker Sort (lắc)

Giới thiệu

 Giải thuật sắp xếp hiệu quả cao

 Shell Sort

 Merge Sort

 Quick Sort

 Heap Sort

Shaker Sort (1)


 Ý tưởng
 Xuất phát từ cuối dãy,
 Xét hai phần tử gần nhau, nếu là nghịch thế
thì hoán vị hai phần tử này với mục đích đẩy
phần tử bé nhất về đầu dãy
9 5 8 3 7
 Trong mỗi lần sắp xếp sẽ thực hiện 2 lượt
 Lượt đi: đẩy phần tử bé nhất về đầu dãy
 Lượt về: đẩy phần tử lớn nhất về cuối dãy

2
BG CTDL&GT - Trang 16

Shaker Sort (1)

 Giải thuật
Bước 1: khởi tạo các giá trị
 left = 0;
 right = n-1;
 k = right;

Shaker Sort (1)


 Giải thuật
Bước 2: tìm và hoán vị các nghịch thế
 Lượt đi: duyệt mảng từ cuối lên đầu
 Hoán vị các nghịch thế
 Ghi nhận lại vị trí
 Sửa lại vị trí đầu dãy
 Lượt về: duyệt mảng từ đầu đến cuối
 Hoán vị các nghịch thế
 Ghi nhận lại vị trí
 Sửa lại vị trí cuối dãy 8

Shaker Sort (1)

 Giải thuật
Bước 3: Lặp lại bước 2
 Kiểm tra chiều dài đoạn cần sắp xếp

 Nếu chiều dài = 1 thì ngưng


 Nếu chiều dài > 1 thì lặp lại bước 2

3
BG CTDL&GT - Trang 17

Shaker Sort (1)

 Chương trình
void ShakerSort(int arr[], int n)
{ int left = 0; int right = n-1; int k = n-1;
while(left < right)
{ for(int i = right; i > left; i--)
if (a[i-1] > a[i])
{ hoanvi(a[i-1],a[i]); k=i; }
left = k;
for(int j = left; j < right; j++)
if (a[j] > a[j+1])
{ hoanvi(a[j],a[j+1]); k=j; }
right = k;
}
} 10

Shaker Sort (1)

 Minh họa

0 8 2 9 3 5 4
1a 2 8 3 9 4 5
1b 2 3 8 4 5 9

2a 2 3 4 8 5 9
2b 2 3 4 5 8 9

11

Shaker Sort (1)

 Đánh giá
 T(n) =?
 f(n) =?
 O(n) =?
 Trong while gồm 4 đoạn chương trình
 Xét cả đoạn chương trình

12

4
BG CTDL&GT - Trang 18

Selection Sort (2)

 Ý tưởng
 Chọn phần tử nhỏ nhất trong mảng
 Đưa phần tử này về đầu mảng
 (Lặp) Tiếp tục sắp xếp mảng từ vị trí thứ 2

8 2 9 3 5 4

2 8 9 3 5 4

13

Selection Sort (2)

 Giải thuật
Bước 1:
 i = 0;
Bước 2:
 Tìm phần tử nhỏ nhất trong mảng từ i đến n
 Hoán vị arr[i] và arr[min]
Bước 3:
i = i+1
 Nếu i < n thì lặp B2 ngược lại thì ngưng
14

Selection Sort (2)


 Chương trình
void SelectionSort(int arr[], int n)
{ int min;
for(int i = 0; i < n -1; i++)
{ min = i;
for(int j = i+1; j < n; j++)
if (arr[j] < arr[min])
min = j;
hoanvi(arr[i], arr[min]);
}
} 15

5
BG CTDL&GT - Trang 19

Selection Sort (2)

 Minh họa

0 8 2 9 3 5 4

1 2 8 9 3 5 4
2
3
4

16

Selection Sort (2)

 Đánh giá
 T(n) =?
 f(n) =?
 O(n) =?

17

Interchange Sort (3)


 Ý tưởng
 Khái niệm nghịch thế

 Bắtđầu từ đầu mảng, tìm các nghịch thế của


phần tử này, thực hiện hoán vị nếu có
8 4 9 3 5 2

 Lặplại từ phần tử kế tiếp cho đến khi mảng


được sắp xếp
18

6
BG CTDL&GT - Trang 20

Interchange Sort (3)

 Giải thuật
Bước 1:
 i = 0;
Bước 2:
 Tìm các nghịch thế với arr[i] từ i+1 đến n-1
và thực hiện hoán vị nếu gặp
Bước 3:
i = i+1
 Nếu i < n thì lặp B2 ngược lại thì ngưng
19

Interchange Sort (3)

 Chương trình
void InterchangeSort(int arr[], int n)
{
for(int i = 0; i < n -1; i++)
for(int j = i+1; j < n; j++)
if (arr[i] > arr[j])
hoanvi(arr[i], arr[j]);
}

20

Interchange Sort (3)

 Minh họa

0 8 2 9 3 5 4
1

2
3
4
5

21

7
BG CTDL&GT - Trang 21

Interchange Sort (3)

 Đánh giá
 T(n) =?
 f(n) =?
 O(n) =?

22

Bubble Sort (4)


 Ý tưởng
 Nghịch thế

 Xuấtphát từ cuối dãy, hoán vị các cặp nghịch


thế kế tiếp nhau
8 4 2 9 3 5

 Lặp lại cho đến khi mảng được sắp xếp


23

Bubble Sort (4)

 Giải thuật
Bước 1:
 i = 0;
Bước 2:
 j=n-1
 nếu arr[j] < arr[j-1] thì hoán vị
Bước 3:
 j=j-1
 Nếu j > i thì lặp B2.2 ngược lại thì ngưng
24

8
BG CTDL&GT - Trang 22

Bubble Sort (4)

 Giải thuật
Bước 4:
 i=i+1
 Nếu i < n thì lặp B2 ngược lại thì ngưng

25

Bubble Sort (4)

 Chương trình
void BubbleSort(int arr[ ], int n)

26

Bubble Sort (4)

 Minh họa

0 8 2 9 3 5 4
1

2
3
4
5

27

9
BG CTDL&GT - Trang 23

Bubble Sort (4)

 Đánh giá
 T(n) =?
 f(n) =?
 O(n) =?

28

Insertion Sort (5)


 Ý tưởng
 Chiamảng cần sắp xếp thành 2 mảng con:
mảng T chứa arr[0], mảng P chứa phần còn lại
 Chọnmột phần tử arr[i] trong P, tìm vị trí thích
hợp và chèn arr[i] vào mảng T
9 5 8 3 7

 Lặp lại cho đến khi mảng P rỗng


29

Insertion Sort (5)


 Giải thuật
Bước 1: Xét i = 1
Bước 2:
 Đặt x = arr[i]

 Tìm vị trí pos thích hợp để chèn x

Bước 3: dời các phần tử từ arr[pos] ra sau 1 ô


Bước 4: arr[pos] = x
Bước 5:
 i++

 Nếu i < n lặp lại Bước 2 ngược lại kết thúc


30

10
BG CTDL&GT - Trang 24

Insertion Sort (5)


 Chương trình
void InsertionSort(int arr[], int n)
{ int pos, x;
for(int i = 1; i < n; i++)
{ x = arr[i]; pos = i – 1;
while((pos >= 0) && arr[pos] > x)
{ arr[pos + 1] = arr[pos];
pos – –;
}
arr[pos + 1] = x;
}
} 31

Insertion Sort (5)

 Minh họa

0 8 2 9 3 5 4
1
2

3
4
5

32

Insertion Sort (5)

 Đánh giá
 T(n) =?
 f(n) =?
 O(n) =?

33

11
BG CTDL&GT - Trang 25

Bài 4
***
SẮP XẾP HIỆU QUẢ CAO

Quick Sort

 Ý tưởng
 Phân chia mảng ban đầu thành ba mảng con
 Mảng con 1: gồm các phần tử nhỏ hơn x
 Mảng con 2: gồm một phần tử x
 Mảng con 3: gồm các phần tử lớn hơn x
8 6 9 12 19 13 15
 Tiếp tục áp dụng Quick Sort cho dãy con 1 và
dãy con 3

Quick Sort

 Giải thuật
Bước 1: Chia mảng ban đầu thành 3 mảng con
 Chọn tùy ý phần tử a[k] làm mốc
 Phát hiện và hoán vị cặp phần tử a[i], a[j] nằm
sai vị trí
 Lặp lại bước 1.2 cho đến khi hết

8 16 17 14 6 10 19

1
BG CTDL&GT - Trang 26

Quick Sort
 Giải thuật
Bước 2: Đệ quy trên hai mảng con
 Số phần tử của mảng con trái > 1?
 Đúng: dùng Quick Sort trên mảng này
 Số phần tử của mảng con phải > 1?

 Đúng: dùng Quick Sort trên mảng này

Quick Sort
 Chương trình
void QuickSort(int arr[], int left, int right)
{ int i = left, j = right, x = arr[(left+right)/2];
do
{ while (arr[i] < x) i++;
while (arr[j] > x) j--;
if (i <= j)
{ hoanvi(arr[i],arr[j]); i++; j--;}
}while (i < j);
if (left < j) QuickSort(arr, left, j);
if (i < right) QuickSort(arr, i, right);
} 5

Quick Sort

 Minh họa

0 12 2 8 5 1 6 4 15
1

2
3
4
5

2
BG CTDL&GT - Trang 27

Quick Sort

 Đánh giá
 T(n) =?
 f(n) =?
 O(n) =?

Merge Sort (trộn trực tiếp)

 Ý tưởng
 Mảng gồm một phần tử là mảng có thứ tự
 Mỗi mảng a1, a2, …, an là một tập hợp n mảng
con có thứ tự
8 16 17 14 6 10 19
 Sắp xếp mảng là thao tác giảm số dãy con
của mảng cho đến khi số dãy con = 1

Merge Sort (trộn trực tiếp)

 Ý tưởng
 Merge Sort được chia thành 2 phần
 Phân hoạch mảng ban đầu thành các mảng
con rồi chia thành hai mảng phụ theo
nguyên tắc phân phối luân phiên
 Trộn từng cặp mảng con của 2 mảng phụ
thành một mảng con của dãy ban đầu
 Lặp lại cho đến khi xong

3
BG CTDL&GT - Trang 28

Merge Sort (trộn trực tiếp)

 Minh họa

0 9 5 4 7 3 8 2 10

1a 9 4 3 2
5 7 8 10
1b 5 9 4 7 3 8 2 10

2a 5 9 3 8
4 7 2 10
2b 4 5 7 9 2 3 8 10
10

Merge Sort (trộn trực tiếp)

 Minh họa

2b 4 5 7 9 2 3 8 10

3a 4 5 7 9
2 3 8 10
3b 2 3 4 5 7 8 9 10

11

Merge Sort (trộn trực tiếp)


 Giải thuật
Bước 1: khởi tạo các giá trị
 k = 1;

Bước 2: phân chia mảng thành 2 mảng con


 b = a1, …, ak, a2k+1, …, a3k, …
 c = ak+1, … a2k, a3k+1, …, a4k, …
Bước 3: trộn từng cặp dãy con
Bước 4: lặp
 k = k*2

 Nếu k < n thì lặp lại B2 ngược lại thì dừng 12

4
BG CTDL&GT - Trang 29

Merge Sort (trộn trực tiếp)

 Chương trình

13

Merge Sort (trộn trực tiếp)

 Đánh giá
 T(n) =?
 f(n) =?
 O(n) =?

14

Merge Sort (trộn tự nhiên)

 Ý tưởng
 “Đường chạy” là một dãy con có thứ tự của
một mảng
 Mỗimảng a1, a2, …, an là một tập hợp các
đường chạy
8 16 17 14 6 10 19

 Sắp xếp mảng là thao tác giảm số đường


chạy của mảng cho đến khi số đường = 1

15

5
BG CTDL&GT - Trang 30

Merge Sort (trộn tự nhiên)

 Ý tưởng
 Merge Sort được chia thành 2 phần
 Phân hoạch mảng ban đầu thành các mảng
con rồi chia thành hai dãy phụ theo nguyên
tắc phân phối luân phiên
 Trộn từng cặp dãy con của 2 dãy phụ thành
một dãy con của dãy ban đầu
 Lặp lại cho đến khi xong

16

Merge Sort (trộn tự nhiên)

 Minh họa

0 9 5 4 7 3 8 2 10

1a 9 4 7 2 10
5 3 8
1b 5 9 3 4 7 8 2 10

2a 5 9 2 10
3 4 7 8

2b 3 4 5 7 8 9 2 10
17

Merge Sort (trộn tự nhiên)

 Minh họa

2b 3 4 5 7 8 9 2 10

3a 3 4 5 7 8 9
2 10
3b 2 3 4 5 7 8 9 10

18

6
BG CTDL&GT - Trang 31

Bài tập

 Quick Sort
 Sắp xếp mảng 14, 12, 6, 10, 8, 16, 18
 Sắp xếp mảng 12, 2, 8, 5, 1, 5, 4
 Merge Sort (trộn trực tiếp)
 Sắp xếp mảng 32, 72, 87, 83, 41, 24, 14, 27
 Sắp xếp mảng 25, 2, 29, 16, 18, 26, 89
 Merge Sort (trộn tự nhiên)
 Sắp xếp mảng 6, 60, 36, 92, 29, 28, 77
 Sắp xếp mảng 5, 59, 31, 85, 10, 88, 32
19

7
BG CTDL&GT - Trang 32

Bài 5
***
CẤU TRÚC DỮ LIỆU ĐỘNG

Nội dung

 Cấu trúc dữ liệu động

 Danh sách liên kết

 Danh sách liên kết đơn

 Stack

 Queue

Cấu trúc dữ liệu động

 Nhu cầu
 Kiểu cơ bản
 Cấu trúc cơ bản
typedef struct sv
{ char mssv[8];
int sotc;
float dtbtl;
}
sv qlsv[1000];
3

1
BG CTDL&GT - Trang 33

Cấu trúc dữ liệu động

 Kiểu con trỏ


 Kiểu dữ liệu tĩnh – Biến tĩnh

 Kiểu dữ liệu con trỏ


Cho kiểu cơ bản T => kiểu con trỏ Tp
 Biến con trỏ
 Khai báo biến con trỏ: kieu_dl *ten_bien;
 Gán địa chỉ cho biến con trỏ: bien_tro = &bien;
 Truy xuất vùng nhớ: *ten_bien
4

Cấu trúc dữ liệu động

 Biến động
 Giới thiệu
 Không khai báo tường minh
 Được quản lý bởi biến con trỏ
 Được tạo ra theo yêu cầu của người sử dụng
 Kích thước có thể thay đổi

Cấu trúc dữ liệu động


 Biến động
 Tạo biến động
 Khai báo biến con trỏ
 Từ khóa new
int *p1, *p2;
p1 = new int;
p2 = new int[10];
p1* = 5;
p2* = 1;
(p2+2)* = 4;
6

2
BG CTDL&GT - Trang 34

Cấu trúc dữ liệu động

 Biến động
 Hủy biến động
 Từ khóa delete
delete p1;
delete []p2;

Danh sách liên kết


 Kiểu danh sách liên kết
 Định nghĩa
Cho kiểu dữ liệu T => kiểu danh sách liên kết Tx

 Thao tác
o Tạo danh sách
o Thêm phần tử
o Xóa phần tử
o Đếm số phần tử/Liệt kê danh sách
o Tìm kiếm
o Sắp xếp 8

Danh sách liên kết


 Các kiểu danh sách liên kết
 Danh sách liên kết đơn

 Danh sách liên kết vòng

 Danh sách liên kết kép

3
BG CTDL&GT - Trang 35

Danh sách liên kết đơn

 Giới thiệu
 Định nghĩa phần tử danh sách

typedef struct Data typedef struct Node


{ Type0 key; { DataType infor;
Type1 var_1; struct Node *next;
… }NodeType;
Typen var_n;
}DataType;
10

Danh sách liên kết đơn

 Giới thiệu
 Định nghĩa danh sách
tydedef struct
{ NodeType *head;
NodeType *tail;
}LList;

11

Danh sách liên kết đơn

 Thao tác cơ bản


 Khởi tạo
void Init_List(LList *list)
{ list->head = NULL;
list->tail = NULL;
}

12

4
BG CTDL&GT - Trang 36

Danh sách liên kết đơn

 Thao tác cơ bản


 Tạo phần tử danh sách
NodeType* GetNode(DataType x)
{ NodeType* p;
p = new NodeType;
p->infor = x;
p->next = NULL;
return p;
}
13

Danh sách liên kết đơn


 Thao tác cơ bản
 Thêm phần tử (vào đầu danh sách)

void AddFirst(LList* list, NodeType *n)


{ if (list->head == NULL)
{ list->head = n;
list->tail = list->head;
}else
{ n->next = list->head;
list->head = n;
}
} 14

Danh sách liên kết đơn


 Thao tác cơ bản
 Thêm phần tử (vào cuối danh sách)

void AddLast(LList *list, NodeType *n)


{ if (list->head == NULL)
{ list->head = n;
list->tail = list->head;
}else
{ list->tail->next = n;
list->tail = n;
}
} 15

5
BG CTDL&GT - Trang 37

Danh sách liên kết đơn


 Thao tác cơ bản
 Xóa phần tử

void DelFirst(LList *list)


{ NodeType *p;
if (list->head != NULL)
{ p = list->head;
list->head = list->head->next;
delete p;
if(list->head == NULL)
lish->tail = NULL;
}
} 16

Danh sách liên kết đơn


 Thao tác cơ bản
 Danh sách phần tử

void PrintList(LList* list)


{ NodeType* p;
p = list->head;
while (p != NULL)
{ Xuat_o(p->infor);
p = p->next;
}
} 17

Danh sách liên kết đơn


 Thao tác cơ bản
 Đếm số phần tử

int CountList(LList* list)


{ NodeType* p;
int count = 0;
p = list->head;
while (p != NULL)
{ count++;
p = p->next;
}
return count;
} 18

6
BG CTDL&GT - Trang 38

Danh sách liên kết đơn

 Tìm kiếm theo khóa


NodeType* FindList(LList* list, Type0 k)
{ NodeType* p;
p = list->head;
while (p != NULL && p->infor->key != k)
p = p->next;
return p;
}

19

Danh sách liên kết đơn


 Sắp xếp
 Selection Sort
void SelectionSortList(LList* list)
{ NodeType *p, *q, *min;
p = list->head;
while (p != list->tail)
{ q = p->next;
//Tìm min;
hoanvi(min->infor, p->infor);
p = p->next;
}
} 20

Danh sách liên kết đơn

 Sắp xếp
 Selection Sort

// Tìm min
min = p;
while (q != NULL)
{ if(q->infor.key < min->infor.key)
min = q;
q = q->next;
}

21

7
BG CTDL&GT - Trang 39

Danh sách liên kết đơn


 Sắp xếp
 Quick Sort
void QuickSortList(LList* list)
{ NodeType *p, *x; LList l1, l2;
if (list->head != list->tail)
{ l1->head = NULL; l1->tail = NULL;
l2->head = NULL; l2->tail = NULL;
x = list->head; list->head = x->next;
//Tách list thành l1 và l2
QuickSortList(l1); QuickSortList(l2);
//Nối l1, x, l2 thành danh sách ban đầu
}
} 22

Danh sách liên kết đơn

 Sắp xếp
 Quick Sort
//Tách list thành l1 và l2
while (list->head != NULL)
{ p = list->head;
list->head = p->next;
p->next = NULL;
if(p->infor->key <= x->infor->key)
AddLast(l1, p);
else
AddLast(l2, p);
}
23

Danh sách liên kết đơn

 Sắp xếp
 Quick Sort
//Nối l1, x và l2 thành chuỗi ban đầu
if(l1->head != NULL)
{ list->head = l1->head;
l1->tail->next = x;
}else
list->head = x;
x->next = l2;
if(l2->head != NULL)
list->tail = l2->tail;
else
list->tail = x;
24

8
BG CTDL&GT - Trang 40

Stack – Ngăn xếp

 Giới thiệu
 Giới thiệu
 Stack là vật chứa dữ liệu
 Cơ chế LIFO (Last In First Out)

 Thao tác trên Stack


 int Push(s, x)
 int Pop(s, x)
 int Top(s, x)

25

Stack – Ngăn xếp

 Cài đặt Stack dùng mảng


 Khai báo
 int Push(sa, t, x)
 int Pop(sa, t, x)
 int Top(sa, t, x)

26

Stack – Ngăn xếp

 Cài đặt Stack dùng mảng


 Khai báo

DataType sa[n];
int t;

t = 0;

27

9
BG CTDL&GT - Trang 41

Stack – Ngăn xếp


 Cài đặt Stack dùng mảng
 Push

int Push(DataType sa[], int &t, DataType x)


{ if(t < n)
{ sa[t] = x;
t++;
return(1);
}else
return(0);
}
28

Stack – Ngăn xếp


 Cài đặt Stack dùng mảng
 Pop

int Pop(DataType sa[], int &t, DataType &x)


{ if(t > 0)
{ t--;
x = sa[t];
return(1);
}else
return(0);
} 29

Stack – Ngăn xếp


 Cài đặt Stack dùng mảng
 Top

int Top(DataType sa[], int t, DataType &x)


{ if(t > 0)
{ x = sa[t-1];
return(1);
}else
return(0);
}
30

10
BG CTDL&GT - Trang 42

Stack – Ngăn xếp

 Cài đặt Stack dùng DSLK


 Khai báo
 void Push(sL, x)
 int IsEmpty(sL)
 int Pop(sL, x)
 int Top(sL, x)

31

Stack – Ngăn xếp

 Cài đặt Stack dùng DSLK


 Khai báo

LList *sL;

sL->head = NULL;
sL->tail = NULL;

32

Stack – Ngăn xếp


 Cài đặt Stack dùng DSLK
 Push

void Push(LList *sL, DataType x)


{ NodeType* n = GetNode(x);
AddFirst(sL, n);
}

33

11
BG CTDL&GT - Trang 43

Stack – Ngăn xếp


 Cài đặt Stack dùng DSLK
 IsEmpty

int IsEmpty(LList *sL)


{ if(sL->head == NULL)
return(1);
else
return(0);
}

34

Stack – Ngăn xếp


 Cài đặt Stack dùng DSLK
 Pop

int Pop(LList *sL, DataType &x)


{ if(IsEmpty(sL) == 0)
{ x = sL->head->infor;
DelFirst(sL);
return(1);
}else
return(0);
}
35

Stack – Ngăn xếp


 Cài đặt Stack dùng DSLK
 Top

int Top(LList *sL, DataType &x)


{ if(IsEmpty(sL) == 0)
{ x = sL->head->infor;
return(1);
}else
return(0);
}
36

12
BG CTDL&GT - Trang 44

Queue – Hàng đợi


 Queue
 Giới thiệu
 Queue là vật chứa dữ liệu
 Cơ chế FIFO (First In First Out)

 Thao tác trên Queue


 EnQueue(q, x)
 DeQueue(q, x)
 Front(q, x)

37

Queue – Hàng đợi

 Cài đặt Queue dùng mảng


 Khai báo
 int EnQueue(qa, f, r, x)
 int DeQueue(qa, f, r, x)
 int Front(qa, f, r, x)
f r f r f r

r f r f r f

38

Queue – Hàng đợi

 Cài đặt Queue dùng mảng


 Khai báo

DataType qa[n];
int f, r;

f = 0;
r = 0;

39

13
BG CTDL&GT - Trang 45

Queue – Hàng đợi


 Cài đặt Queue dùng mảng
 EnQueue

int EnQueue(DataType qa[ ], int f, int &r, DataType x)


{ if(r!= f) //Queue chưa đầy
{ qa[r] = x;
r++;
if(r == n)
r = 0;
return(1);
}else
return(0);
}
40

Queue – Hàng đợi


 Cài đặt Queue dùng mảng
 DeQueue

int DeQueue(DataType qa[ ], int &f, int r, DataType &x)


{ if(r != f) //Queue không rỗng
{ x = qa[f];
f++;
if(f == n)
f = 0;
return(1);
}else
return(0);
} 41

Queue – Hàng đợi


 Cài đặt Queue dùng mảng
 Front

int Front(DataType qa[ ], int f, int r, DataType &x)


{ if(r != f) //Queue không rỗng
{ x = qa[f];
return(1);
}else
return(0);
}

42

14
BG CTDL&GT - Trang 46

Queue – Hàng đợi

 Cài đặt Queue dùng DSLK


 Khai báo
 void EnQueue(qL, x)
 int DeQueue(qL, x)
 int Front(qL, x)

43

Queue – Hàng đợi

 Cài đặt Queue dùng DSLK


 Khai báo

LList *qL;

qL->head = NULL;
qL->tail = NULL;

44

Queue – Hàng đợi


 Cài đặt Queue dùng DSLK
 EnQueue

void EnQueue(LList *qL, DataType x)


{ NodeType *p;
p = GetNode(x);
if(qL->head ==NULL)
{ qL->head = p;
qL->tail = qL->head;
}else
{ qL->tail->next = p;
qL->tail = p;
}
} 45

15
BG CTDL&GT - Trang 47

Queue – Hàng đợi


 Cài đặt Queue dùng DSLK
 DeQueue

int DeQueue(LList *qL, DataType &x)


{ if(qL->head != NULL)
{ x = qL->head->infor;
DelFirst(qL);
return(1);
}else
return(0);
}
46

Queue – Hàng đợi


 Cài đặt Queue dùng DSLK
 Front

int Front(LList *qL, DataType &x)


{ if(qL->head != NULL)
{ x = qL->head->infor;
return(1);
}else
return(0);
}
47

16
Bài thực hành Cấu trúc dữ liệu và Giải thuật

Proj 01: PHÂN TÍCH GIẢI THUẬT

1.1 Viết chương trình con thực hiện các yêu cầu. Sau đó tính toán thời gian chạy của chương
trình.

a. Hoán vị hai số nguyên

b. Tính tổng 2 số nguyên trong phạm vi từ 0 đến 100. Nếu số không hợp lệ thì kết quả = -1.

c. Tìm giá trị nhỏ nhất của 4 số thực

d. Tính n giai thừa (với 0 <= n <= 10)

1.2 Viết chương trình con thực hiện các yêu cầu. Tính toán thời gian chạy của chương trình.

a. Cài đặt cấu trúc lưu trữ đa thức bậc n

b. Nhập đa thức

c. Xuất đa thức

d. Tính giá trị của đa thức

Proj 02: MẢNG CƠ BẢN

2.1 Cài đặt mảng số nguyên gồm 100 phần tử

2.2 Viết chương trình con nhập mảng số nguyên có n phần tử (5 <= n <= 100)

2.3 Viết chương trình con xuất mảng số nguyên có n phần tử, mỗi phần tử cách nhau 1 tab

2.4 Viết chương trình con tìm kiếm phần tử x trong mảng số nguyên có n phần tử (dùng LS)

2.5 Viết chương trình con tìm kiếm phần tử x trong mảng số nguyên có n phần tử (dùng BS)

2.6 Viết chương trình con sắp xếp mảng số nguyên có n phần tử (dùng Shaker Sort)

2.7 Viết chương trình con sắp xếp mảng số nguyên có n phần tử (dùng Selection Sort)

2.8 Viết chương trình con sắp xếp mảng số nguyên có n phần tử (dùng Interchange Sort)

2.9 Viết chương trình con sắp xếp mảng số nguyên có n phần tử (dùng Bubble Sort)

2.10 Viết chương trình con sắp xếp mảng số nguyên có n phần tử (dùng Insertion Sort)

2.11 Viết chương trình con sắp xếp mảng số nguyên có n phần tử (dùng Quick Sort)

2.12 Viết chương trình con sắp xếp mảng số nguyên có n phần tử (dùng Merge Sort)

1
Bài thực hành Cấu trúc dữ liệu và Giải thuật

Proj 03: MẢNG CẤU TRÚC

3.1 Định nghĩa cấu trúc Sinh viên gồm: MSSV, Họ, Tên, Số TC, ĐTBTL

3.2 Cài đặt mảng cấu trúc Sinh viên (mảng SV) gồm 100 phần tử

3.3 Viết chương trình con nhập mảng SV có n phần tử (5 <= n <= 100)

3.4 Viết chương trình con xuất mảng SV có n phần tử

3.5 Viết chương trình con tìm thông tin SV có mã số x trong mảng SV có n phần tử (dùng LS)

3.6 Viết chương trình con tìm thông tin SV có mã số x trong mảng SV có n phần tử (dùng BS)

3.7 Viết chương trình con tìm thông tin SV có điểm cao nhất trong mảng SV có n phần tử

3.8 Viết chương trình con sắp xếp theo MSSV của mảng SV có n phần tử (dùng Shaker Sort)

3.9 Viết chương trình con sắp xếp theo MSSV của mảng SV có n phần tử (dùng Selection Sort)

3.10 Viết chương trình con sắp xếp theo Tên của mảng SV có n phần tử (dùng Interchange Sort)

3.11 Viết chương trình con sắp xếp theo Số TC của mảng SV có n phần tử (dùng Bubble Sort)

3.12 Viết chương trình con sắp xếp theo ĐTBTL của mảng SV có n phần tử (dùng Insertion Sort)

3.13 Viết chương trình con sắp xếp theo MSSV của mảng SV có n phần tử (dùng Quick Sort)

3.14 Viết chương trình con sắp xếp theo MSSV của mảng SV có n phần tử (dùng Merge Sort)

Proj 04: DANH SÁCH LIÊN KẾT

4.1 Cài đặt DSLK hỗ trợ quản lý danh sách Nhân viên (MSNV, Tên, Tuổi, Lương)

4.2 Viết chương trình con nhập danh sách Nhân viên

4.3 Viết chương trình con xuất danh sách Nhân viên

4.4 Viết chương trình con tìm kiếm thông tin NV có mã số x trong danh sách (dùng LS)

4.5 Viết chương trình con tìm kiếm thông tin NV có mã số x trong danh sách (dùng BS)

4.6 Viết chương trình con tìm kiếm thông tin NV có tuổi cao nhất trong danh sách

4.7 Viết chương trình con sắp xếp danh sách theo MSNV (dùng Shaker Sort)

4.8 Viết chương trình con sắp xếp danh sách theo MSNV (dùng Selection Sort)

4.9 Viết chương trình con sắp xếp danh sách theo Tên (dùng Interchange Sort)

4.10 Viết chương trình con sắp xếp danh sách theo Tuổi (dùng Bubble Sort)

2
Bài thực hành Cấu trúc dữ liệu và Giải thuật
4.11 Viết chương trình con sắp xếp danh sách theo Lương (dùng Insertion Sort)

4.12 Viết chương trình con sắp xếp danh sách theo MSNV (dùng Quick Sort)

4.13 Viết chương trình con sắp xếp danh sách theo MSNV (dùng Merge Sort)

Proj 05: STACK

5.1 Cài đặt Stack1 sử dụng mảng 5 phần tử hỗ trợ lưu trữ đa thức bậc n (Bậc, Các hệ số)

5.2 Viết chương trình con Push cho Stack1

5.3 Viết chương trình con Pop cho Stack1

5.4 Viết chương trình con Top cho Stack1

5.5 Cài đặt Stack2 sử dụng DSLK hỗ trợ lưu trữ đa thức bậc n

5.6 Viết chương trình con Push cho Stack2

5.7 Viết chương trình con IsEmpty cho Stack2

5.8 Viết chương trình con Pop cho Stack2

5.9 Viết chương trình con Top cho Stack2

Proj 06: QUEUE

6.1 Cài đặt Queue1 sử dụng mảng 5 phần tử hỗ trợ lưu trữ thông tin hàng hóa (Mã hàng, Tên,
Giá)

6.2 Viết chương trình con EnQueue cho Queue1

6.3 Viết chương trình con DeQueue cho Queue1

6.4 Viết chương trình con Front cho Queue1

6.5 Cài đặt Queue2 sử dụng DSLK hỗ trợ lưu trữ thông tin hàng hóa

6.6 Viết chương trình con EnQueue cho Queue2

6.7 Viết chương trình con DeQueue cho Queue2

6.8 Viết chương trình con Front cho Queue2

HẾT

You might also like