Tải bản đầy đủ (.pdf) (63 trang)

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

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (453.76 KB, 63 trang )


S P X PẮ Ế
Nguy n Văn Linhễ

M c tiêuụ
Sau khi hoàn t t bài h c này b n c n ph i:ấ ọ ạ ầ ả

Hi u các gi i thu t s p x p.ể ả ậ ắ ế

V n d ng đ c gi i thu t đ minh h a vi c s p ậ ụ ượ ả ậ ể ọ ệ ắ
x p.ế

Hi u các l u đ c a các gi i thu t s p x p.ể ư ồ ủ ả ậ ắ ế

Hi u các ch ng trình s p x p. ể ươ ắ ế

Hi u đ c vi c đánh giá các gi i thu t. ể ượ ệ ả ậ

T m quan tr ng c a bài toán s p x pầ ọ ủ ắ ế

S p x p m t danh sách các đ i t ng theo m t ắ ế ộ ố ượ ộ
th t nào đó là m t bài toán th ng đ c v n ứ ự ộ ườ ượ ậ
d ng trong các ng d ng tin h c.ụ ứ ụ ọ

S p x p là m t yêu c u không th thi u trong ắ ế ộ ầ ể ế
khi thi t k các ph n m m. ế ế ầ ề

Do đó vi c nghiên c u các ph ng pháp s p ệ ứ ươ ắ
x p là r t c n thi t đ v n d ng trong khi l p ế ấ ầ ế ể ậ ụ ậ
trình.


S p x p trong và s p x p ngoàiắ ế ắ ế

S p x p trongắ ế là s s p x p ự ắ ế d li u đ c t ch c trong b nh ữ ệ ượ ổ ứ ộ ớ
trong c a máy tính.ủ

Các đ i t ng c n đ c s p x p là các m u tin g m m t ho c nhi u ố ượ ầ ượ ắ ế ẩ ồ ộ ặ ề
tr ng. M t trong các tr ng đ c g i là khóa (key), ki u c a nó là m t ườ ộ ườ ượ ọ ể ủ ộ
ki u có quan h th t (nh các ki u s nguyên, s th c, chu i ký t ...). ể ệ ứ ự ư ể ố ố ự ỗ ự

Danh sách các đ i t ng c n s p x p s là m t m ng c a các m u tin ố ượ ầ ắ ế ẽ ộ ả ủ ẩ
v a nói trên. ừ ở

M c đích c a vi c s p x p là t ch c l i các m u tin sao cho các khóa ụ ủ ệ ắ ế ổ ứ ạ ẩ
c a chúng đ c s p th t t ng ng v i quy lu t s p x p. ủ ượ ắ ứ ự ươ ứ ớ ậ ắ ế

M t cách m c nhiên, quy lu t s p x p là th t không gi m. Khi c n s p ộ ặ ậ ắ ế ứ ự ả ầ ắ
x p theo th t không tăng thì ph i nói rõ.ế ứ ự ả

S p x p ngoàiắ ế là s s p x p đ c s d ng khi s l ng đ i t ng c n ự ắ ế ượ ử ụ ố ượ ố ượ ầ
s p x p l n không th l u tr trong b nh trong mà ph i l u tr trên ắ ế ớ ể ư ữ ộ ớ ả ư ữ b ộ
nh ngoàiớ .

T ch c d li u và ngôn ng cài đ tổ ứ ữ ệ ữ ặ

Ð trình bày các ví d minh h a chúng ta s dùng C ể ụ ọ ẽ
(Turbo C++, Version 3.0) làm ngôn ng th hi n và ữ ể ệ
s d ng khai báo sau. ử ụ
const int n = 10;
typedef int keytype;
typedef float othertype;

typedef struct recordtype {
keytype key;
othertype otherfields;
};
recordtype a[n]; /* khai bao mang a co n phan tu */

T ch c d li u và ngôn ng cài đ t (tt)ổ ứ ữ ệ ữ ặ
void Swap(recordtype *x, recordtype *y)
{
recordtype temp;
temp = *x;
*x = *y;
*y = temp;
}

C n th y r ng th t c Swap l y O(1) th i gian vì ch ầ ấ ằ ủ ụ ấ ờ ỉ
th c hi n 3 l nh gán n i ti p nhau.ự ệ ệ ố ế

Gi i thu t s p x p ch n (Selection Sort)ả ậ ắ ế ọ

B c 0, ch n ph n t có khóa nh nh t trong n ph n ướ ọ ầ ử ỏ ấ ầ
t t a[0] đ n a[n-1] và hoán v nó v i ph n t a[0].ử ừ ế ị ớ ầ ử

B c 1, ch n ph n t có khóa nh nh t trong n-1 ph n ướ ọ ầ ử ỏ ấ ầ
t t a[1] đ n a[n-1] và hoán v nó v i a[1].ử ừ ế ị ớ

T ng quát b c th i, ch n ph n t có khoá nh ổ ở ướ ứ ọ ầ ử ỏ
nh t trong n-i ph n t t a[i] đ n a[n-1] và hoán v nó ấ ầ ử ừ ế ị
v i a[i].ớ


Sau n-1 b c này thì m ng đã đ c s p x p.ướ ả ượ ắ ế

Ph ng pháp ch n ph n tươ ọ ầ ử

Đ u tiên ta đ t khoá nh nh t là khoá c a a[i] (lowkey ầ ặ ỏ ấ ủ
= a[i].key) và ch s c a ph n t có khoá nh nh t là i ỉ ố ủ ầ ử ỏ ấ
(lowindex = i).

Xét các ph n t a[j] (v i j t i+1 đ n n-1), n u khoá c a ầ ử ớ ừ ế ế ủ
a[j] nh h n khoá nh nh t (a[j].key < lowkey) thì đ t ỏ ơ ỏ ấ ặ
l i l i khoá nh nh t là khoá c a a[j] (lowkey = a[j].key) ạ ạ ỏ ấ ủ
và ch s c a ph n t có khoá nh nh t là j (lowindex ỉ ố ủ ầ ử ỏ ấ
= j).

Khi đã xét h t các a[j] (j>n-1) thì ph n t có khoá nh ế ầ ử ỏ
nh t là a[lowindex]. ấ

Ví d s p x p ch nụ ắ ế ọ
                Khóa
Bước 
a[0] a[1] a[2] a[3] a[4] a[5] a[6] a[7] a[8] a[9]
Ban đầu 5 6 2 2 10 12 9 10 9 3
Bước 0  2 6 5 2 10 12 9 10 9 3
Bước 1 
2
5 6 10 12 9 10 9 3
Bước 2
3
6 10 12 9 10 9 5
Bước 3

5
10 12 9 10 9 6
Bước 4
6
12 9 10 9 10
Bước 5
9
12 10 9 10
Bước 6
9
10 12 10
Bước 7
10
12 10
Bước 8
10
12
Kết quả 2 2 3 5 6 9 9 10 10 12

L u đ ư ồ
s p x p ch nắ ế ọ
Begin
i = 0
i<=n-2
lowindex = i
lowkey = a[i].key
j<=n-1
i = i+1
a[j].key<lowkey
lowindex = j

lowkey = a[j].key
j = j+1
S
j = i+1
End
swap(a[i],a[lowindex])
S
Đ
S
Đ
Đ

Ch ng trình s p x p ch nươ ắ ế ọ
void SelectionSort(void)
{ int i,j,lowindex;
keytype lowkey;
/*1*/ for (i=0; i<=n-2; i++) {
/*2*/ lowindex = i;
/*3*/ lowkey = a[i].key;
/*4*/ for (j = i+1; j <= n-1; j++)
/*5*/ if (a[j].key < lowkey) {
/*6*/ lowkey = a[j].key;
/*7*/ lowindex = j; }
/*8*/ Swap(&a[i],&a[lowindex]);
}
}

Đánh giá s p x p ch nắ ế ọ

Hàm Swap t n O(1).ố


Toàn b ch ng trình ch bao g m l nh /*1*/. L nh /*1*/ ch a ộ ươ ỉ ồ ệ ệ ứ
các l nh “đ ng c p” /*2*/, /*3*/, /*4*/ và /*8*/, trong đó các ệ ồ ấ
l nh /*2*/, /*3*/ và /*8*/ đ u t n th i gian O(1). ệ ề ố ờ

L nh /*6*/ và /*7*/ đ u t n O(1) nên l nh /*5*/ t n O(1).ệ ề ố ệ ố

Vòng l p /*4*/ th c hi n n-i-1 l n, vì j ch y t i+1 đ n n-1, m i ặ ự ệ ầ ạ ừ ế ỗ
l n l y O(1), nên l y O(n-i-1) th i gian. ầ ấ ấ ờ

G i T(n) là th i gian th c hi n c a ch ng trình, thì T(n) là th i ọ ờ ự ệ ủ ươ ờ
gian th c hi n l nh /*1*/. Mà l nh /*1*/ có i ch y t 0 đ n n-2 ự ệ ệ ệ ạ ừ ế
nên ta có:
)O(n
2
1)-n(n
1)-i-(nT(n)
2
2-n
0=i
===


Gi i thu t s p x p xen (Insertion ả ậ ắ ế
Sort)

Tr c h t ta xem ph n t a[0] là m t dãy đã có th t .ướ ế ầ ử ộ ứ ự

B c 1, xen ph n t a[1] vào danh sách đã có th t ướ ầ ử ứ ự
a[0] sao cho a[0], a[1] là m t danh sách có th t .ộ ứ ự


B c 2, xen ph n t a[2] vào danh sách đã có th t ướ ầ ử ứ ự
a[0], a[1] sao cho a[0], a[1], a[2] là m t danh sách có th ộ ứ
t .ự

T ng quát, b c i, xen ph n t a[i] vào danh sách đã có ổ ướ ầ ử
th t a[0], a[1], … a[i-1] sao cho a[0], a[1],.. a[i] là m t ứ ự ộ
danh sách có th t .ứ ự

Sau n-1 b c thì k t thúc.ướ ế

Ph ng pháp xenươ

Ph n t đang xét a[j] s đ c xen vào v trí thích ầ ử ẽ ượ ị
h p trong danh sách các ph n t đã đ c s p tr c ợ ầ ử ượ ắ ướ
đó a[0],a[1],..a[j-1]:

So sánh khoá c a a[j] v i khoá c a a[j-1] đ ng ngay ủ ớ ủ ứ
tr c nó. ướ

N u khoá c a a[j] nh h n khoá c a a[j-1] thì hoán ế ủ ỏ ơ ủ
đ i a[j-1] và a[j] cho nhau và ti p t c so sánh khoá ổ ế ụ
c a a[j-1] (lúc này a[j-1] ch a n i dung c a a[j]) v i ủ ứ ộ ủ ớ
khoá c a a[j-2] đ ng ngay tr c nó... ủ ứ ướ

Ví d s p x p xenụ ắ ế
                Khóa 
Bước
a[0] a[1] a[2] a[3] a[4] a[5] a[6] A[7] a[8] a[9]
Ban đầu 5 6 2 2 10 12 9 10 9 3

Bước 1
5 6
Bước 2
2 5 6
Bước 3
2 2 5 6
Bước 4
2 2 5 6 10
Bước 5
2 2 5 6 10 12
Bước 6
2 2 5 6 9 10 12
Bước 7
2 2 5 6 9 10 10 12
Bước 8
2 2 5 6 9 9 10 10 12
Bước 9
2 2 3 5 6 9 9 10 10 12

L u đ ư ồ
s p x p xenắ ế
Begin
i = 1
i<=n-1
(j>0) and
(a[j].key < a[j-1].key)
i = i+1
j = i
End
swap(a[j],a[j-1])

j = j-1
S
Đ
Đ
S

Ch ng trình s p x p xen ươ ắ ế
void InsertionSort(void)
{
int i,j;
/*1*/ for (i = 1; i<= n-1; i++) {
/*2*/ j = i;
/*3*/ while ((j>0) && (a[j].key < a[j-1].key)) {
/*4*/ Swap(&a[j], &a[j-1]);
/*5*/ j= j-1;
}
}
}

Đánh giá s p x p xenắ ế

Các l nh /*4*/ và /*5*/ đ u l y O(1). Vòng l p ệ ề ấ ặ
/*3*/, trong tr ng h p x u nh t, ch y i l n (j ườ ợ ấ ấ ạ ầ
gi m t i đ n 1), m i l n t n O(1) nên /*3*/ l y i ả ừ ế ỗ ầ ố ấ
th i gian. ờ

L nh /*2*/ và /*3*/ là hai l nh n i ti p nhau, l nh ệ ệ ố ế ệ
/*2*/ l y O(1) nên c hai l nh này l y i.ấ ả ệ ấ

Vòng l p /*1*/ có i ch y t 1 đ n n-1 nên ta có:ặ ạ ừ ế

)O(n
2
1)-n(n
iT(n)
2
1-n
1i
===

=

Gi i thu t s p x p “n i b t” (Bubble ả ậ ắ ế ổ ọ
Sort)

B c 1: Xét các ph n t a[j] (j gi m t n-1 đ n 1), ướ ầ ử ả ừ ế
so sánh khoá c a a[j] v i khoá c a a[j-1]. N u khoá ủ ớ ủ ế
c a a[j] nh h n khoá c a a[j-1] thì hoán đ i a[j] và ủ ỏ ơ ủ ổ
a[j-1] cho nhau. Sau b c này thì a[0] có khoá nh ướ ỏ
nh t.ấ

B c 2: Xét các ph n t a[j] (j gi m t n-1 đ n 2), ướ ầ ử ả ừ ế
so sánh khoá c a a[j] v i khoá c a a[j-1]. N u khoá ủ ớ ủ ế
c a a[j] nh h n khoá c a a[j-1] thì hoán đ i a[j] và ủ ỏ ơ ủ ổ
a[j-1] cho nhau. Sau b c này thì a[1] có khoá nh ướ ỏ
th 2.ứ



Sau n-1 b c thì k t thúc.ướ ế


Ví d s p x p “n i b t”ụ ắ ế ổ ọ
           Khóa
Bước
a[0] a[1] a[2] a[3] a[4] A[5] a[6] a[7] a[8] a[9]
Ban đầu 5 6 2 2 10 12 9 10 9 3
Bước 1
2
5 6 2 3 10 12 9 10 9
Bước 2
2
5 6 3 9 10 12 9 10
Bước 3
3
5 6 9 9 10 12 10
Bước 4
5
6 9 9 10 10 12
Bước 5
6
9 9 10 10 12
Bước 6
9
9 10 10 12
Bước 7
9
10 10 12
Bước 8
10
10 12
Bước 9

10
12
Kết quả 2 2 3 5 6 9 9 10 10 12

L u đ ư ồ
s p x p n i b tắ ế ổ ọ
Begin
i = 0
i<=n-2
i = i+1
j = n-1
End
swap(a[j],a[j-1])
S
Đ
Đ
S
a[j].key < a[j-1].key
j>= i+1
Đ
j = j-1
S

Ch ng trình ươ
s p x p “n i ắ ế ổ
b t”ọ
void BubbleSort(void)
{ int i,j;
/*1*/ for(i= 0; i<= n-2; i++)
/*2*/ for(j=n-1;j>=i+1; j--)

/*3*/ if (a[j].key < a[j-1].key)
/*4*/ Swap(&a[j],&a[j-1]);
}
Begin
i = 0
i<=n-2
i = i+1
j = n-1
End
swap(a[j],a[j-1])
S
Đ
Đ
S
a[j].key < a[j-1].key
j>=
i+1
Đ
j = j-1
S

Ý t ng c a QuickSortưở ủ

Ch n m t giá tr khóa v làm ch t (pivot).ọ ộ ị ố

Phân ho ch dãy a[0]..a[n-1] thành hai m ng con "bên trái" và ạ ả
"bên ph i". M ng con "bên trái" bao g m các ph n t có ả ả ồ ầ ử khóa
nh h n ch tỏ ơ ố , m ng con "bên ph i" bao g m các ph n t có ả ả ồ ầ ử
khóa l n h n ho c b ng ch tớ ơ ặ ằ ố .


S p x p m ng con “bên trái” và m ng con “bên ph i”.ắ ế ả ả ả

Sau khi đã s p x p đ c m ng con “bên trái” và m ng con ắ ế ượ ả ả
“bên ph i” thì m ng đã cho s đ c s p b i vì t t c các khóa ả ả ẽ ượ ắ ở ấ ả
trong m ng con “bên trái” đ u nh h n các khóa trong m ng ả ề ỏ ơ ả
con “bên ph i”.ả

Vi c s p x p các m ng con “bên trái” và “bên ph i” cũng đ c ệ ắ ế ả ả ượ
ti n hành b ng ph ng pháp nói trên.ế ằ ươ

M t m ng ch g m m t ph n t ho c g m nhi u ph n t có ộ ả ỉ ồ ộ ầ ử ặ ồ ề ầ ử
khóa b ng nhau thì đã có th t . ằ ứ ự

Ph ng pháp ch n ch tươ ọ ố

Ch n giá tr ọ ị khóa l n nh tớ ấ trong hai ph n t có khóa ầ ử
khác nhau đ u tiên k t trái qua. ầ ể ừ

N u m ng ch g m m t ph n t hay g m nhi u ph n ế ả ỉ ồ ộ ầ ử ồ ề ầ
t có khóa b ng nhau thì không cóử ằ ch tố .

Ví d :ụ Ch n ch t trong các m ng sauọ ố ả

Cho m ng g m các ph n t có khoá là 6, 6, 5, 8, 7, 4, ta ch n ả ồ ầ ử ọ
ch t là 6 (khoá c a ph n t đ u tiên).ố ủ ầ ử ầ

Cho m ng g m các ph n t có khoá là 6, 6, 7, 5, 7, 4, ta ch n ả ồ ầ ử ọ
ch t là 7 (khoá c a ph n t th 3).ố ủ ầ ử ứ

Cho m ng g m các ph n t có khoá là 6, 6, 6, 6, 6, 6 thì không ả ồ ầ ử

có ch t (các ph n t có khoá b ng nhau).ố ầ ử ằ

Cho m ng g m m t ph n t có khoá là 6 thì không có ch t (do ả ồ ộ ầ ử ố
ch có m t ph n t ). ỉ ộ ầ ử

Ph ng pháp phân ho chươ ạ

Ð phân ho ch m ng ta dùng 2 "con nháy" L và R trong ể ạ ả
đó L t bên trái và R t bên ph i.ừ ừ ả

Ta cho L ch y sang ph i cho t i khi g p ph n t có khóa ≥ ạ ả ớ ặ ầ ử
ch t ố

Cho R ch y sang trái cho t i khi g p ph n t có khóa < ạ ớ ặ ầ ử
ch t. ố

T i ch d ng c a L và R n u L < R thì hoán v a[L],a[R]. ạ ỗ ừ ủ ế ị

L p l i quá trình d ch sang ph i, sang trái c a 2 "con ặ ạ ị ả ủ
nháy" L và R cho đ n khi L > R. ế

Khi đó L s là đi m phân ho ch, c th là a[L] là ph n t ẽ ể ạ ụ ể ầ ử
đ u tiên c a m ng con “bên ph i”.ầ ủ ả ả

×