写在前面
上一篇博客实际上就是选择排序,每次找到最小的数放在前面,然后对后面的数做同样的事情
用循环的方式写选择排序
- 算法永远可以用循环或递归的方式写
- 所有递归都可以改成循环
- 重写minIndex,相当于min
function minIndex(numbers){
let index = 0
for(let i = 0;i <= numbers.length;i++){
if(numbers[i] <= numbers[index]){
index = i
}
}
return index
}
重写sort,swap待实现
function sort(numbers){
for(let i = 0;i <= numbers.length;i++){
let index = minIndex(numbers)
swap(numbers,index,i)
}
}
实现swap
function swap(numbers i j){
let temp = numbers[i]
numbers[i] = numbers[j]
numbers[j] = temp
}
大致写好后解决问题,每次给minIndex传递时应该削去已经排好的
function sort(numbers) {
for (let i = 0; i <= ???; i++) {
let index = minIndex(numbers.slice(1))+i;
swap(numbers, index, i);
}
}
- slice 不会修改原数组,只会返回一个浅复制了原数组中的元素的一个新数组。
- splice()方法通过删除或替换现有元素或者原地添加新的元素来修改数组,并以数组形式返回被修改的内容。此方法会改变原数组
- 注意区别
function 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
}
- 选择排序就是把最小值放到前面不管,对剩下的进行同样的操作
用递归的方式写快速排序
function quicksort(numbers) {
if (numbers.length <= 1) {
return numbers;
} else {
let pivotIndex = Math.floor(arr.length / 2);
let pivot = numbers.splice(pivotIndex, 1)[0];
let right = [];
let left = [];
for (let i = 0; i < numbers.length; i++) {
if (numbers[i] < pivot) {
left.push(numbers[i]);
} else {
right.push(numbers[i]);
}
}
return quicksort(left).concat([pivot], quicksort(right));
}
}
- 快排让我知道,递归可以递归调用两次,先一分为二,分别递归
用递归的方式写归并排序
分成两队直到每队剩一个人相当于已经排好了
关键在于每次合并是都要排序,所以迭代时mergesort外面一点有个merge
function mergesort(numbers) {
if (numbers.length === 1) {
return numbers;
}
let left = arr.slice(0, Math.floor(numbers.length / 2));
let right = arr.slice(Math.floor(numbers.length / 2));
return merge(mergesort(left), mergesort)(right);
}
function merge(a, b) {
if (a.length === 0) return b;
if (b.length === 0) return a;
if (a[0] > b[0]) {
[b[0]].concat(merge(a, b.slice(1)));
} else {
[a[0]].concat(merge(a.slice(1), b));
}
}
计数排序
function countSort(arr){
let hashTable = {}
max = 0
result = []
for(let i = 0;i <= numbers.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 i = 0;i <= hashTable[j];i++){
result.push(j)
}
}
}
return result
}
- 主要就是制造一个哈希表,并且用in来遍历哈希表
- 分清楚key和value
时间复杂度
- 选择排序0(n^2)
- 快速排序O(n*log2 n)
- 归并排序0(n*log2 n)
- 计数排序0(n + max)
- n次排序怎么样都必须排,乘一个衰落次数