演算法之排序篇
阿新 • • 發佈:2018-12-21
排序=比較+交換=無序區+有序區
js自帶的排序,sort()函式。
sort()函式本質是上把所有的元素轉換成String再排序,通過ASCII來排序,就會造成大小寫,數字比較不是你想的結果
所以不推薦使用 arr.sort();
幸運的是,sort()方法是一個高階函式,可以接受一個比較函式來實現自定義的排序。修改了原陣列
'use strict';
var arr=[2,1,23,4,2,4,4];
arr.sort(function (x,y) {
if(x>y){
return 1
}
if(x<y){
return -1;
}
return 0;
});
console.log("+++++++++++++",arr); 1 2 2 4 4 4 23
若對字串排序,要忽略大小寫
ar arr = ['Google', 'apple', 'Microsoft']; arr.sort(function (s1, s2) { x1 = s1.toUpperCase(); x2 = s2.toUpperCase(); if (x1 < x2) { return -1; } if (x1 > x2) { return 1; } return 0; }); // ['apple', 'Google', 'Microsoft']
1、氣泡排序:
在無序區比較相鄰的兩個數,如果前一個數大於後一個數,就將這兩個數換位置。每一次遍歷都會將本次遍歷最大的數冒泡到最後。為了將n個數排好序,需要n-1次遍歷。 如果某次遍歷中,沒有調整任何兩個相鄰的數的位置關係,說明此時陣列已排好序,可以結束程式。
<script> arr = [2, 3, 5, 16, 1, 2, 6, 3, 2] paixu(arr); function paixu(arr) { var flag = true; for (var i = 1; i < arr.length; i++) { //表示本次是第i次遍歷 for (var j = 0; j < arr.length - i; j++) { // 比較相鄰的元素 if (arr[j] > arr[j + 1]) { // js方法交換 // var temp=arr[j]; // arr[j]=arr[j+1]; // arr[j+1]=temp; // es6方法交換 [arr[j], arr[j + 1]] = [arr[j + 1], arr[j]]; flag = false; } } // 走完j後還是沒有交換flag=false if (flag) { break; } } console.log("+++++", arr); }
2、選擇排序:
第i輪遍歷arr[0:n-i]選出最大的數,與arr[n-i]互換。
輸出是原序列的一個重排 ,它們通過對陣列中的元素進行比較來實現排序,
// 自定義原型函式 如splice map等都是陣列本身的原型方法。
Array.prototype.selectSort = function () {
var i, j;
for (i = 1; i <=this.length-1; i++) { // 共進行n-1趟排序 表示本次是第i趟排序,確定第幾大的位置
var maxIndex = 0;
// 比較 找到無序區裡最大的值
for (j = 0; j <= this.length - i; j++) { //訪問子序列為arr[0:this.length-i]
if (this[j] > this[maxIndex]) {//當前值大於當前最大值時,記錄索引
// 找到最大的值
maxIndex = j;
}
}
//交換 將最大值和有序區位置進行交換
[this[this.length - i], this[maxIndex]] = [this[maxIndex], this[this.length - i]]
}
};
var arr = [43, 21, 10, 5, 9, 15, 32, 57, 35];
arr.selectSort();
console.log(arr);
3、插入排序:有序區+無序區
<script>
Array.prototype.insertSort = function () {
var i, j;
for (i = 1; i < this.length; i++) { // i表示要插入的數字的索引,從第二個數開始前插
var val = this[i]; // 記錄當前要插入陣列的大小
/*
* 用指標j(從後向前遍歷i-1得位置開始)來遍歷第i個數字前面的,已經排好序的子陣列。當j沒有指到頭,並且j的數字大於要插入的數字時,說明
* j還要向前遍歷,直到發現一個比要插入數字小的位置pos,然後將這個數字插到pos+1處。如果j已經指到頭了,
* 到了-1了還沒有找到比當前數字小的位置,就把當前數字放在索引0處。
* */
for (j=i-1;j>=0&&this[j]>val;j--) {
// 資料後移
this[j+1]=this[j];
}
// 插入val
this[j+1]=val;
}
}
var arr = [43, 21, 2, 3, 4, 1, 4];
arr.insertSort();
console.log("++++++++++", arr)
</script>
4、快速排序
<script> Array.prototype.quickSort=function (asc=true) { quickSort(this,0,this.length-1,asc); } function quickSort(arr,start,end) { if(start<end){ // pivot記錄樞軸插入的位置; var pivot= partition(arr,start,end); quickSort(arr,start,pivot-1); // 遞迴的對temp左邊的元素進行排序 quickSort(arr,pivot+1,end); // 遞迴的對temp右邊的元素進行排序 } } // 下面這個函式完成一趟排序 function partition(arr,start,end) { // temp是樞軸,是待排序元素的第一個,一趟排序後,樞軸左邊小於等於temp,右邊大於等於temp var temp=arr[start]; while (start!=end) { while (start<end&&arr[end]>temp) {end--;} // 從右向左掃描找到一個小於temp的元素 if(start<end){ arr[start]=arr[end]; // 把右邊值放到左邊 start++; // start 右移 } while (start<end&&arr[start]<temp) {start++;} if(start<end){ arr[end]=arr[start];// 把左邊值放到右邊 end--; // end左移 } } arr[start]=temp; //將temp放到最終位置,完成一次排序(小於或等於)temp(大於或等於) return start; } var arr=[49,38,65,97,76,13,27,49]; arr.quickSort(); console.log("+++++++++++",arr); </script>