1. Trang chủ
  2. » Công Nghệ Thông Tin

Bài giảng Cấu trúc dữ liệu: Chương 3 - ThS. Thiều Quang Trung (2018)

61 3 0

Đ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ấu trúc dữ liệu: Chương 3
Tác giả Th.S. Thiều Quang Trung
Trường học Trường Cao đẳng Kinh tế Đối ngoại
Thể loại Bài giảng
Năm xuất bản 2018
Định dạng
Số trang 61
Dung lượng 1,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

Bài giảng Cấu trúc dữ liệu - Chương 3: Các thuật toán sắp xếp cung cấp cho người học các kiến thức: Chọn trực tiếp - Selection Sort, chèn trực tiếp - Insertion Sort, đổi chỗ trực tiếp - Interchange Sort, nổi bọt - Bubble Sort, sắp xếp dựa trên phân hoạch - Quick Sort, trộn trực tiếp - Merge Sort. Mời các bạn cùng tham khảo.

Trang 1

C HƯƠNG 3

C ÁC T HUẬT T OÁN S ẮP X ẾP

GV Th.S Thiều Quang Trung Trường Cao đẳng Kinh tế Đối ngoại

Trang 2

• Chọn trực tiếp - Selection Sort

Trang 3

Các khái niệm

• Sắp xếp là gì ?

– Sắp xếp là quá trình xử lý một danh sách các phần

tử (hoặc các mẫu tin) để đặt chúng theo một thứ

tự thỏa mãn một tiêu chuẩn nào đó

• Khái niệm nghịch thế:

– Xét một mảng các số a0, a1, … ,aN

– Giả sử xét mảng có thứ tự tăng dần, nếu có i < j và

a i > a j , thì ta gọi đó là nghịch thế.

Trang 4

Các khái niệm

• Để sắp xếp một mảng => tìm cách giảm số các nghịch thế trong mảng này bằng cách hoán vị các cặp phần tử.

• Cho trước một dãy số a1, a2, … aN được lưu trữ trong cấu trúc dữ liệu mảng.

Ví dụ: int a[N];

=> Chọn lựa một số phương pháp để sắp xếp.

Trang 5

• Ý tưởng: thực hiện N-1 lần việc đưa phần tử nhỏ

nhất trong dãy hiện hành về vị trí đứng ở đầu dãy

• Nhận xét: nếu mảng có thứ tự thì phần tử ai luôn

là min (ai,ai+1, ,an-1) => Ý tưởng của thuật toán

chọn trực tiếp:

– Chọn phần tử nhỏ nhất trong N phần tử ban đầu, đưa

phần tử này về vị trí đứng đầu dãy hiện hành;

– Sau đó không quan tâm phần tử này nữa, xem dãy hiện hành chỉ còn N-1 phần tử của dãy ban đầu, bắt đầu từ

Trang 7

1 Chọn trực tiếp (tt)

Trang 8

1 Chọn trực tiếp (tt)

Trang 9

void SelectionSort ( int a[], int n )

{

int min; // chỉ số phần tử nhỏ nhất trong dãy hiện hành

Trang 10

• Ở lượt thứ I, cần (n-i) lần so sánh để tìm phần tử nhỏ nhất

hiện hành Số lượng phép so sánh không phụ thuộc vào tình trạng của dãy ban đầu.

• Trong mọi trường hợp số lần so sánh là

• Số lần hoán vị (một hoán vị bằng 3 phép gán) phụ thuộc vào tình trạng ban đầu của dãy số

Đánh giá giải thuật Chọn trực tiếp

Xấu nhất

0 Tốt nhất

Số phép gán

Số lần so sánh Trường hợp

2

) 1 ( −n n

2

) 1 ( −n n

2

) 1 (

3n n

2

1) n(n i)

(n

1 n

1 i

Trang 11

theo giải thuật tìm tuần tự (Sequential Search)

→ có dãy mới {a0,a1,…,ak-1,ak} có thứ tự.

• Vị trí cần chèn ak chính là giữa 2 phần tử ai-1 và aisao cho ai-1 ≤ ak+1 ≤ ai

Chèn trực tiếp - Insertion Sort

Trang 12

Thuật toán:

B1: k = 1 //Giả sử đoạn a[0] đã sắp xếp

B2: x = ak Tìm vị trí pos thích hợp trong đoạn a0 đến ak-1 để chèn ak vào

B3: Dời chỗ các phần tử từ apos đến ak-1 sang phải 1 vị trí để dành chỗ cho ak

B4: apos = x; // đoạn a 0 … a k đã được sắp

Trang 13

Ví dụ mô phỏng chèn trực tiếp

• Cho dãy số a : N = 8 ;

Trang 14

Ví dụ mô phỏng chèn trực tiếp (tt)

Trang 15

void InsertionSort (int a [ ], int n)

{ int k=0, i;

while (a[k]≤a[k+1] && k<n) k++;

while (k<n)

while (x<a[i] && i>0)

i ;

} a[i+1]=x;

k++;

} return ;

Cài đặt giải thuật Chèn trực tiếp

Trang 16

• Trường hợp tốt nhất: khi mảng a ban đầu đã

– Số phép gán: Gmax = 2*(n-1) + n*(n-1)/2

– Số phép so sánh: Smax = n-1

• Độ phức tạp của thuật toán: O(n2)

Đánh giá giải thuật Chèn trực tiếp

Trang 17

(Binary Search) thay cho tìm kiếm tuần tự

(Sequential Search)

Chèn nhị phân – Binary Insertion Sort

Trang 18

void BinaryInsertionSort ( int a[], int n )

{ int l,r,m,i;

int x;//lưu trữ giá trị a[i] tránh bị ghi đè khi dời chỗ các phần tử.

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

{ x = a[i]; l = 0; r = i-1;

while (l<=r) // tìm vị trí chèn x{ m = (l+r)/2; // tìm vị trí thích hợp m

if (x < a[m]) r = m-1;

else l = m+1;

} for ( int j = i ; j >l ; j )

a[j] = a[j-1]; // dời chỗ các phần tử sẽ đứng sau x

a[l] = x; // chèn x vào dãy}

}

Cài đặt Binary Insertion Sort

Trang 19

• Phương pháp chèn nhị phân chỉ cải tiến cách tìm kiếm vị trí thích hợp của phần tử a[i], làm giảm số lần so sánh nhưng lại không làm thay đổi số lần di chuyển.

• Vì vậy việc cải tiến này không đáng kể lắm →

Độ phức tạp của thuật toán vẫn là O(n2)

Đánh giá Binary Insertion Sort

Trang 20

Đổi chỗ trực tiếp - Interchange Sort

• Ý tưởng :

Ý tưởng chính của giải thuật là xuất phát đầu dãy, tìm tất cả nghịch thế chứa phần tử này, triệt tiêu chúng bằng cách đổi chỗ phần tử này với phần tử tương

ứng trong cặp nghịch thế Lặp lại xử lý trên với các

phần tử tiếp theo trong dãy

Trang 21

3 Đổi chỗ trực tiếp (tt)

• Giải thuật :

B1 : i = 1 ; // Bắt đầu từ đầu dãy.

B2 : j = i + 1 ; // Tìm các phần tử a[j] < a[i], j > i

B3 : Trong khi j  n thực hiện

Nếu a[j] < a[i] : Hoán vị a[i] và a[j] ;

j = j +1;

B4 :i = i+1;

Nếu i < n : lặp lại Bước 2

Ngược lại : Dừng

Trang 22

Ví dụ mô phỏng Đổi chỗ trực tiếp

• Cho dãy số a : N = 8 ;

Trang 23

Ví dụ mô phỏng Đổi chỗ trực tiếp (tt)

Trang 24

Ví dụ mô phỏng Đổi chỗ trực tiếp (tt)

Trang 25

Ví dụ mô phỏng Đổi chỗ trực tiếp (tt)

Trang 26

Ví dụ mô phỏng Đổi chỗ trực tiếp (tt)

Trang 27

Ví dụ mô phỏng Đổi chỗ trực tiếp (tt)

Trang 28

Cài đặt thuật toán Đổi chỗ trực tiếp

void InterchangeSort ( int a[] , int N )

Trang 29

Đánh giá giải thuật Đổi chỗ trực tiếp

Số lượng các phép so sánh không phụ thuộc vào tình trạng của dãy số ban đầu, nhưng số lượng các phép hoán vị phụ thuộc vào kết quả so sánh

2

) 1 ( −n n

2

) 1 ( −n n

2

) 1 ( −n

n

Xấu nhất

0 Tốt nhất

Số lần hoán vị

Số lần so sánh Trường hợp

Trang 30

Giải thuật Nổi bọt (Bubble Sort)

Ý tưởng :

• Xuất phát từ cuối (đầu) dãy, đổi chỗ các cặp phần tử

kế cận để đưa phần tử nhỏ (lớn) hơn trong cặp phần

tử đó về vị trí đứng đầu (cuối) dãy hiện hành, sau đó

sẽ không xét đến nó ở bước tiếp theo,

• Ở lần xử lý thứ i sẽ có vị trí đầu dãy là i

• Lặp lại xử lý trên cho đến khi không còn cặp phần tử nào để xét

Trang 31

Giải thuật :

B1: i = 0 ; // Lần xử lý đầu tiên

B2: j = N-1 ; // Duyệt từ cuối dãy ngược về vị trí i

Trong khi (j > i) thực hiện

if a[j] < a[j-1] : swap (a[j], a[j-1]);

j = j - 1;

B3: i = i + 1; // Lần xử lý kế tiếp

Nếu i = n: Hết dãy DừngNgược lại : Lặp lại Bước 2

Giải thuật Nổi bọt (Bubble Sort)

Trang 32

void BubbleSort ( int a[], int n)

Trang 33

Ví dụ mô phỏng giải thuật Nổi bọt

• Cho dãy số a : N = 8 ;

Trang 34

4 Nổi bọt (tt)

Trang 35

4 Nổi bọt (tt)

Trang 36

4 Nổi bọt (tt)

Trang 37

4 Nổi bọt (tt)

Trang 38

4 Nổi bọt (tt)

Trang 39

Đánh giá thuật toán Nổi bọt

• Số lượng các phép so sánh xảy ra không phụ thuộc vào tình trạng của dãy số ban đầu,

• Số lượng phép hoán vị thực hiện tùy thuộc vào kết quả so sánh

Xấu nhất

0 Tốt nhất

Số lần hoán vị

Số lần so sánh Trường hợp

2

) 1 ( −n n

2

) 1 ( −n n

2

) 1 ( −n n

Trang 40

Sắp xếp dựa trên phân hoạch - Quick Sort

Trang 41

Sắp xếp dựa trên phân hoạch (tt)

Giải thuật sắp xếp : Cho dãy aL, aL + 1, …, aR :

Trang 42

Sắp xếp dựa trên phân hoạch (tt)

Giải thuật phân hoạch:

(Phân hoạch dãy aL, aL + 1, …, aR thành 2 dãy con)

B1 : Chọn tùy ý một phần tử a[k] trong dãy là giá trị mốc , LkR :

x = a[k]; i = L; j = R ; B2 : Phát hiện và hiệu chỉnh cặp phần tử a[i], a[j] nằm sai chỗ

B2.1 : Trong khi (a[i] < x) i++ ;

B2.2: Trong khi (a[j] > x) j ;

B2.3 : Nếu (i < j) Hoán vị a[i] và a[j] ;

B3 :

Nếu i < j : lặp lại bước 2.

Ngược lại : Dừng phân hoạch.

Trang 43

void QuickSort ( int a[], int l, int r)

Trang 44

• Hiệu quả phụ thuộc vào việc chọn giá trị mốc:

• Trường hợp tốt nhất: mỗi lần phân hoạch đều chọn phần tử

median làm mốc → dãy được chia thành 2 phần bằng nhau → log2(n) lần phân hoạch thì sắp xếp xong

• Nếu mỗi lần phân hoạch chọn phần tử có giá trị cực đại (hay cực tiểu) là mốc → dãy sẽ bị phân chia thành 2 phần không

Trang 45

5 Sắp xếp dựa trên phân hoạch (tt)

• Ví dụ : Cho dãy số a : N = 8 ;

Trang 46

5 Sắp xếp dựa trên phân hoạch (tt)

Trang 47

5 Sắp xếp dựa trên phân hoạch (tt)

Trang 48

Giải thuật Trộn trực tiếp - Merge Sort

• Ý tưởng :

Để sắp xếp dãy a 1 , a 2 , , a n , giải thuật trộn trực tiếp

dựa trên nhận xét sau :

– Mỗi dãy a 1 , a 2 , , a n bất kỳ đều có thể coi như là một tập hợp các dãy con liên tiếp mà mỗi dãy con đều đã có thứ tự Ví dụ dãy 12, 2, 8, 5, 1, 6, 4, 15

có thể coi như gồm 5 dãy con không giảm (12); (2, 8); (5); (1, 6); (4, 15)

– Dãy đã có thứ tự coi như có 1 dãy con

Trang 49

▪ Cách tiếp cận để sắp xếp dãy là tìm cách làm giảm số dãy con không giảm của nó => Phân hoạch dãy ban đầu thành các dãy con

▪ Sau khi phân hoạch xong , dãy ban đầu sẽ được tách ra

thành 2 dãy phụ theo nguyên tắc phân phối đều 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 , ta sẽ nhận lại dãy ban đầu nhưng với số lượng dãy con ít nhất giảm đi một nửa

▪ Lặp lại quá trình trên sau một số bước, ta sẽ nhận được một dãy gồm 1 dãy con không giảm Nghĩa là dãy ban đầu

Giải thuật Trộn trực tiếp - Merge Sort (tt)

Trang 50

▪ Giải thuật trộn là phương pháp đơn giản nhất

Việc phân hoạch thành các dãy con đơn giản là tách dãy gồm n phần tử thành n dãy con Cứ mỗi lần tách rồi trộn, chiều dài của các dãy con

sẽ được nhân đôi.

Giải thuật Trộn trực tiếp - Merge Sort (tt)

Trang 51

Nếu k < n thì trở lại bước 2.

Giải thuật Trộn trực tiếp - Merge Sort (tt)

Trang 52

• Cho dãy số a : N = 8 ;

Ví dụ mô phỏng giải thuật Merge Sort

Trang 53

Ví dụ mô phỏng giải thuật Merge Sort (tt)

Trang 54

void MergeSort (int a[], int N)

 int pa, pb, pc; // các chỉ số trên các mảng a,b,c

int i, k = 1; // độ dài của dãy con khi phân hoạch

int b [N], c[N]; // hai mảng phụ

do  // tách a thành b và c

pa = pb = pc = 0;

while (pa < N)

 for (i = 0 ; (pa < N) && (i < k) ; i++) b [pb++] = a [pa++];

for (i = 0 ; (pa < N) && (i < k) ; i ++) c [pc++] = a [pa++]

 Merge (a, b, c, pb, pc, k); // trộn b, c lại thành a

k * = 2;

 while (k < N);

Cài đặt giải thuật Merge Sort

Trang 55

void Merge ( int a [], int b [], int c [], int nb, int nc, int k)

 int pa, pb, pc, ib, ic, kb, kc;

Trang 57

• Số lần lặp của bước 2 và bước 3 là log2n do sau mỗi lần lặp giá trị của k tăng lên gấp đôi.

• Chi phí thực hiện của giải thuật trộn là nlog2n

• Do không sử dụng thông tin nào về đặc tính của dãy cần sắp xếp, nên trong mọi trường hợp của thuật

toán chi phí là không đổi Đây chính là một trong

những nhược điểm lớn của thuật toán

Đánh giá giải thuật Merge Sort

Trang 58

So sánh các phương pháp sắp xếp

Trang 59

Bài tập thực hành

• Bài 1: Cho dãy số dùng mảng lưu trữ Viết chương trình

sắp xếp bằng phương pháp chọn trực tiếp (Selection

Sort) In ra dãy số trước khi sắp và sau khi sắp.

• Bài 2: Cho dãy số dùng mảng lưu trữ Viết chương trình

sắp xếp bằng phương pháp chèn trực tiếp (Insertion

Sort) In ra dãy số trước khi sắp và sau khi sắp.

• Bài 3: Cho dãy số dùng mảng lưu trữ Viết chương trình

sắp xếp bằng phương pháp đổi chổ trực tiếp

(Interchange Sort) In ra dãy số trước khi sắp và sau khi sắp.

Trang 60

Bài tập thực hành (tt)

• Bài 4: Cho dãy số dùng mảng lưu trữ Viết chương

trình sắp xếp bằng phương pháp nổi bọt (Bubble

Sort) In ra dãy số trước khi sắp và sau khi sắp

• Bài 5: Cho dãy số dùng mảng lưu trữ Viết chương

trình sắp xếp bằng phương pháp theo nguyên tắc trộn(Merge Sort) In ra dãy số trước khi sắp và sau khi sắp

• Bài 6: Cho dãy số dùng mảng lưu trữ Viết chương

trình sắp xếp bằng phương pháp hiệu quả cao (Quick Sort) In ra dãy số trước khi sắp và sau khi sắp

Ngày đăng: 21/05/2021, 14:08

🧩 Sản phẩm bạn có thể quan tâm