Skip to content

Commit 92e267e

Browse files
Create javascript-array-sorting.md
1 parent 430dbb8 commit 92e267e

File tree

1 file changed

+336
-0
lines changed

1 file changed

+336
-0
lines changed
Lines changed: 336 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,336 @@
1+
Từ xưa đến nay, sắp xếp giữ một vai trò vô cùng quan trọng. Nhiều ứng dụng (từ điển, danh bạ, quản lý tài khoản,…) thường có chức năng sắp xếp theo thứ tự từ điển (a-z). Việc này giúp cho người quản lý và người dùng dễ dàng tìm kiếm nội dung hơn. Do đó, trong bài viết này, tôi sẽ cùng với các bạn tìm hiểu về vấn đề [Array](https://completejavascript.com/javascript-array-co-ban/) Sorting trong JavaScript.
2+
3+
Về sắp xếp nói chung, chúng ta có rất nhiều thuật toán với độ phức tạp khác nhau, có thể kể đến là: selection sort, insertion sort, binary insertion sort, interchange sort, bubble sort, shaker sort, quick sort, merge sort, heap sort,…
4+
5+
(Xem thêm hai bài tổng hợp về thuật toán sắp xếp trong C/C++: [phần 1](http://thuattoan.phamvanlam.com/tong-hop-mot-so-thuat-toan-co-ban-ve-sap-xep-phan-1/), [phần 2](http://thuattoan.phamvanlam.com/tong-hop-mot-so-thuat-toan-co-ban-ve-sap-xep-phan-2/))
6+
7+
Tuy nhiên, bạn không cần thiết phải implement lại những thuật toán sắp xếp này. Vì JavaScript hỗ trợ sẵn cho chúng ta một [function](https://completejavascript.com/tim-hieu-function-javascript/) để sắp xếp.
8+
9+
## Cú pháp:
10+
11+
```js
12+
arr.sort()
13+
arr.sort(compareFunction)
14+
```
15+
16+
### Tham số
17+
18+
**compareFunction**: dùng để xác định thứ tự sắp xếp. Nếu bạn bỏ qua tham số này thì mặc định JavaScript sẽ sắp xếp theo thứ tự tăng dần trong bảng mã Unicode (hay đơn giản thì cứ gọi là thứ tự tăng dần bảng chữ cái).
19+
20+
### Giá trị trả về
21+
22+
Mảng đã được sắp xếp (và mảng ban đầu có bị thay đổi).
23+
24+
```js
25+
var a = ['c', 'g', 'w', 'a'];
26+
var b = a.sort();
27+
console.log(a); // => ["a", "c", "g", "w"]
28+
console.log(b); // => ["a", "c", "g", "w"]
29+
```
30+
31+
## Tìm hiểu compareFunction
32+
33+
Hàm *compareFunction* dùng để xác định thứ tự sắp xếp. Nếu a và b là hai phần tử dùng để so sánh thì:
34+
* Nếu compareFunction(a, b) trả về < 0 thì a sẽ đứng trước b.
35+
* Nếu compareFunction(a, b) trả về > 0 thì a sẽ đứng sau b.
36+
* Nếu compareFunction(a, b) trả về = 0 thì không sắp xếp (giữ nguyên thứ tự).
37+
38+
## Array sorting với numbers
39+
40+
JavaScript hỗ trợ sắp xếp nhiều kiểu dữ liệu. Tuy nhiên, phổ biến nhất vẫn là [numbers](https://completejavascript.com/values-types-va-operators-trong-javascript-phan-1/). Và như tôi đã nói ở trên, mặc định hàm sort sẽ so sánh theo kiểu [string](https://completejavascript.com/values-types-va-operators-trong-javascript-phan-2/). Do đó, kết quả sẽ như thế này:
41+
42+
```js
43+
var a = [9, 100, 45, 33];
44+
console.log(a.sort());
45+
// => [100, 33, 45, 9]
46+
```
47+
48+
Bạn không nhìn lầm đâu. Kết quả trên là hoàn toàn chính xác. Vì khi so sánh theo kiểu string thì ‘1’ < ‘3’ < ‘4’ < ‘9’. Vì vậy, để sắp xếp chúng theo kiểu numbers thì bạn cần phải sử dụng hàm compareFunction.
49+
50+
### Sử dụng hàm compareNumbers sắp xếp numbers theo thứ tự tăng dần
51+
52+
```js
53+
function compareNumbers(a, b) {
54+
return a - b;
55+
}
56+
var a = [9, 100, 45, 33];
57+
console.log(a.sort(compareNumbers));
58+
// => [9, 33, 45, 100]
59+
```
60+
61+
Theo đúng mô tả của hàm compareFunction, khi a < b => a – b < 0 => a sẽ đứng trước b. Nghĩa là số bé hơn sẽ đứng trước. Áp dụng quy tắc này, ta được mảng các số sắp xếp theo thứ tự tăng dần.
62+
63+
Ngoài cách viết hàm riêng như trên, bạn có thể áp dụng [JavaScript closures](https://completejavascript.com/tim-hieu-javascript-closures/):
64+
65+
```js
66+
var a = [9, 100, 45, 33];
67+
console.log(a.sort(function(a, b){
68+
return a - b;
69+
}));
70+
// => [9, 33, 45, 100]
71+
```
72+
73+
### Sắp xếp numbers theo thứ tự giảm dần
74+
75+
Để sắp xếp mảng numbers theo thứ tự giảm dần thì bạn chỉ cần thay đổi nội dung hàm compareNumbers. Thay vì return a – b thì bây giờ tôi sẽ return b – a.
76+
77+
```js
78+
var a = [9, 100, 45, 33];
79+
console.log(a.sort(function(a, b){
80+
return b - a;
81+
}));
82+
// => [100, 45, 33, 9]
83+
```
84+
85+
Bây giờ, khi a < b => b – a > 0 => a sẽ đứng sau b. Nghĩa là số nhỏ hơn sẽ đứng sau. Do đó, kết quả thu được là dãy số giảm dần như trên.
86+
87+
Trên đây là cách sử dụng hàm sort (mặc định) của [JavaScript](https://completejavascript.com/category/javascript-co-ban/) để sắp xếp mảng. Tuy nhiên, nếu như bạn không muốn sử dụng hàm mặc định này thì bạn vẫn có thể tự implement sử dụng một số thuật toán sắp xếp cơ bản.
88+
89+
## Array sorting trong JavaScript sử dụng thuật toán
90+
91+
Nếu bạn từng học ít nhất một ngôn ngữ lập trình như C/C++, Java,… thì tôi dám chắc là bạn đã implement thuật toán sắp xếp rồi.
92+
93+
Một số thuật toán cơ bản là:
94+
95+
* Thuật toán sắp xếp chọn trực tiếp – Selection Sort
96+
* Sắp xếp chèn trực tiếp – Insertion Sort
97+
* Sắp xếp chèn trực tiếp dựa trên tìm kiếm nhị phân – Binary Insertion Sort
98+
* Thuật toán sắp xếp đổi chỗ trực tiếp – Interchange Sort
99+
* Sắp xếp nổi bọt – Bubble Sort
100+
* Thuật toán Shaker Sort
101+
* Sắp xếp nhanh – Quick Sort
102+
* Sắp xếp trộn – Merge Sort
103+
* Sắp xếp vun đống – Heap Sort
104+
105+
### Array sorting với sắp xếp chọn trực tiếp – [Selection Sort](https://en.wikipedia.org/wiki/Selection_sort)
106+
107+
```js
108+
function selectionSort(array){
109+
for(let i = 0; i < array.length - 1; i++){
110+
let idmin = i;
111+
for(let j = i + 1; j < array.length; j++){
112+
if(array[j] < array[idmin]) idmin = j;
113+
}
114+
115+
// swap
116+
let t = array[i];
117+
array[i] = array[idmin];
118+
array[idmin] = t;
119+
}
120+
}
121+
```
122+
123+
### Sắp xếp chèn trực tiếp – Insertion Sort
124+
125+
```js
126+
function insertionSort(array){
127+
let pos, x;
128+
for(let i = 1; i < array.length; i++){
129+
pos = i - 1;
130+
x = array[i];
131+
while(pos >= 0 && array[pos] > x){
132+
array[pos + 1] = array[pos];
133+
pos--;
134+
}
135+
array[pos + 1] = x;
136+
}
137+
}
138+
```
139+
140+
### Sắp xếp chèn trực tiếp dựa trên tìm kiếm nhị phân – Binary Insertion Sort
141+
142+
```js
143+
function binaryInsertionSort(array){
144+
let l, r, m, x;
145+
for(let i = 1; i < array.length; i++){
146+
l = 0;
147+
r = i - 1;
148+
x = array[i];
149+
150+
while(l <= r){
151+
m = Math.floor((l + r) / 2);
152+
if(array[m] > x) r = m - 1;
153+
else l = m + 1;
154+
}
155+
156+
for(let j = i; j > l; j--)
157+
array[j] = array[j - 1];
158+
array[l] = x;
159+
}
160+
}
161+
```
162+
163+
### Sắp xếp đổi chỗ trực tiếp – Interchange Sort
164+
165+
```js
166+
function interChangeSort(array){
167+
for(let i = 0; i < array.length - 1; i++){
168+
for(let j = i + 1; j < array.length; j++){
169+
if(array[j] < array[i]){
170+
let t = array[i];
171+
array[i] = array[j];
172+
array[j] = t;
173+
}
174+
}
175+
}
176+
}
177+
```
178+
179+
### Sắp xếp nổi bọt – [Bubble Sort](https://en.wikipedia.org/wiki/Bubble_sort)
180+
181+
```js
182+
function bubbleSort(array){
183+
for(let i = 0; i < array.length - 1; i++){
184+
for(let j = array.length - 1; j > i; j--){
185+
if(array[j] < array[j-1]){
186+
let t = array[j];
187+
array[j] = array[j - 1];
188+
array[j - 1] = t;
189+
}
190+
}
191+
}
192+
}
193+
```
194+
195+
### Thuật toán [Shaker Sort](https://en.wikipedia.org/wiki/Cocktail_shaker_sort)
196+
197+
```js
198+
function shakerSort(array){
199+
let left, right, k;
200+
201+
left = 0;
202+
right = array.length - 1;
203+
k = array.length - 1;
204+
205+
while(left < right)
206+
{
207+
for(let j = right; j > left; j--)
208+
{
209+
if(array[j] < array[j - 1])
210+
{
211+
let t = array[j];
212+
array[j] = array[j - 1];
213+
array[j - 1] = t;
214+
k = j;
215+
}
216+
}
217+
left = k;
218+
219+
for (let j = left; j < right; j++)
220+
{
221+
if (array[j] > array[j + 1])
222+
{
223+
let t = array[j];
224+
array[j] = array[j + 1];
225+
array[j + 1] = t;
226+
k = j;
227+
}
228+
}
229+
right = k;
230+
}
231+
}
232+
```
233+
234+
### Sắp xếp nhanh – [Quick Sort](https://en.wikipedia.org/wiki/Quicksort)
235+
236+
```js
237+
function quickSort(array, left, right){
238+
let l = left, r = right;
239+
let m = Math.floor((l + r) / 2);
240+
let pivot = array[m];
241+
242+
while(l <= r){
243+
while(array[l] < pivot) l++;
244+
while(array[r] > pivot) r--;
245+
if(l <= r){
246+
let t = array[l];
247+
array[l] = array[r];
248+
array[r] = t;
249+
l++;
250+
r--;
251+
}
252+
}
253+
254+
if(l < right) quickSort(array, l, right);
255+
if(r > left) quickSort(array, left, r);
256+
}
257+
```
258+
259+
### Sắp xếp trộn – [Merge Sort](https://en.wikipedia.org/wiki/Merge_sort)
260+
261+
```js
262+
function merge(array, left, m, right){
263+
let l = left, r = m + 1;
264+
let tmp = [];
265+
266+
while(l <= m && r <= right){
267+
if(array[l] < array[r]) tmp.push(array[l++]);
268+
else tmp.push(array[r++]);
269+
}
270+
271+
while(l <= m) tmp.push(array[l++]);
272+
while(r <= right) tmp.push(array[r++]);
273+
274+
for(let i = 0; i < tmp.length; i++)
275+
array[i + left] = tmp[i];
276+
}
277+
278+
function mergeSort(array, left, right){
279+
if(left < right){
280+
let m = Math.floor((left + right) / 2);
281+
mergeSort(array, left, m);
282+
mergeSort(array, m + 1, right);
283+
merge(array, left, m, right);
284+
}
285+
}
286+
```
287+
288+
### Sắp xếp vun đống – [Heap Sort](https://en.wikipedia.org/wiki/Heapsort)
289+
290+
```js
291+
function heapify(array, N, i){
292+
let left = 2*i + 1, right = 2*i + 2, largest;
293+
294+
if(left < N && array[left] > array[i]) largest = left;
295+
else largest = i;
296+
297+
if(right < N && array[right] > array[largest]) largest = right;
298+
299+
if(largest != i){
300+
let t = array[i];
301+
array[i] = array[largest];
302+
array[largest] = t;
303+
heapify(array, N, largest);
304+
}
305+
}
306+
307+
function buildHeap(array){
308+
let m = Math.floor(array.length / 2 - 1);
309+
for(let i = m; i >= 0; i--)
310+
heapify(array, array.length, i);
311+
}
312+
313+
function heapSort(array){
314+
buildHeap(array);
315+
316+
for(let i = array.length - 1; i >= 0; i--) {
317+
let t = array[0];
318+
array[0] = array[i];
319+
array[i] = t;
320+
321+
heapify(array, i, 0);
322+
}
323+
}
324+
```
325+
326+
Trên đây là những vấn đề cơ bản về Array Sorting, cùng với một số thuật toán sắp xếp. Theo tôi, đây là những kiến thức cơ bản và có thể được áp dụng rất nhiều.
327+
328+
Cuối cùng, xin chào và hẹn gặp lại ở bài viết sau trong series [JavaScript cơ bản](https://completejavascript.com/category/javascript-co-ban/).
329+
330+
Thân ái,
331+
332+
## Tham Khảo
333+
334+
* [Array.prototype.sort()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort?v=control)
335+
336+
**Bản gốc**: [Blog Complete JavaScript](https://completejavascript.com/array-sorting-van-de-muon-thuo/)

0 commit comments

Comments
 (0)