Giáo trình: Cấu Trúc Dữ Liệu và Giải Thuật
Trang: 43
B15: K2++
B16: IF (J2 > N2) //Đã chép hết các phần tử trong Temp2
Thực hiện B30
B17: Lặp lại B11
//Chép phần run còn lại trong Temp1 về M
B18: IF (K1 > L) //Đã chép hết phần run còn lại trong Temp1 về M
Lặp lại B4
B19: M[I] = Temp1[J1]
B20: I++
B21: J1++
B22: K1++
B23: IF (J1 > N1) //Đã chép hết các phần tử trong Temp1
Thực hiện B25
B24: Lặp lại B18
//Chép các phần tử còn lại trong Temp2 về M
B25: IF (J2>N2)
Thực hiện Bkt
B26: M[I] = Temp2[J2]
B27: I++
B28: J2++
B29: Lặp lại B25
//Chép các phần tử còn lại trong Temp1 về M
B30: IF (J1>N1)
Thực hiện Bkt
B31: M[I] = Temp1[J1]
B32: I++
B33: J1++
B34: Lặp lại B30
Bkt: Kết thúc
- Thuật toán sắp xếp trộn thẳng:
B1: L = 1 //Chiều dài ban đầu của các run
B2: IF (L ≥ N) //Dãy chỉ còn 01 run
Thực hiện Bkt
B3: Phân_Phối(M, N, Temp1, N1, Temp2, N2, L)
B4: Trộn(Temp1, N1, Temp2, N2, M, N, L)
B5: L = 2*L
B6: Lặp lại B2
Bkt: Kết thúc
- Cài đặt thuật toán:
Hàm StraightMergeSort có prototype như sau:
void StraightMergeSort(T M[], int N);
Hàm thực hiện việc sắp xếp N phần tử có kiểu dữ liệu T trên mảng M theo thứ tự
tăng dựa trên thuật toán sắp trộn trực tiếp. Hàm sử dụng các hàm Distribute, Merge
có prototype và ý nghóa như sau:
void Distribute(T M[], int N, T Temp1[], int &N1, T Temp2[], int &N2, int L);
Click to buy NOW!
P
D
F
-
X
C
h
a
n
g
e
V
i
e
w
e
r
w
w
w
.
d
o
c
u
-
t
r
a
c
k
.
c
o
m
Click to buy NOW!
P
D
F
-
X
C
h
a
n
g
e
V
i
e
w
e
r
w
w
w
.
d
o
c
u
-
t
r
a
c
k
.
c
o
m
.
Giáo trình: Cấu Trúc Dữ Liệu và Giải Thuật
Trang: 44
Hàm thực hiện việc phân phối luân phiên các đường chạy có chiều dài L trên dãy M
có N phần tử về thành các dãy Temp1 và Temp2 có tương ứng N1 và N2 phần tử.
void Merge(T Temp1[], int N1, T Temp2[], int N2, T M[], int &N, int L);
Hàm thực hiện việc trộn từng cặp tương ứng các đường chạy với độ dài L trên
Temp1, Temp2 về dãy M thành các đường chạy có chiều dài 2*L.
Nội dung của các hàm như sau:
void Distribute(T M[], int N, T Temp1[], int &N1, T Temp2[], int &N2, int L)
{ int I = 0, J1 = 0, J2 = 0;
while (I < N)
{ for(int K = 0; K<L && I<N; K++, I++, J1++)
Temp1[J1] = M[I];
for(K = 0; K<L && I<N; K++, I++, J2++)
Temp2[J2] = M[I];
}
N1 = J1;
N2 = J2;
return;
}
//========================================================
void Merge(T Temp1[], int N1, T Temp2[], int N2, T M[], int &N, int L)
{ int I = 0, J1 = 0, J2 = 0, K1 = 0, K2 = 0;
while (J1 < N1 && J2 < N2)
{ while (Temp1[J1] <= Temp2[J2] && J1 < N1 && J2 < N2)
{ M[I] = Temp1[J1];
I++;
J1++;
if (J1 == N1)
{ for (; J2 < N2; J2++, I++)
M[I] = Temp2[J2];
return;
}
K1++;
if (K1 == L)
{ for (; K2 < L && J2 < N2; K2++, I++, J2++)
M[I] = Temp2[J2];
K1 = K2 = 0;
break;
}
}
while (Temp2[J2] < Temp1[J1] && J1 < N1 && J2 < N2)
{ M[I] = Temp2[J2];
I++;
J2++;
if (J2 == N2)
{ for (; J1 < N1; J1++, I++)
M[I] = Temp1[J1];
Click to buy NOW!
P
D
F
-
X
C
h
a
n
g
e
V
i
e
w
e
r
w
w
w
.
d
o
c
u
-
t
r
a
c
k
.
c
o
m
Click to buy NOW!
P
D
F
-
X
C
h
a
n
g
e
V
i
e
w
e
r
w
w
w
.
d
o
c
u
-
t
r
a
c
k
.
c
o
m
.
Giáo trình: Cấu Trúc Dữ Liệu và Giải Thuật
Trang: 45
return;
}
K2++;
if (K2 == L)
{ for (; K1 < L && J1 < N1; K1++, I++, J1++)
M[I] = Temp1[J1];
K1 = K2 = 0;
break;
}
}
}
while (J1 < N1)
{ M[I] = Temp1[J1];
I++;
J1++;
}
while (J2 < N2)
{ M[I] = Temp2[J2];
I++;
J2++;
}
N = N1 + N2;
return;
}
//========================================================
void StraightMergeSort(T M[], int N)
{ int L = 1, N1 = 0, N2 = 0;
T * Temp1 = new T[N];
T * Temp2 = new T[N];
if (Temp1 == NULL || Temp2 == NULL)
return;
while (L < N)
{ Distribute(M, N, Temp1, N1, Temp2, N2, L);
Merge(Temp1, N1, Temp2, N2, M, N, L);
L = 2*L;
}
delete Temp1;
delete Temp2;
return;
}
- Ví dụ minh họa thuật toán:
Giả sử ta cần sắp xếp mảng M có 10 phần tử sau (N = 10):
M: 41 36 32 47 65 21 52 57 70 50
Ta thực hiện các lần phân phối và trộn các phần tử của M như sau:
Lần 1: L = 1
Click to buy NOW!
P
D
F
-
X
C
h
a
n
g
e
V
i
e
w
e
r
w
w
w
.
d
o
c
u
-
t
r
a
c
k
.
c
o
m
Click to buy NOW!
P
D
F
-
X
C
h
a
n
g
e
V
i
e
w
e
r
w
w
w
.
d
o
c
u
-
t
r
a
c
k
.
c
o
m
.
Giáo trình: Cấu Trúc Dữ Liệu và Giải Thuật
Trang: 46
Phân phối M thành Temp1, Temp2:
M: 41 36 32 47 65 21 52 57 70 50
Temp1:N1=5
41 32 65 52 70
Temp2:N2=5
36 47 21 57 50
Trộn Temp1, Temp2 thành M:
Temp1:N1=5
41 32 65 52 70
Temp2:N2=5
36 47 21 57 50
M: 36 41 32 47 21 65 52 57 50 70
Lần 2: L = 2
Phân phối M thành Temp1, Temp2:
M: 36 41 32 47 21 65 52 57 50 70
Temp1: N1=6
36 41 21 65 50 70
Temp2: N2=4
32 47 52 57
Trộn Temp1, Temp2 thành M:
Temp1: N1=6
36 41 21 65 50 70
Temp2: N2=4
32 47 52 57
M: 32 36 41 47 21 52 57 65 50 70
Lần 3: L = 4
Click to buy NOW!
P
D
F
-
X
C
h
a
n
g
e
V
i
e
w
e
r
w
w
w
.
d
o
c
u
-
t
r
a
c
k
.
c
o
m
Click to buy NOW!
P
D
F
-
X
C
h
a
n
g
e
V
i
e
w
e
r
w
w
w
.
d
o
c
u
-
t
r
a
c
k
.
c
o
m
.
Giáo trình: Cấu Trúc Dữ Liệu và Giải Thuật
Trang: 47
Phân phối M thành Temp1, Temp2:
M: 32 36 41 47 21 52 57 65 50 70
Temp1:N1=6 32 36 41 47 50 70
Temp2: N2=4 21 52 57 65
Trộn Temp1, Temp2 thành M:
Temp1:N1=6 32 36 41 47 50 70
Temp2: N2=4 21 52 57 65
M: 21 32 36 41 47 52 57 65 50 70
Lần 4: L = 8
Phân phối M thành Temp1, Temp2:
M: 21 32 36 41 47 52 57 65 50 70
Temp1: N1=8 21 32 36 41 47 52 57 65
Temp2: N2=2 50 70
Trộn Temp1, Temp2 thành M:
Temp1: N1=8 21 32 36 41 47 52 57 65
Temp2: N2=2 50 70
M: 21 32 36 41 47 50 52 57 65 70
L = 16 > 10: Kết thúc thuật toán
- Phân tích thuật toán:
+ Trong thuật giải này chúng ta luôn thực hiện log
2
(N) lần phân phối và trộn các run.
Click to buy NOW!
P
D
F
-
X
C
h
a
n
g
e
V
i
e
w
e
r
w
w
w
.
d
o
c
u
-
t
r
a
c
k
.
c
o
m
Click to buy NOW!
P
D
F
-
X
C
h
a
n
g
e
V
i
e
w
e
r
w
w
w
.
d
o
c
u
-
t
r
a
c
k
.
c
o
m
.