BÀI TOÁN SẮP XẾPtrong mảng một chiều, thứ tự sắp xếp là tăng Đầu vào: Dãy n đối tượng, mỗi đối tượng có một khóa sắp xếp Đầu ra: Dãy n đối tượng được sắp xếp theo trật tự của khóa...
Trang 1CHƯƠNG 5
CÁC THUẬT TOÁN SẮP XẾP
Trang 2NỘI DUNG
Trang 3An Bình Hoàng
21 44 52 73 81
Trang 5BÀI TOÁN SẮP XẾP
trong mảng một chiều, thứ tự sắp xếp là tăng
Đầu vào: Dãy n đối tượng, mỗi đối
tượng có một khóa sắp xếp
Đầu ra: Dãy n đối tượng được sắp
xếp theo trật tự của khóa
BÀI
TOÁN
Trang 65.2 CÁC THUẬT TOÁN SẮP XẾP ĐƠN GiẢN
Thuật toán sắp xếp lựa chọn (Selectsort)
Thuật toán sắp xếp chèn (Insertsort)
Thuật toán sắp xếp nổi bọt (Bubblesort)
Trang 7 Ý tưởng thuật toán
Dựa vào thuật toán tìm MAX, MIN
Ở lần duyệt thứ i, với 0<=i<n-1 tìm ra phần
Trang 85.2.1 THUẬT TOÁN SẮP XẾP LỰA CHỌN
Trang 95.2.1 THUẬT TOÁN SẮP XẾP LỰA CHỌN
Trang 10 Ví dụ 2
Cho mảng số nguyên như sau
Yêu cầu: Mô tả quá trình sắp xếp dãy số
5.2.1 THUẬT TOÁN SẮP XẾP LỰA CHỌN
53 -21 67 15 82 -14
Trang 11void chon( int a[], int n )
{ int i, j, tg, m ;
for (i=0; i<n-1; i++)
{ m=i ;
for (j=i+1; j<n; j++)
if (a[j]<a[m]) m=j;
if (m!=i)
{ tg=a[i]; a[i]=a[m]; a[m]=tg; }
}
5.2.1 THUẬT TOÁN SẮP XẾP LỰA CHỌN
Trang 12 Ý tưởng thuật toán
Trang 13 Ý tưởng thuật toán :
Ở lần duyệt thứ i, với 0<i<n đặt phần tử ở vị trí i
vào đúng thứ tự của nó so với i phần tử trước đã được sắp xếp
Sau n-1 lượt dãy được sắp xếp
5.2.2 THUẬT TOÁN SẮP XẾP CHÈN
Trang 14 Ví dụ
Cho mảng a có 5 số nguyên (n=5) như sau
Yêu cầu sắp xếp dãy số theo chiều tăng dần
5.2.2 THUẬT TOÁN SẮP XẾP CHÈN
Trang 15 Xem dãy cần sắp gồm 2 dãy nối tiếp
được sắp, dãy phải (dãy nguồn) là các phần
tử chưa được sắp.
5.2.2 THUẬT TOÁN SẮP XẾP CHÈN
Trang 16 Ý tưởng thuật toán
Lấy phần tử đầu dãy nguồn chèn vào vị trí thích hợp trong dãy đích
Trang 19 Ví dụ 2
Cho mảng số nguyên như sau
Yêu cầu: Mô tả quá trình sắp xếp dãy số theo chiều giảm dần bằng thuật toán chèn
5.2.2 THUẬT TOÁN SẮP XẾP CHÈN
53 -21 67 15 82 -14
Trang 20void chen(int a[], int n)
{ int i, j, tg ;
for (i=1; i<n; i++)
{ j=i-1 ; tg=a[i] ;
while ((j>=0) && (a[j]>tg))
{ a[j+1]=a[j]; j ; }
a[j+1]=tg;
}
}
5.2.2 THUẬT TOÁN SẮP XẾP CHÈN
Trang 215.2.3 THUẬT TOÁN SẮP XẾP NỔI BỌT
Ý tưởng thuật toán :
Ở lần duyệt thứ i, với 0<=i<n-1, xuất phát từ cuối
dãy, so sánh hai phần tử kế tiếp nhau, phần tử nào nhỏ hơn cho đổi lên Phần tử nhỏ nhất sẽ được đổi lên vị trí thứ i
Sau n -1 lượt dãy được sắp xếp
Trang 22 Ví dụ
Cho mảng a có 5 số nguyên (n=5) như sau
Yêu cầu sắp xếp dãy số theo chiều tăng dần
5.2.3 THUẬT TOÁN SẮP XẾP NỔI BỌT
Trang 235.2.3 THUẬT TOÁN SẮP XẾP NỔI BỌT
Trang 245.2.3 THUẬT TOÁN SẮP XẾP NỔI BỌT
Trang 25 Ví dụ 2:
Cho dãy số sau
Yêu cầu: Mô tả quá trình sắp xếp dãy theo
5.2.3 THUẬT TOÁN SẮP XẾP NỔI BỌT
Trang 26void nbot( int a[], int n )
Trang 275.2.3 THUẬT TOÁN SẮP XẾP NỔI BỌT
Trang 285.2.3 THUẬT TOÁN SẮP XẾP NỔI BỌT
Thuật toán cải tiến
void nbot(int a[], int n) { int i,j,tg,d; i=0;
while (i<n-1) { d=n;
for (j=n-1; j>i; j )
if (a[j]<a[j-1]) {tg=a[j]; a[j]=a[j-1]; a[j-1]=tg; d=j;} i=d;
Trang 295.3 CÁC THUẬT TOÁN SẮP XẾP NHANH
Trang 30 Ý tưởng
Chia bài toán thành các bài toán con
Giải quyết các bài toán con
Tổng hợp kết quả
5.3.1 SẮP XẾP PHÂN ĐOẠN
Trang 31 Ý tưởng
Chọn 1 phần tử làm chốt (đầu, giữa, cuối)
So sánh các phần tử với chốt để chia đoạn cần sắp thành 2 phần (lớn hơn chốt và nhỏ hơn chốt)
Gọi đệ quy cho tới khi mỗi phần chỉ còn 1 phần tử mảng được sắp xếp
5.3.1 SẮP XẾP PHÂN ĐOẠN
Trang 35j < i
Trang 36j < i
25 21 31 12 33 40 67 68 53
Trang 37ij
25 21 12 31 33 40 67 68 53
Trang 38j < i
12 21 25 31 33 40 67 68 53
Trang 39j < i
12 21 25 31 33 40 53 68 67
Trang 40void quick(int l,int r,int a[])
quick(l,j,a);
Trang 425.3.2 SẮP XẾP VUN ĐỐNG
Ý tưởng :
- Tổ chức mảng thành Heap với Heap được định
nghĩa là cây nhị phân hoàn chỉnh
- Khóa của nút cha không nhỏ hơn khóa của 2
con trong sắp xếp tăng dần và không lớn hơn khóa của 2 con trong sắp xếp giảm dần
- Đổi chỗ gốc với phần tử thứ n, tổ chức lại n-1
Trang 445.3.2 SẮP XẾP VUN ĐỐNG
Cây ban đầu
42a0
a1a3
a2
a6a5
a4
11 65 58 94
Trang 455.3.2 SẮP XẾP VUN ĐỐNG
Điều chỉnh a4
42a0
a1a3
a2
a6a5
a4
11 65 58 94
Trang 465.3.2 SẮP XẾP VUN ĐỐNG
Điều chỉnh a3
42a0
a1a3
a2
a6a5
a4
Trang 475.3.2 SẮP XẾP VUN ĐỐNG
Điều chỉnh a2
42a0
a1a3
a2
a6a5
a4
Trang 485.3.2 SẮP XẾP VUN ĐỐNG
Điều chỉnh a1
42a0
a1a3
a2
a6a5
a4
Trang 495.3.2 SẮP XẾP VUN ĐỐNG
Điều chỉnh a1
42a0
a1a3
a2
a6a5
a4
Trang 505.3.2 SẮP XẾP VUN ĐỐNG
Điều chỉnh a0
42
a0a1
a3
a2
a6a5
a4
Trang 515.3.2 SẮP XẾP VUN ĐỐNG
Điều chỉnh a0
99
a0a1
a3
a2
a6a5
a4
Trang 525.3.2 SẮP XẾP VUN ĐỐNG
Điều chỉnh a0
99
a0a1
a3
a2
a6a5
a4
Trang 535.3.2 SẮP XẾP VUN ĐỐNG
Điều chỉnh a0
99
a0a1
a3
a2
a6a5
a4
Trang 545.3.2 SẮP XẾP VUN ĐỐNG
Đổi chỗ gốc với phần tử thứ n (ở vị trí n-1)
99
a0a1
a3
a2
a6a5
a4
Trang 555.3.2 SẮP XẾP VUN ĐỐNG
Đổi chỗ gốc với phần tử thứ n (ở vị trí n-1)
42
a0a1
a3
a2
a6a5
a4
Trang 565.3.2 SẮP XẾP VUN ĐỐNG
Kết thúc bước 1
42
a0a1
a3
a2
a6a5
a4
Trang 605.3.2 SẮP XẾP VUN ĐỐNG
void push(int i,int a[], int n)
{ int j,tg;
while (i<= n/2-1)
{ j=2*i+1;
if ((j<n-1)&&(a[j]<a[j+1])) j++;
if (a[j]>a[i])
{tg=a[i]; a[i]=a[j];
a[j]=tg; i=j; }
else i=n;
}
} void heap(int a[], int n)
{ int i,tg;
for (i= n/2-1;i>=0;i )
push(i,a,n);
for (i=n-1;i>0;i )
{ tg=a[0]; a[0]=a[i]; a[i]=tg;
push(0,a,i);
}
Trang 615.3.2 SẮP XẾP VUN ĐỐNG
void push2(int i,int a[], int n)
{
int j, tg=a[i];
while (i<= n/2-1)
{ j=2*i+1;
if ((j<n-1)&&(a[j]<a[j+1])) j++;
if (a[j]>tg)
{ a[i]=a[j]; i=j; }
else n=i;
}
a[i]=tg;
} void heap(int a[], int n)
{int i,tg;
for (i= n/2-1;i>=0;i )
push2(i,a,n);
for (i=n-1;i>0;i )
{ tg=a[0]; a[0]=a[i]; a[i]=tg;
push2(0,a,i);
}
Trang 63- Bắt đầu kích thước mạch là 1, sau mỗi lần hòa
nhập kích thước mạch tăng gấp đôi
- Sử dụng luân phiên 2 mảng a, b cho tới khi n
Trang 645.3.3 SẮP XẾP HÒA NHẬP
Công việc cần thực hiện :
- Xây dựng hàm merge hòa nhập 2 đoạn mạch
kế tiếp nhau từ mảng a sang mảng b
để hòa nhập n phần tử từ a sang b
- Xây dựng mergesort sử dụng mergepass để
Trang 655.3.3 SẮP XẾP HÒA NHẬP
a0 a1 a2 a3 a4 a5 a6 a7 a8 a9
42 32 74 11 65 58 94 36 99 87
Ví dụ 1 : Sắp xếp mảng a theo thứ tự tăng dần
Trang 685.3.3 SẮP XẾP HÒA NHẬP
void merge(int a[],int d1,int c1,int c2,int b[])
{ int i,j,k;
i=d1; k=d1; j=c1+1;
while ((i<=c1)&&(j<=c2))
if (a[i]<a[j]) b[k++]=a[i++];
else b[k++]=a[j++];
Trang 695.3.3 SẮP XẾP HÒA NHẬP
void mpass(int a[],int b[],int n,int l)
{ int i,j;
i=-1;
while (i+2*l<n)
{merge(a,i+1,i+l,i+2*l,b); i+=2*l; }
if (i+l<n-1) merge(a,i+1,i+l,n-1,b);
else for(j=i+1;j<n;j++) b[j]=a[j];
Trang 705.3.3 SẮP XẾP HÒA NHẬP
void mergesort(int a[], int n)
{ int l; int b[100];
l=1;
while (l<n)
{ mpass(a,b,n,l); l=2*l;
mpass(b,a,n,l); l=2*l;
Trang 735.3.3 SẮP XẾP HÒA NHẬP
void mpass2(int a[],int b[],int n,int &d)
{ int c1,c2,i=-1, j; d=0;
do { c1=i+1;
while ((a[c1]<=a[c1+1])&&(c1<n-1)) c1++;
if (c1<n-1)
{ c2=c1+1;
while ((a[c2]<=a[c2+1])&&(c2<n-1)) c2++;
merge(a,i+1,c1,c2,b); i=c2; d=1;
}
else {for (j=i+1;j<n;j++) b[j]=a[j]; i=n;}
}
Trang 745.3.3 SẮP XẾP HÒA NHẬP
void mergesort2(int a[], int n)
{ int b[100];
do
{ mpass2(a,b,n,d);
mpass2(b,a,n,d);
}
Trang 755.3.3 SẮP XẾP HÒA NHẬP
Độ phức tạp của các giải thuật sắp xếp
• Thuật toán sắp xếp lựa chọn (Selectsort) : O(n2)
• Thuật toán sắp xếp chèn (Insertsort) : O(n2)
• Thuật toán sắp xếp nổi bọt (Bubblesort) : O(n2)
• Thuật toán sắp xếp phân đoạn (Quicksort): n*log2(n), O(n2 )
• Thuật toán sắp xếp vun đống (Heapsort) : n*log2(n)
Trang 76Bài 1 - Viết chương trình thực hiện các yêu cầu sau :
Nhập vào một dãy n số nguyên (0<n<100)
In dãy vừa nhập ra màn hình
Sắp xếp dãy theo chiều tăng dần bằng các thuật toán đã học
BÀI TẬP ÁP DỤNG
Trang 77Bài 2
Tự cho các dãy n số nguyên (n>10), mô tả quá trình sắp xếp lại dãy số theo thứ tự tăng dần, giảm dần bằng các thuật toán sắp xếp
BÀI TẬP ÁP DỤNG