快速排序
基本思想:(分治)
- 先从数列中取出一个数作为key值,用来比较
- 将比这个数小的数全部放在它的左边,大于它的数全部放在它的右边
- 对左右的两个小数列重复第二步的操作,直到各区间只剩一个数
let quickSort = arr => {
if(arr.length <= 1){ return arr }
let pivotIndex =Math.floor(arr.length / 2)
let pivot = arr.splice(pivotIndex,1)[0]
let left = [],right = []
for(let i = 0 ; i < arr.length ; i++){
if(arr[i] < pivot) {
left.push(arr[i])
}else{
right.push(arr[i])
}
}
return quickSort(left).concat([pivot],quickSort(right))
}
计数排序
基本思路
- 用一个哈希表作记录
- 发现数字N就记N:1,如果再一次发现就加1
- 最后把哈希表的key全部打印出来,假如N:M,那么N需要打印M次
let countSort = arr => {
let hashTable = {} , max = 0 , result = []
for(let i = 0; i < arr.length; i++){
if(!(arr[i] in hashTable)){ // in 判断hashTable中是否含有arr[i]
hashTable[arr[i]] = 1
}else{
hashTable[arr[i]]+=1
}
if(arr[i] > max){ max = arr[i] }
}
for(let j = 0;j <= max ;j++ ){
if(j in hashTable){
for(let i =0 ; i < hashTable[j]; i++){
result.push(j)
}
}
}
return result
}
冒泡排序
基本思想:相邻的两个数比大小,较大的数下沉,较小的数冒起来
let bubbleSort = arr => {
for(let i = 0;i < arr.length-1; i++ ){
for(let j = 0;j < arr.length-i; j++){
if(arr[j] > arr[j+1]){
arr[j] ^= arr[j+1]
arr[j+1] ^= arr[j]
arr[j] ^= arr[j+1]
}
}
}
return arr
}
选择排序
基本思想:
- 在长度为N的无序数组中,第一次遍历n-1个数,找到最小的数值与第一个元素交换;
- 第二次遍历n-2个数,找到最小的数值与第二个元素交换;
- ......
- 第n-1次遍历,找到最小的数值与第n-1个元素交换,排序完成。
let minIndex = (numbers) => {
let index = 0
for(let i = 1;i<numbers.length;i++){
if(numbers[i] < numbers[index]){
index = i
}
}
return index
}
let swap = (array,i,j) => {
array[i] ^= array[j]
array[j] ^= array[i]
array[i] ^= array[j]
}
let selctionSort = numbers => {
for(let i = 0;i < numbers.length-1; i++){
let index = minIndex(numbers.slice(i)) + i
if(index !== i){swap(numbers,index,i)}
}
return numbers
}
插入排序
基本思路:在要排序的一组数中,假定前n-1个数已经排好序,现在将第n个数插到前面的有序数列中,使得这n个数也是排好顺序的。如此反复循环,直到全部排好顺序。
let insertSort = arr => {
let index = 0
for(let i = 1; i < arr.length ; i++){
index = i
for(let j = i - 1; j >= 0; j--){
if(arr[i] < arr[j] ){
index = j
}
}
arr.splice(index,0,arr[i]); //插入arr[i]
arr.splice(i+1,1); // 由于数组变了,所以原先arr[i]的值到arr[i+1]去了,删掉它
}
return arr
}
归并排序
基本思路: 首先考虑下如何将2个有序数列合并。这个非常简单,只要从比较2个数列的第一个数,谁小就先取谁,取了后就在对应数列中删除这个数。然后再进行比较,如果有数列为空,那直接将另一个数列的数据依次取出即可。
let mergeSort = arr => {
let k = arr.length
if(k === 1){ return arr }
let left = arr.slice(0,Math.floor(k/2))
let right = arr.slice(Math.floor(k/2))
return merge(mergeSort(left),mergeSort(right))
}
let merge = (a,b) => {
if(a.length === 0){ return b }
if(b.length === 0){ return a }
return a[0] > b[0] ? [b[0]].concat(merge(a,b.slice(1))) : [a[0]].concat(merge(a.slice(1),b))
}