119
Trần Minh Thái Email: [email protected] Website: www.minhthai.edu.vn 1 Chương 2.2. Giải thuật sắp xếp

Chuong2 2 Sapxep 2853

Embed Size (px)

DESCRIPTION

sdasdfsdfs f

Citation preview

Page 1: Chuong2 2 Sapxep 2853

Trần Minh Thái

Email: [email protected]

Website: www.minhthai.edu.vn

1

Chương 2.2. Giải thuật sắp xếp

Page 2: Chuong2 2 Sapxep 2853

Mục tiêu

Nắm vững, minh họa và tính toán được các

phép gán (hoán vị) các giải thuật sắp xếp cơ

bản trên mảng một chiều

Cài đặt được các giải thuật bằng ngôn ngữ

C/C++

2

Page 3: Chuong2 2 Sapxep 2853

Các khái niệm

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 đó dựa trên nội dung thông tin lưu giữ tại mỗi phần tử.

Khái niệm nghịch thế

Giả sử xét mảng có thứ tự tăng dần, nếu có i<j và ai>aj thì ta gọi đó là nghịch thế.

Mục tiêu của sắp xếp là khử các nghịch thế (bằng cách hoán vị)

3

a1 a2 a3 a4 … … aN-2 aN-1 aN

Page 4: Chuong2 2 Sapxep 2853

Các giải thuật sắp xếp cơ bản

Đổi chổ trực tiếp – Interchange Sort Chọn trực tiếp – Selection Sort Chèn trực tiếp – Insertion Sort Nổi bọt – Bubble Sort Quick Sort Một số giải thuật khác đọc thêm trong tài liệu

4

Page 5: Chuong2 2 Sapxep 2853

Đổ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 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. 5

Page 6: Chuong2 2 Sapxep 2853

1 2 3 4 5 6 7 8

Đổi chổ trực tiếp – interchange sort

6

105 7 3

92

15

1

Giả sử cần sắp xếp dãy số sau tăng dần

Page 7: Chuong2 2 Sapxep 2853

1 2 3 4 5 6 7 8

Đổi chổ trực tiếp – interchange sort

7

Bước 1: Xét phần tử đầu tiên (tại vị trí 1)

i

7 39

2

15

1

j

105

Page 8: Chuong2 2 Sapxep 2853

1 2 3 4 5 6 7 8

Đổi chổ trực tiếp – interchange sort

8

Bước 1: Xét phần tử đầu tiên (tại vị trí 1)

10

i

39

2

15

1

j

5 7

Page 9: Chuong2 2 Sapxep 2853

1 2 3 4 5 6 7 8

Đổi chổ trực tiếp – interchange sort

9

Bước 1: Xét phần tử đầu tiên (tại vị trí 1)

10

i

7 92

15

1

j

5 3

Page 10: Chuong2 2 Sapxep 2853

1 2 3 4 5 6 7 8

Đổi chổ trực tiếp – interchange sort

10

Bước 1: Xét phần tử đầu tiên (tại vị trí 1)

10

i

572

15

1

j

39

Page 11: Chuong2 2 Sapxep 2853

1 2 3 4 5 6 7 8

Đổi chổ trực tiếp – interchange sort

11

Bước 1: Xét phần tử đầu tiên (tại vị trí 1)

10

i

57 915

1

j

3 2

Page 12: Chuong2 2 Sapxep 2853

1 2 3 4 5 6 7 8

Đổi chổ trực tiếp – interchange sort

12

Bước 1: Xét phần tử đầu tiên (tại vị trí 1)

10

i

57 39

1

j

2

15

Page 13: Chuong2 2 Sapxep 2853

1 2 3 4 5 6 7 8

Đổi chổ trực tiếp – interchange sort

13

Bước 1: Xét phần tử đầu tiên (tại vị trí 1)

10

i

57 39

j

2

15

1

Page 14: Chuong2 2 Sapxep 2853

1 2 3 4 5 6 7 8

Đổi chổ trực tiếp – interchange sort

14

Bước 1: Xét phần tử đầu tiên (tại vị trí 1)

10

i

57 39

2

15

1

j

1

Kết thúc bước 1

Page 15: Chuong2 2 Sapxep 2853

1 2 3 4 5 6 7 8

Đổi chổ trực tiếp – interchange sort

15

Bước 2: Xét phần tử thứ hai (tại vị trí 2)

i

5 39

2

15

1

j

110

7

Page 16: Chuong2 2 Sapxep 2853

1 2 3 4 5 6 7 8

Đổi chổ trực tiếp – interchange sort

16

Bước 2: Xét phần tử thứ hai (tại vị trí 2)

10

i

39

2

15

1

j

1 57

Page 17: Chuong2 2 Sapxep 2853

1 2 3 4 5 6 7 8

Đổi chổ trực tiếp – interchange sort

17

Bước 2: Xét phần tử thứ hai (tại vị trí 2)

10

i

7 3 2

15

1

j

1 59

Page 18: Chuong2 2 Sapxep 2853

1 2 3 4 5 6 7 8

Đổi chổ trực tiếp – interchange sort

18

Bước 2: Xét phần tử thứ hai (tại vị trí 2)

10

i

7 92

15

1

j

1 5 3

Page 19: Chuong2 2 Sapxep 2853

1 2 3 4 5 6 7 8

Đổi chổ trực tiếp – interchange sort

19

Bước 2: Xét phần tử thứ hai (tại vị trí 2)

10

i

57 921

j

1 3

15

Page 20: Chuong2 2 Sapxep 2853

1 2 3 4 5 6 7 8

Đổi chổ trực tiếp – interchange sort

20

Bước 2: Xét phần tử thứ hai (tại vị trí 2)

10

i

57 915

1

j

1 3 2

Page 21: Chuong2 2 Sapxep 2853

1 2 3 4 5 6 7 8

Đổi chổ trực tiếp – interchange sort

21

Bước 2: Xét phần tử thứ hai (tại vị trí 2)

10

i

57 39

2

15

1

j

1

Kết thúc bước 2

2

Page 22: Chuong2 2 Sapxep 2853

1 2 3 4 5 6 7 8

Đổi chổ trực tiếp – interchange sort

22

Bước 3: Xét phần tử thứ ba (tại vị trí 3)

i

5 39

2

15

1

j

1 210

7

Page 23: Chuong2 2 Sapxep 2853

1 2 3 4 5 6 7 8

Đổi chổ trực tiếp – interchange sort

23

10

i

5 32

15

1

j

1 2

Bước 3: Xét phần tử thứ ba (tại vị trí 3)

7 9

Page 24: Chuong2 2 Sapxep 2853

1 2 3 4 5 6 7 8

Đổi chổ trực tiếp – interchange sort

24

10

i

39

2

15

1

j

1 2

Bước 3: Xét phần tử thứ ba (tại vị trí 3)

57

Page 25: Chuong2 2 Sapxep 2853

1 2 3 4 5 6 7 8

Đổi chổ trực tiếp – interchange sort

25

10

i

7 39

21

j

1 2

Bước 3: Xét phần tử thứ ba (tại vị trí 3)

5

15

Page 26: Chuong2 2 Sapxep 2853

1 2 3 4 5 6 7 8

Đổi chổ trực tiếp – interchange sort

26

10

i

792

15

1

j

1 2

Bước 3: Xét phần tử thứ ba (tại vị trí 3)

5 3

Page 27: Chuong2 2 Sapxep 2853

1 2 3 4 5 6 7 8

Đổi chổ trực tiếp – interchange sort

27

10

i

5739

2

15

1

j

1 2

Bước 3: Xét phần tử thứ ba (tại vị trí 3)

Kết thúc bước 3

3

Page 28: Chuong2 2 Sapxep 2853

1 2 3 4 5 6 7 8

Đổi chổ trực tiếp – interchange sort

28

i

5732

15

1

j

1 2

Bước 4: Xét phần tử thứ tư (tại vị trí 4)

310 9

Page 29: Chuong2 2 Sapxep 2853

1 2 3 4 5 6 7 8

Đổi chổ trực tiếp – interchange sort

29

10

i

532

15

1

j

1 2

Bước 4: Xét phần tử thứ tư (tại vị trí 4)

3 79

Page 30: Chuong2 2 Sapxep 2853

1 2 3 4 5 6 7 8

Đổi chổ trực tiếp – interchange sort

30

10

i

539

21

j

1 2

Bước 4: Xét phần tử thứ tư (tại vị trí 4)

3 715

Page 31: Chuong2 2 Sapxep 2853

1 2 3 4 5 6 7 8

Đổi chổ trực tiếp – interchange sort

31

10

i

39

2

15

1

j

1 2

Bước 4: Xét phần tử thứ tư (tại vị trí 4)

3 57

Page 32: Chuong2 2 Sapxep 2853

1 2 3 4 5 6 7 8

Đổi chổ trực tiếp – interchange sort

32

10

i

5 739

2

15

1

j

1 2

Bước 4: Xét phần tử thứ tư (tại vị trí 4)

3

Kết thúc bước 4

5

Page 33: Chuong2 2 Sapxep 2853

1 2 3 4 5 6 7 8

Đổi chổ trực tiếp – interchange sort

33

i

5 732

15

1

j

1 2

Bước 5: Xét phần tử thứ năm (tại vị trí 5)

3 510 9

Page 34: Chuong2 2 Sapxep 2853

1 2 3 4 5 6 7 8

Đổi chổ trực tiếp – interchange sort

34

10

i

5321

j

1 2 3 5

Bước 5: Xét phần tử thứ năm (tại vị trí 5)

1579

Page 35: Chuong2 2 Sapxep 2853

1 2 3 4 5 6 7 8

Đổi chổ trực tiếp – interchange sort

35

10

i

532

15

1

j

1 2 3 5

Bước 5: Xét phần tử thứ năm (tại vị trí 5)

79

Page 36: Chuong2 2 Sapxep 2853

1 2 3 4 5 6 7 8

Đổi chổ trực tiếp – interchange sort

36

10

i

5 739

2

15

1

j

1 2 3 5

Kết thúc bước 5

Bước 5: Xét phần tử thứ năm (tại vị trí 5)

7

Page 37: Chuong2 2 Sapxep 2853

1 2 3 4 5 6 7 8

Đổi chổ trực tiếp – interchange sort

37

i

5 739

21

j

1 2 3 5

Bước 6: Xét phần tử thứ sáu (tại vị trí 6)

710

15

Page 38: Chuong2 2 Sapxep 2853

1 2 3 4 5 6 7 8

Đổi chổ trực tiếp – interchange sort

38

i

5 732

15

1

j

1 2 3 5

Bước 6: Xét phần tử thứ sáu (tại vị trí 6)

710 9

Page 39: Chuong2 2 Sapxep 2853

1 2 3 4 5 6 7 8

Đổi chổ trực tiếp – interchange sort

39

10

i

5 739

2

15

1

j

1 2 3 5

Bước 6: Xét phần tử thứ sáu (tại vị trí 6)

7

Kết thúc bước 6

9

Page 40: Chuong2 2 Sapxep 2853

1 2 3 4 5 6 7 8

Đổi chổ trực tiếp – interchange sort

40

i

5 739

21

j

1 2 3 5

Bước 7: Xét phần tử thứ bảy (tại vị trí 7)

7 9 1015

Page 41: Chuong2 2 Sapxep 2853

1 2 3 4 5 6 7 8

Đổi chổ trực tiếp – interchange sort

41

10

i

5 739

2

15

1

j

1 2 3 5

Bước 7: Xét phần tử thứ bảy (tại vị trí 7)

7 9

Kết thúc bước 7

10

Page 42: Chuong2 2 Sapxep 2853

1 2 3 4 5 6 7 8

Đổi chổ trực tiếp – interchange sort

42

105 73

92

15

11 2 3 5

Hoàn tất sắp xếp

7 9 10

Page 43: Chuong2 2 Sapxep 2853

Giải thuật Bước 1 : i = 1;// bắt đầu từ đầu dãy Bước 2 : j = i+1;//tìm các phần tử a[j] < a[i], j>i Bước 3 :

Trong khi j <= N thực hiện Nếu a[j]<a[i]: Hoán vị a[i], a[j];

j = j+1; Bước 4 : i = i+1;

Nếu i < N: Lặp lại Bước 2. Ngược lại: Dừng.

43

Page 44: Chuong2 2 Sapxep 2853

Cài đặtvoid InterchangeSort(int a[], int N ){

int i, j;for (i = 0 ; i<N-1 ; i++){

for (j =i+1; j < N ; j++)if(a[j ]< a[i])

HoanVi(a[i],a[j]);}

}void HoanVi(int &a, int &b){

int tam=a;a=b;b=tam;

} 44

Page 45: Chuong2 2 Sapxep 2853

Bài tập

Minh họa từng bước thực hiện của giải thuật Interchange Sort khi sắp dãy số sau tăng dần:

Cho biết tổng số phép hoán vị

45

15 7 9 10 6 20

1 2 3 4 5 6

Page 46: Chuong2 2 Sapxep 2853

Ðánh giá giải thuậ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, nhưng số lượng phép hoán vị thực hiện tùy thuộc vào kết quả so sánh, có thể ước lượng trong từng trường hợp như sau:

46

Page 47: Chuong2 2 Sapxep 2853

Chọn trực tiếp – selection sort

Ý tưởng:

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 là đầu dãy hiện

hành; lúc này dãy hiện hành chỉ còn N-1 phần tử

cần sắp xếp, bắt đầu từ vị trí thứ 2; lặp lại quá

trình trên cho dãy hiện hành... đến khi dãy hiện

hành chỉ còn 1 phần tử47

Page 48: Chuong2 2 Sapxep 2853

Chọn trực tiếp – selection sort

48

Làm sao để xác định được vị trí phần

tử có giá trị nhỏ nhất trong một dãy gồm N phần tử?

?

Page 49: Chuong2 2 Sapxep 2853

1 2 3 4 5 6 7 8

Chọn trực tiếp – selection sortTìm vị trí phần tử nhỏ nhất?

49

105 7 3

92

15

1

Giả sử cần tìm vị trí phần tử nhỏ nhất trong dãy số sau ?

Page 50: Chuong2 2 Sapxep 2853

1 2 3 4 5 6 7 8

Chọn trực tiếp – selection sortTìm vị trí phần tử nhỏ nhất?

50

105 7 3

92

15

1

Bước 1: Giả sử vị trí phần tử nhỏ nhất là 1 (vtmin), phần tử này có giá trị 10

vtmin

Page 51: Chuong2 2 Sapxep 2853

1 2 3 4 5 6 7 8

Chọn trực tiếp – selection sortTìm vị trí phần tử nhỏ nhất?

51

5 7 39

2

15

1

Bước 2: So sánh giá trị tại vtmin với tất cả giá trị tại vị trí còn lại (từ 2 đến 8), nếu có phần tử nào nhỏ hơn phần tử tại vtmin thì cập nhật lại vtmin vtmin

5 nhỏ hơn 10 nên cập nhật

vị trí min

10

Page 52: Chuong2 2 Sapxep 2853

1 2 3 4 5 6 7 8

Chọn trực tiếp – selection sortTìm vị trí phần tử nhỏ nhất?

52

39

2

15

1

Bước 2: So sánh giá trị tại vtmin với tất cả giá trị tại vị trí còn lại (từ 2 đến 8), nếu có phần tử nào nhỏ hơn phần tử tại vtmin thì cập nhật lại vtmin vtmin

7 lớn hơn 5 nên không cập nhật vị trí min

105 7

Page 53: Chuong2 2 Sapxep 2853

1 2 3 4 5 6 7 8

Chọn trực tiếp – selection sortTìm vị trí phần tử nhỏ nhất?

53

39

2

15

1

Bước 2: So sánh giá trị tại vtmin với tất cả giá trị tại vị trí còn lại (từ 2 đến 8), nếu có phần tử nào nhỏ hơn phần tử tại vtmin thì cập nhật lại vtmin vtmin

3 nhỏ hơn 5 nên cập nhật

vị trí min

105 7

Page 54: Chuong2 2 Sapxep 2853

1 2 3 4 5 6 7 8

Chọn trực tiếp – selection sortTìm vị trí phần tử nhỏ nhất?

54

39

2

15

1

Bước 2: So sánh giá trị tại vtmin với tất cả giá trị tại vị trí còn lại (từ 2 đến 8), nếu có phần tử nào nhỏ hơn phần tử tại vtmin thì cập nhật lại vtmin vtmin

9 lớn hơn 3 nên không cập nhật vị trí min

105 7

Page 55: Chuong2 2 Sapxep 2853

1 2 3 4 5 6 7 8

Chọn trực tiếp – selection sortTìm vị trí phần tử nhỏ nhất?

55

92

15

Bước 2: So sánh giá trị tại vtmin với tất cả giá trị tại vị trí còn lại (từ 2 đến 8), nếu có phần tử nào nhỏ hơn phần tử tại vtmin thì cập nhật lại vtmin vtmin

1 nhỏ hơn 3 nên cập nhật

vị trí min

105 7 3 1

Page 56: Chuong2 2 Sapxep 2853

1 2 3 4 5 6 7 8

Chọn trực tiếp – selection sortTìm vị trí phần tử nhỏ nhất?

56

92

Bước 2: So sánh giá trị tại vtmin với tất cả giá trị tại vị trí còn lại (từ 2 đến 8), nếu có phần tử nào nhỏ hơn phần tử tại vtmin thì cập nhật lại vtmin vtmin

15 lớn hơn 1 nên không cập nhật vị trí min

105 7 3

15

1

Page 57: Chuong2 2 Sapxep 2853

1 2 3 4 5 6 7 8

Chọn trực tiếp – selection sortTìm vị trí phần tử nhỏ nhất?

57

9

Bước 2: So sánh giá trị tại vtmin với tất cả giá trị tại vị trí còn lại (từ 2 đến 8), nếu có phần tử nào nhỏ hơn phần tử tại vtmin thì cập nhật lại vtmin vtmin

105 7 3

15

2 lớn hơn 1 nên không cập nhật vị trí min

21

Page 58: Chuong2 2 Sapxep 2853

Chọn trực tiếp – selection sortTìm vị trí phần tử nhỏ nhất?

58

Hãy cài đặt hàm tìm và trả về vị trí

của phần tử nhỏ nhất bằng ngôn ngữ C, đầu vào là mảng số nguyên a, kích thước N?

?

Page 59: Chuong2 2 Sapxep 2853

Chọn trực tiếp – selection sortTìm vị trí phần tử nhỏ nhất?

59

Giả sử cần tìm vị trí phần tử nhỏ nhất bắt đầu từ vị trí k cho trước (ví dụ đoạn

từ 3 đến 8) thì giải quyết như thế nào? Hãy viết hàm cài đặt bằng ngôn ngữ C?

?

1 2 3 4 5 6 7 8

10

17 3

92

158

Page 60: Chuong2 2 Sapxep 2853

1 2 3 4 5 6 7 8

Chọn trực tiếp – selection sort

60

105 7 3

92

15

1

Giả sử cần sắp xếp dãy số sau tăng dần

Page 61: Chuong2 2 Sapxep 2853

1 2 3 4 5 6 7 8

Chọn trực tiếp – selection sort

61

5 7 39

2

15

Bước 1: Xét phần tử thứ nhất (vị trí 1)

i

• Tìm phần tử nhỏ nhất từ vị trí 1 đến 8

min

• Hoán vị 2 phần tử tại vị trí đang xét với vị trí phần tử min

10

1

Page 62: Chuong2 2 Sapxep 2853

1 2 3 4 5 6 7 8

Chọn trực tiếp – selection sort

62

7 39

15

Bước 2: Xét phần tử thứ hai (vị trí 2)

i

• Tìm phần tử nhỏ nhất từ vị trí 2 đến 8

min

• Hoán vị 2 phần tử tại vị trí đang xét với vị trí phần tử min

10

1 5 2

Page 63: Chuong2 2 Sapxep 2853

1 2 3 4 5 6 7 8

Chọn trực tiếp – selection sort

63

915

Bước 3: Xét phần tử thứ ba (vị trí 3)

i

• Tìm phần tử nhỏ nhất từ vị trí 3 đến 8

min

• Hoán vị 2 phần tử tại vị trí đang xét với vị trí phần tử min

10

1 527 3

Page 64: Chuong2 2 Sapxep 2853

1 2 3 4 5 6 7 8

Chọn trực tiếp – selection sort

64

915

Bước 4: Xét phần tử thứ tư (vị trí 4)

i

• Tìm phần tử nhỏ nhất từ vị trí 4 đến 8

min

• Hoán vị 2 phần tử tại vị trí đang xét với vị trí phần tử min

10

1 2 3 57

Page 65: Chuong2 2 Sapxep 2853

1 2 3 4 5 6 7 8

Chọn trực tiếp – selection sort

65

15

Bước 5: Xét phần tử thứ năm (vị trí 5)

i

• Tìm phần tử nhỏ nhất từ vị trí 5 đến 8

min

• Hoán vị 2 phần tử tại vị trí đang xét với vị trí phần tử min

10

1 2 3 59 7

Page 66: Chuong2 2 Sapxep 2853

Bước 6: Xét phần tử thứ sáu (vị trí 6)• Tìm phần tử nhỏ nhất từ vị trí 6 đến 8• Hoán vị 2 phần tử tại vị trí đang xét với vị trí phần tử min

1 2 3 4 5 6 7 8

Chọn trực tiếp – selection sort

66

15

i

min

10

1 2 3 5 7 9

Page 67: Chuong2 2 Sapxep 2853

Bước 7: Xét phần tử thứ bảy (vị trí 7)• Tìm phần tử nhỏ nhất từ vị trí 7 đến 8

1 2 3 4 5 6 7 8

Chọn trực tiếp – selection sort

67

i

min

1 2 3 5 7 9

• Hoán vị 2 phần tử tại vị trí đang xét với vị trí phần tử min

1510

Page 68: Chuong2 2 Sapxep 2853

Kết thúc giải thuật - hoàn tất sắp xếp

1 2 3 4 5 6 7 8

Chọn trực tiếp – selection sort

68

1 2 3 5 7 915

10

Page 69: Chuong2 2 Sapxep 2853

Giải thuậtBước 1:   i = 1; Bước 2: Tìm phần tử a[vtmin] nhỏ nhất trong

dãy hiện hành từ a[i] đến a[N] Bước 3:  Hoán vị a[vtmin] và a[i] Bước 4: i = i+1

Nếu i < N thì lặp lại Bước 2            Ngược lại: Dừng.

69

Page 70: Chuong2 2 Sapxep 2853

Cài đặt 1void SelectionSort(int a[],int N )

{

int vtmin;

for (int i=0; i<N-1 ; i++)

{vtmin = i;

for(int j = i+1; j <N ; j++)

{

if (a[j ] < a[vtmin])

vtmin=j;

}

HoanVi(a[vtmin], a[i]); }

}70

Tìm vị trí min tính từ i đến N-1

Page 71: Chuong2 2 Sapxep 2853

Cài đặt 2int TimVTMin(int a[], int N, int k)

{

int vtmin=k;

for(int i=k+1; i<N; i++)

{

if(a[i]<a[vtmin])

vtmin=i;

}

return vtmin;

}

71

void SelectionSort(int a[],int N )

{

int vtmin;

for (int i=0; i<N-1 ; i++)

{vtmin = TimVTMin(a, N, i);

HoanVi(a[vtmin], a[i]); }

}

Page 72: Chuong2 2 Sapxep 2853

Bài tập

Minh họa từng bước thực hiện của giải thuật Selection Sort khi sắp dãy số sau tăng dần:

Cho biết tổng số phép gán tìm min và tổng số phép hoán vị

72

15 7 9 10 6 201 2 3 4 5 6

Page 73: Chuong2 2 Sapxep 2853

Ðánh giá giải thuật Ðối với giải thuật chọn trực tiếp, có thể thấy rằng ở lượt thứ i, bao giờ cũng cần (n-i) lần so sánh để xác định phần tử nhỏ nhất hiện hành. Số lượng phép so sánh này không phụ thuộc vào tình trạng của dãy số ban đầu, do vậy trong mọi trường hợp có thể kết luận :

73

Page 74: Chuong2 2 Sapxep 2853

Nổi bọt – bubble sort

Ý tưởng:Xuất phát từ cuối dãy, đổi chỗ các cặp phần tử kế cận để đưa phần tử nhỏ hơn trong cặp phần tử đó về vị trí đúng đầu dãy hiện hành, sau đó sẽ không xét đến nó ở bước tiếp theo, do vậy ở 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.

74

Page 75: Chuong2 2 Sapxep 2853

1

2

3

4

5

6

7

875

7

3

9

2

15

1

10

5

i

j

Page 76: Chuong2 2 Sapxep 2853

1

2

3

4

5

6

7

876

7

3

9

2

15

1

10

5

i

j

Page 77: Chuong2 2 Sapxep 2853

1

2

3

4

5

6

7

877

7

3

9

2

15

1

10

5

i

j

Page 78: Chuong2 2 Sapxep 2853

1

2

3

4

5

6

7

878

7

3

9

2

15

1

10

5

i

j

Page 79: Chuong2 2 Sapxep 2853

1

2

3

4

5

6

7

879

7

3

9

2

15

1

10

5i

j

Page 80: Chuong2 2 Sapxep 2853

1

2

3

4

5

6

7

880

7

3

9

2

15

1

10

5

i

j

Page 81: Chuong2 2 Sapxep 2853

1

2

3

4

5

6

7

881

7

3

9

2

15

1

10

5

i

j

Page 82: Chuong2 2 Sapxep 2853

1

2

3

4

5

6

7

882

7

3

9

2

15

1

10

5

i

Kết thúc

Page 83: Chuong2 2 Sapxep 2853

Giải thuậtBước 1:

i = 1;

Bước 2:

j = N;

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

Nếu a[j]<a[j-1]: Hoán vị a[j] và a[j-1]

j = j-1;

Bước 3:

i = i+1;

Nếu i >N-1: Hết dãy. Dừng

Ngược lại: Lặp lại Bước 2.

83

Page 84: Chuong2 2 Sapxep 2853

Cài đặt

void BubleSort(int a[], int N )

{int i, j;for (i = 0 ; i<N-1 ; i++){

for (j =N-1; j >i ; j --){

if(a[j]< a[j-1])HoanVi(a[j],a[j-

1]);}

}

}84

Page 85: Chuong2 2 Sapxep 2853

Đánh giá giải thuật

Trong mọi trường hợp, số phép so sánh là:

(n-1) + (n-2) + … + 1 = n(n-1)/2 = O(n2)

Số phép hoán vị:

Trường hợp xấu nhất: n(n-1)/2

Trường hợp tốt nhất: 0

85

Page 86: Chuong2 2 Sapxep 2853

Các giải thuật sắp xếp cơ bản

Đổi chổ trực tiếp – Interchange Sort Chọn trực tiếp – Selection Sort Nổi bọt – Bubble Sort Chèn trực tiếp – Insertion Sort Quick Sort

86

Page 87: Chuong2 2 Sapxep 2853

Chèn trực tiếp – insertion sort

Ý tưởng

Cho dãy ban đầu a1 , a2 ,... ,an, ta có thể xem như đã có đoạn gồm một phần tử a1 đã được sắp, sau đó thêm a2 vào đoạn a1 sẽ có đoạn a1 a2 được sắp; tiếp tục thêm a3 vào đoạn a1 a2 để có đoạn a1 a2 a3 được sắp; tiếp tục cho đến khi thêm xong aN vào đoạn a1 a2 ...aN-1 sẽ có dãy a1 a2 .... aN

được sắp.

87

Page 88: Chuong2 2 Sapxep 2853

1 2 3 4 5 6 7 8

Chèn trực tiếp – insertion sort

88

105 7 3

92

15

1

Giả sử cần sắp xếp dãy số sau tăng dần

Page 89: Chuong2 2 Sapxep 2853

1 2 3 4 5 6 7 8

Chèn trực tiếp – insertion sort

89

105 7 3

92

15

1

Xem như phần tử thứ 1 đã có thứ tựTìm vị trí thích hợp để chèn cho phần tử thứ 2

Page 90: Chuong2 2 Sapxep 2853

1 2 3 4 5 6 7 8

Chèn trực tiếp – insertion sort

90

7 39

2

15

1

Hai phần tử đầu tiên đã có thứ tựTìm vị trí thích hợp để chèn cho phần tử thứ 3

105

Page 91: Chuong2 2 Sapxep 2853

1 2 3 4 5 6 7 8

Chèn trực tiếp – insertion sort

91

39

2

15

1

Ba phần tử đầu tiên đã có thứ tựTìm vị trí thích hợp để chèn cho phần tử thứ 4

710

5

Page 92: Chuong2 2 Sapxep 2853

1 2 3 4 5 6 7 8

Chèn trực tiếp – insertion sort

92

92

15

1

Bốn phần tử đầu tiên đã có thứ tựTìm vị trí thích hợp để chèn cho phần tử thứ 5

3 710

5

Page 93: Chuong2 2 Sapxep 2853

1 2 3 4 5 6 7 8

Chèn trực tiếp – insertion sort

93

2

15

1

Năm phần tử đầu tiên đã có thứ tựTìm vị trí thích hợp để chèn cho phần tử thứ 6

93 7

105

Page 94: Chuong2 2 Sapxep 2853

1 2 3 4 5 6 7 8

Chèn trực tiếp – insertion sort

94

15

1

Sáu phần tử đầu tiên đã có thứ tựTìm vị trí thích hợp để chèn cho phần tử thứ 7

29

3 710

5

Page 95: Chuong2 2 Sapxep 2853

1 2 3 4 5 6 7 8

Chèn trực tiếp – insertion sort

95

15

Bảy phần tử đầu tiên đã có thứ tựTìm vị trí thích hợp để chèn cho phần tử thứ 8

29

3 710

5 1

Page 96: Chuong2 2 Sapxep 2853

1 2 3 4 5 6 7 8

Chèn trực tiếp – insertion sort

96

15

Kết thúc giải thuật

29

3 710

51

Page 97: Chuong2 2 Sapxep 2853

Chèn trực tiếp – insertion sort

97

Dựa vào đâu để xác định được vị trí chèn thích hợp của một giá trị

trong dãy có giá trị tăng dần?Hãy viết hàm chèn x vào dãy a tăng dần sao cho dãy a thu được cũng tăng dần

?

Page 98: Chuong2 2 Sapxep 2853

Giải thuậtBước 1: i = 2; // giả sử có đoạn a[1] đã được sắp Bước 2: x = a[i]; Tìm vị trí pos thích hợp trong đoạn [1..i-1] để chèn a[i]

vào Bước 3: Dời chỗ các phần tử từ pos đến i-1 sang phải 1 vị

trí để dành chỗ cho a[i] Bước 4: a[pos] = x; // có đoạn a[1]..a[i] đã được sắp Bước 5: i = i+1;

Nếu i ≤ N : Lặp lại Bước 2. Ngược lại : Dừng.

98

Page 99: Chuong2 2 Sapxep 2853

void InsertionSort(int a[], int N )

{

int pos;int x; for(int i=1 ; i<N ; i++) //đoạn a[0] đã sắp{

x = a[i]; pos = i-1;while((pos >= 0)&&(a[pos] > x)){

a[pos+1] = a[pos]; pos--;}a[pos+1] = x;// chèn x vào dãy

}

} 99

Page 100: Chuong2 2 Sapxep 2853

Bài tập

Minh họa từng bước thực hiện của giải thuật Insertion Sort khi sắp dãy số sau tăng dần:

Cho biết tổng số gán và số phép so sánh

100

15 7 9 10 6 201 2 3 4 5 6

Page 101: Chuong2 2 Sapxep 2853

Đánh giá giải thuật

Các phép so sánh xảy ra trong mỗi vòng lặp while tìm vị trí thích hợp pos, và mỗi lần xác định vị trí đang xét không thích hợp, sẽ dời chỗ phần tử a[pos] tương ứng. Giải thuật thực hiện tất cả N-1 vòng lặp while, do số lượng phép so sánh và dời chỗ này phụ thuộc vào tình trạng của dãy số ban đầu, nên chỉ có thể ước lượng trong từng trường hợp như sau:

101

Page 102: Chuong2 2 Sapxep 2853

Kết luận

“Chèn trực tiếp” và “Chọn trực tiếp” đều có chi

phí cho trường hợp xấu nhất là O(n2) do đó,

không thích hợp cho việc sắp xếp các mảng lớn

Dễ cài đặt, dễ kiểm lỗi

“Chèn trực tiếp” tốt hơn “Chọn trực tiếp”, nhất

là khi mảng đã có thứ tự sẵn

Cần có những giải thuật hiệu quả hơn cho việc

sắp xếp các mảng lớn102

Page 103: Chuong2 2 Sapxep 2853

Các giải thuật sắp xếp cơ bản

Đổi chỗ trực tiếp – Interchange Sort Chọn trực tiếp – Selection Sort Nổi bọt – Bubble Sort Chèn trực tiếp – Insertion Sort Quick Sort

103

Page 104: Chuong2 2 Sapxep 2853

Quick sort

Chia dãy cần sắp thành 2 phần Cách “chia”: ½ dãy bên trái chứa các giá trị

nhỏ hơn ½ dãy bên phải Thực hiện việc sắp xếp trên từng dãy con (đệ

qui)

(x là phần tử trong dãy)

104

<x x >x

Page 105: Chuong2 2 Sapxep 2853

VD: 3; 5; 8; 10; 31; 4; 81; 7; 15; 17; 1. Giả sữ x = 10 thì sẽ có 2 phần như sau: Phần nhỏ hơn x: 3; 5; 8; 4; 7; 1 Phần lớn hơn x: 31; 81; 15; 17

105

Quick sort

Page 106: Chuong2 2 Sapxep 2853

1 2 3 4 5 6 7 8

106Đoạn cần sắp xếp

L=1R=8

i j

x

i=1, j=8

L=1R=3

L=4R=8

Đoạn 1 Đoạn 2

L R

7 3 9 2 15 110 5

Page 107: Chuong2 2 Sapxep 2853

1 2 3 4 5 6 7 8

107

i j

x

Đoạn cần sắp xếp

i=4, j=8

L=1R=3

L=4R=8

L=4R=5

L=5R=8

L R

Đoạn 1 Đoạn 2

3 7 9 5 15 101 2

Page 108: Chuong2 2 Sapxep 2853

1 2 3 4 5 6 7 8

108Đoạn cần sắp xếp

i j

i=5, j=8

x

L=1R=4

L=4R=5

L=5R=8

L R

Đoạn 2

L=6R=8

3 5 9 7 15 101 2

Page 109: Chuong2 2 Sapxep 2853

1 2 3 4 5 6 7 8

109Đoạn cần sắp xếp

i j

i=6, j=8

x

L=1R=4

L=4R=5

L R

Đoạn 1

L=6R=8

L=6R=7

3 5 7 9 15 101 2

Page 110: Chuong2 2 Sapxep 2853

1 2 3 4 5 6 7 8

110Đoạn cần sắp xếp

i j

i=6, j=7 x

L=1R=4

L=4R=5

L R

L=6R=7

3 5 7 9 10 151 2

Page 111: Chuong2 2 Sapxep 2853

1 2 3 4 5 6 7 8

111Đoạn cần sắp xếp

i j

i=4, j=5 x

L=1R=4

L=4R=5

L R

3 5 7 9 10 151 2

Page 112: Chuong2 2 Sapxep 2853

1 2 3 4 5 6 7 8

112Đoạn cần sắp xếp

i j

i=1, j=4

x

L=1R=4

L R

3 5 7 9 10 151 2

Đoạn 2

L=3R=4

Page 113: Chuong2 2 Sapxep 2853

1 2 3 4 5 6 7 8

113Đoạn cần sắp xếp

i j

i=3, j=4 x

L=3R=4

L R

3 5 7 9 10 151 2

Page 114: Chuong2 2 Sapxep 2853

1 2 3 4 5 6 7 8

114

3 5 7 9 10 151 2

Đoạn cần sắp xếp

Không còn đoạn nào cần sắp xếp!

Kết thúc

Page 115: Chuong2 2 Sapxep 2853

Giải thuậtCho dãy aL, aL+1, … aR

Bước 1:

Phân hoạch dãy aL … aR thành các dãy con: Dãy con 1: aL … aj < x Dãy con 2: aj+1 … ai-1 =x Dãy con 3: ai … aR > x

Bước 2: Nếu (L<j) Phân hoạch dãy aL … aj

Nếu (i<R) Phân hoạch dãy ai … aR115

Page 116: Chuong2 2 Sapxep 2853

Giải thuật phân hoạch dãy aL, aL+1, … aR thành 2 dãy con

Bước 1.1:

Chọn tùy ý một phần tử a[k] trong dãy, L≤k≤R

x=a[k], i=L, j=R

Bước 1.2:

Phát hiện và hiệu chỉnh cặp a[i] và a[j] nằm sai chỗ:

Bước 1.2a: Trong khi (a[i]<x) i++

Bước 1.2b: Trong khi (a[j]>x) j--

Bước 1.2c: Nếu (i≤j): Hoán vị a[i] và a[j]; i++, j--

Bước 1.3:

Nếu i<j: Lặp lại bước 1.2

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

Page 117: Chuong2 2 Sapxep 2853

Cài đặtvoid QuickSort(int a[], int left, int right)

{ int i, j, x; x=a[(left+right)/2];i=left, j=right;

do{ while(a[i]<x) i++;

while(a[j]>x) j--;

if(i<=j)

{

HoanVi(a[i], a[j]); i++; j--;

}

} while(i<j);

if(left<j) QuickSort(a, left, j);

if(i<right) QuickSort(a, i, right);

}117

Page 118: Chuong2 2 Sapxep 2853

Bài tập

Minh họa từng bước thực hiện của giải thuật Quick Sort khi sắp dãy số sau tăng dần:

118

15 7 9 10 6 20 6 9 12 301 2 3 4 5 6 7 8 9 10

Page 119: Chuong2 2 Sapxep 2853

Đánh giá giải thuật

Chi phí trung bình O(n*log2n) Chi phí cho trường hợp xấu nhất O(n2) Chi phí tùy thuộc vào cách chọn phần tử

“trục”: Nếu chọn được phần tử có giá trị trung bình,

ta sẽ chia thành 2 dãy bằng nhau; Nếu chọn nhằm phần tử nhỏ nhất (hay lớn

nhất) O(n2)

119