选择排序
原理:
- 找最小(大)元素
- 放到最前面
- 重复 1, 2步骤
- 直到所有元素均排序完毕
时间复杂度:О(n²)
/*选择排序的递归写法*/
let minIndex = (numbers) => {
let index = 0;
for(let i=1; i<numbers.length; i++) {
if(numbers[i] < numbers[index]) {
index = i;
}
}
return index;
}
let sort= (numbers) => {
if(numbers.length > 2) {
let index = minIndex(numbers);
let min = numbers[index];
numbers.splice(index, 1); //从numbers里删除min
return [min].concat(sort(numbers));
} else {
return numbers[0] < numbers[1] ? numbers : numbers.reverse();
}
}
/*选择排序的循环写法*/
let sort = (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;
}
let swap = (array, i, j) => {
let temp = array[i];
array[i] = array[j];
array[j] = temp;
}
let minIndex = (numbers) => {
let index = 0;
for(let i=1; i<numbers.length; i++){
if(numbers[i] < numbers[index]){
index = i;
}
}
return index;
}
快速排序
原理:
- 选个基准值,随便选
- 跟别人比 大的放后面,小的放前面
- 重复 1,2步骤
- 直到所有元素均排序完毕
时间复杂度:О(n log2 n)
/*快速排序的递归写法*/
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 = [];
let 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));
}
归并排序
原理:
- 申请空间,使其大小为两个已经排序序列之和,该空间用来存放合并后的序列
- 设定两个指针,最初位置分别为两个已经排序序列的起始位置
- 比较两个指针所指向的元素,选择相对小的元素放入到合并空间,并移动指针到下一位置
- 重复步骤3直到某一指针超出序列尾
- 将另一序列剩下的所有元素直接复制到合并序列尾
时间复杂度:О(n log2 n)
/*归并排序的递归写法*/
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;
let sortedArr;
if(a[0] > b[0]){
sortedArr = [b[0]].concat(merge(a, b.slice(1)));
return sortedArr;
} else {
sortedArr = [a[0]].concat(merge(a.slice(1), b));
return sortedArr;
}
}
计数排序
原理:
- 先遍历一遍数组,创建空的哈希表
- 把遍历的数组元素和计数放入哈希表,记录数组中最大元素
- 遍历哈希表,遍历次数为数组中最大元素值,把哈希表中存在的值放入新数组中
时间复杂度:О(n + max)
/*计数排序的循环写法*/
let countSort = arr => {
let hashTable = {}, max = 0, result = [];
for(let i=0; i<arr.length; i++) { //遍历数组
if(!(arr[i] in hashTable)) {
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 k=0; k<hashTable[j]; k++) {
result.push(j);
}
}
}
return result;
}