Bài giảng Cấu trúc dữ liệu và giải thuật: Chương 3 - Th.S Thiều Quang Trung

20 10 0
Bài giảng Cấu trúc dữ liệu và giải thuật: Chương 3 - Th.S Thiều Quang Trung

Đ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

Ý 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ế. [r]

(1)

CHƯƠNG

CÁC THUẬT TOÁN SẮP XẾP

(2)

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

1

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

2

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

3

• Nổi bọt - Bubble Sort

4

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

5

• Trộn trực tiếp - Merge Sort

6

(3)

Các khái niệm

Sắp xếp ?

– Sắp xếp trình xử lý danh sách phần tử (hoặc mẫu tin) để đặt chúng theo thứ tự thỏa mãn tiêu chuẩn đó

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

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

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

(4)

Các khái niệm

• Để xếp mảng => tìm cách giảm số nghịch mảng cách hoán vị các cặp phần tử

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

Ví dụ: int a[N];

(5)

Ý tưởng: thực N-1 lần việc đưa phần tử nhỏ nhất dãy hành vị trí đứng đầu dãy

• Nhận xét: mảng có thứ tự phần tử ai là (ai,ai+1, ,an-1) => Ý tưởng thuật toán chọn trực tiếp:

– Chọn phần tử nhỏ N phần tử ban đầu, đưa phần tử vị trí đứng đầu dãy hành;

– Sau khơng quan tâm phần tử nữa, xem dãy hành N-1 phần tử dãy ban đầu, vị trí thứ 2;

– Lặp lại q trình cho dãy hành … dãy hành phần tử

(6)

Giải thuật : B1: i = 0;

B2: Tìm phần tử a[min] nhỏ dãy hành từ a[i] đến a[n]

B3: if (min ≠ i) : hoán vị a[min] a[i]

B4: if (i≤ (n-1):

B4.1: i++

B4.2: Lặp lại B2

Ngược lại : dừng // vì n-1 phần tử nằm vị trí

(7)(8)(9)

void SelectionSort(int a[],int n ) {

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

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

min = i;

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

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

= j; // ghi nhận vị trí phần tử nhỏ nhất

if (min != i)

Swap(a[min], a[i]);

} }

(10)

• Ở lượt thứ I, cần (n-i) lần so sánh để tìm phần tử nhỏ hành Số lượng phép so sánh khơng phụ thuộc vào tình trạng dãy ban đầu

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

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

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

Xấu

0 Tốt

Số phép gán Số lần so sánh

Trường hợp

2 ) (nn

2 ) (nn

2 ) (

3n n

(11)

Ý tưởng:

• Giả sử dãy {a0,a1,…an-1} có k phần tử

{a0,a1,…ak-1} có thứ tự

• Chèn phần tử ak vào k phần tử có

thứ tự cách tìm vị trí phần tử k theo giải thuật tìm (Sequential Search)

 có dãy {a0,a1,…,ak-1,ak} có thứ tự

• Vị trí cần chèn ak phần tử ai-1 ai

sao cho ai-1 ≤ ak+1 ≤ ai

(12)

Thuật toán:

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

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

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

B4: apos = x; // đoạn a0 … ak

B5: k = k+1

Nếu i<= n: lặp lại B2 Ngược lại : dừng

(13)

Ví dụ mơ chèn trực tiếp • Cho dãy số a : N = ;

(14)(15)

void InsertionSort (int a [ ], int n) { int k=0, i;

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

while (k<n)

{ int x=a[k+1]; i=k;

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

{ a[i+1] = a[i];

i ;

}

a[i+1]=x;

k++;

} return;

(16)

• Trường hợp tốt nhất: mảng a ban đầu có thứ tự tăng

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

– Số phép so sánh: Smin = 1+2+…+ (n-1) = n*(n-1)/2

• Trường hợp xấu nhất: mảng a ban đầu ln có phần tử nhỏ n-k phần tử còn lại

– 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 thuật toán: O(n2)

(17)

Ý tưởng:

• Phương pháp chèn nhị phân tương tự phương pháp chèn trực tiếp

• Tuy nhiên, thực tìm kiếm vị trí i cho phần tử ai để chèn vào đoạn {a0,a1,…,ai-1} có thể dùng phương pháp tìm kiếm nhị phân (Binary Search) thay cho tìm kiếm (Sequential Search)

(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

}

(19)

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

• Vì việc cải tiến không đáng kể  Độ phức tạp thuật toán O(n2)

(20)

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

Ý tưởng :

Ngày đăng: 11/03/2021, 13:19

Tài liệu cùng người dùng

Tài liệu liên quan