js数组排序
1.快速排序
var arr = [1, 2, 5, 6, 3, 1, 4]; function mySort(arr) { if (arr.length <= 1) { return arr; } // 获取中间值的索引 var len = Math.floor(arr.length / 2); // 截取中间值 var middle = arr.splice(len, 1); var left = []; var right = []; for (var i = 0; i < arr.length; i++) { if (middle > arr[i]) { left.push(arr[i]) } else { right.push(arr[i]) } } return mySort(left).concat(middle, mySort(right)) } console.log(mySort(arr))//[ 1, 1, 2, 3, 4, 5, 6 ]
2.冒泡排序
思想:冒泡排序思想:每一次对比相邻两个数据的大小,小的排在前面,如果前面的数据比后面的大就交换这两个数的位置
要实现上述规则需要用到两层for循环,外层从第一个数到倒数第二个数,内层从外层的后面一个数到最后一个数
var bubbleSort=function(arr){ for(var i=0;i<arr.length-1;i++){ for(var j=i+1;j<arr.length;j++){ if(arr[i]>arr[j]){//如果前面的数据比后面的大就交换 var temp=arr[i]; arr[i]=arr[j]; arr[j]=temp; } } } return arr; }
// 优化,加入标识,如果不需要交换跳出循环
function bubbleSort(arr) {
for (let i = 0; i < arr.length; i++) {
let flag = false
for (let j = 1; j < arr.length; j++) {
if (arr[j - 1] > arr[j]) {
const temp = arr[j - 1]
arr[j - 1] = arr[j]
arr[j] = temp
flag = true
}
}
if (!flag) {
break
}
}
return arr
}
console.log("The result is:"+bubbleSort(arr));
3.插入排序
/** * 插入排序的工作原理是通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入 * 1.默认从 i = 1 开始判断,这样 preIndex 自然是内部循环的游标; * 2.current 保存 arr[i],通过循环来确定 current 的最终位置; * 3.每个内循环开始的时候,arr[i] === current === arr[preIndex + 1],所以在内循环首次时 arr[preIndex + 1] = arr[preIndex] * 的时候不必担心 arr[i] 的值丢失; * 4.总体思路是,需要排位的元素先额外缓存起来,然后套用内循环,使得需要调整的元素赋值给它后面的一个位置上, * 形成依次挪位,最后因为内循环在判断条件不生效的时候停止意味着找到了需要排位的元素的正确位置,然后赋值上去,完成排序。 */ const arr = [2, 1, 8, 4, 9, 9, 12, 32, 7, 5] function insertionSort(arr) { let len = arr.length let preIndex, current for (let i = 1; i < len; i++) { preIndex = i - 1 current = arr[i] while (preIndex >= 0 && arr[preIndex] > arr[i]) { arr[preIndex + 1] = arr[preIndex] preIndex-- } arr[preIndex + 1] = current } return arr } console.log(insertionSort(arr));
4.归并排序
/** * 它采用了分治策略,将数组分成2个较小的数组,然后每个数组再分成两个更小的数组, * 直至每个数组里只包含一个元素,然后将小数组不断的合并成较大的数组, * 直至只剩下一个数组,就是排序完成后的数组序列。 */ const arr = [2, 1, 8, 4, 9, 9, 12, 32, 7, 5] function mergeSort(arr) { if (arr.length < 2) { return arr } let middleIndex = Math.floor(arr.length / 2) let left = arr.slice(0, middleIndex) let right = arr.slice(middleIndex) return merge(mergeSort(left), mergeSort(right)) } function merge(left, right) { let result = [] while (left.length && right.length) { if (left[0] < right[0]) { result.push(left.shift()) } else { result.push(right.shift()) } } while (left.length) { result.push(left.shift()) } while (right.length) { result.push(right.shift()) } return result } console.log(mergeSort(arr));
5.计数排序
// 利用对象key自动排序 const arr = [2, 1, 8, 4, 9, 7, 12, 32, 7, 5] function countingSort(arr) { let obj = {} let len = arr.length for (let i = 0; i < len; i++) { if (!obj[arr[i]]) { obj[arr[i]] = 1 } else { obj[arr[i]]++ } } let index = 0 for (const key in obj) { while (obj[key] > 0) { arr[index] = Number(key) obj[key]-- index++ } } return arr } console.log(countingSort(arr, 32));
6.希尔排序
/** * 希尔排序是按一定的间隔对数列进行分组,然后在每一个分组中做插入排序; * 随后逐次缩小间隔,在每一个分组中做插入排序...直到间隔等于1,做一次插入排序后结束。 */ const arr = [2, 1, 8, 4, 9, 9, 12, 32, 7, 5] function shellSort(arr) { let n = arr.length; for (let gap = Math.floor(n / 2); gap > 0; gap = Math.floor(gap / 2)) { for (i = gap; i < n; i++) { let j = i current = arr[i] while (j - gap >= 0 && current < arr[j - gap]) { arr[j] = arr[j - gap] j = j - gap } arr[j] = current } } return arr; } console.log(shellSort(arr));
7.选择排序
/** * 从未排序的序列中找到最大(或最小的)放在已排序序列的末尾(为空则放在起始位置),重复该操作,知道所有数据都已放入已排序序列中。 */ const arr = [2, 1, 8, 4, 9, 12, 32, 7, 5] function selectSort(arr) { let indexMin, len = arr.length for (let i = 0; i < len - 1; i++) { indexMin = i for (let j = i; j < len; j++) { if (arr[indexMin] > arr[j]) { indexMin = j } } if (indexMin !== i) { const temp = arr[i] arr[i] = arr[indexMin] arr[indexMin] = temp } } return arr } console.log(selectSort(arr))