一、求数组最值 &排序 & 求最值下标
- 1请写一个 min 函数,要求 min(numbers)能返回数组 numbers 中的最小数字。
let min = (numbers) => {
if(numbers.length > 2){
return min(
[numbers[0], min(numbers.slice(1))]
)
}else{
return Math.min.apply(null, numbers)
}
}
1.2 请写一个 max 函数,要求 max(numbers) 能返回数组 numbers 中的最大数字。
let max = (numbers) =>{
if(numbers.length > 2){
return max([numbers[0],max(numbers.slice(1))])
}else{
return Math.max.apply(null,numbers)
}
}
let b = max ([12,4,2,5])
console.log(b)
2.1 请写出一个 sort 函数,要求 sort(numbers) 能返回一个把 numbers 从小到大排列的数组
let min = (numbers) => {
if(numbers.length > 2){
return min(
[numbers[0], min(numbers.slice(1))]
)
}else{
return Math.min.apply(null, numbers)
}
}
let minIndex = (numbers) =>
numbers.indexOf(min(numbers))
let sort = (numbers) => {
if(numbers.length > 2){
let index = minIndex(numbers)
let min = numbers[index]
numbers.splice(index, 1)
return [min].concat(sort(numbers))
}else{
return numbers[0]<numbers[1] ? numbers :
numbers.reverse()
}
}
2.2 请写出一个 sort 函数,要求 sort(numbers) 能返回一个把 numbers 从大到小排列的数组
let max = (numbers) => {
if(numbers.length > 2){
return max(
[numbers[0], max(numbers.slice(1))]
)
}else{
return Math.max.apply(null, numbers)
}
}
let maxIndex = (numbers) =>
numbers.indexOf(max(numbers))
let reverse = (numbers) => {
if(numbers.length > 2){
let index = maxIndex(numbers)
let max = numbers[index]
numbers.splice(index, 1)
return [max].concat(reverse(numbers))
}else{
return numbers[0] > numbers[1] ? numbers :numbers.reverse()
}
}
let a = reverse.call(null,[12,11,10,9,8,7])
console.log(a)
3. 查找数组中最小值的下标
let index =(numbers) =>{
let index = 0
for(i = 1;i < numbers.length;i++){
if(numbers[i]<numbers[index])
index = i;
}
return index
}
let a = index.call(null,[12,13,14,11,9,6,7])
console.log(a) // 5
二、 4种排序方法
- 选择排序
- 在数组中找到最小值的下标,和当前的换位置,排除这个最小值后,再从剩下的数组中找最小的,互换下标~
- 时间复杂度O(n^2)
let minIndex =(numbers) =>{
let index = 0
for(i = 1;i < numbers.length;i++){
if(numbers[i]<numbers[index])
index = i;
}
return index
}
let swap = (numbers, index, i) =>{
let temp = numbers[index]
numbers[index] = numbers[i]
numbers[i] = temp
}
let sort = (numbers) =>{
for(let i=0;i<numbers.length-1;i++){
console.log(`--------`)
console.log(`i:${i}`)
let index = minIndex(numbers.slice(i))+i
console.log(`index:${index}`)
console.log(`min: ${numbers[index]}`)
if(index!=i){
swap(numbers, index, i)
console.log(`swap: ${index}: ${i}`)
}
console.log(numbers)
}
return numbers
}
let c = sort.call(null,[2,13,4,5,16])
console.log(`最终结果:`)
console.log(c) // [2,4,5,13,16]
去掉 console.log 版
//循环,排序 小——大
let minIndex =(numbers) =>{
let index = 0
for(i = 1;i < numbers.length;i++){
if(numbers[i]<numbers[index])
index = i;
}
return index
}
let swap = (numbers, index, i) =>{
let temp = numbers[index]
numbers[index] = numbers[i]
numbers[i] = temp
}
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 c = sort.call(null,[2,13,4,5,16])
console.log(c)
- 快速排序
- (找个中间数,比他大放在右,比他小放在左)
- 时间复杂度 O(n log2 n)
//快速排序 [1,12,8,9,19,4]
let quickSort = (numbers) =>{
if(numbers.length <= 1){return numbers}
let pivotIndex = Math.floor(numbers.length/2)
console.log(`----------`)
console.log(`pivotIn: ${pivotIndex}`)
let pivot = numbers.splice(pivotIndex,1)[0]
console.log(`pivot: ${pivot}`)
let left = []
let right = []
for(let i=0;i<numbers.length;i++){
if(numbers[i]<pivot){
console.log(numbers[i])
left.push(numbers[i])
console.log(`left:${left}`)
}else{
right.push(numbers[i])
console.log(`right:${right}`)
}
}
return quickSort(left).concat([pivot],quickSort(right))
}
let c = quickSort.call(null,[1,12,8,9,19,4])
console.log(c)
let pivot = numbers.splice(pivotIndex,1) [0]
因为: numbers.splice(pivotIndex,1) 返回的是数组 如:[9], 在后面加 [0],才是数字 9
if(numbers.length <=1){return numbers} 这句关键要加上
- 归并排序 (merge sort)
- 没有基准,左边一半自觉排好序,右边一半自觉排好序,两边从小的依次对比,然后左右两边合并(merge)起来。
- 时间复杂度 O(n log2 n)
![70d0c591b67b1ef29fc9ce146ad918df.png](https://i-blog.csdnimg.cn/blog_migrate/8405f6d65cda6198464178f058f91e3a.jpeg)
//插 冒 归 基
//快 选 堆 希
//归并排序 [1,12,8,9,19,4]
//左右分队 归1 再merge
let mergeSort = (arr) =>{
if(arr.length===1){
return arr
}
let left = arr.slice(0,Math.floor(arr.length/2))
let right = arr.slice(Math.floor(arr.length/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]? [a[0]].concat(merge(a.slice(1),b)):[b[0]].concat(merge(a,b.slice(1)))
}
let c = mergeSort.call(null,[1,12,8,9,19,4])
return 后面不能换行!!!,巨坑,别再踩了!!! 注意:return [a[0]].concat~
- 计数排序(哈希)
- 像找扑克牌一样,A 4个放在一起,2放4个在一起,一直到K...
- 时间复杂度O(n+max-min)
//计数排序
let CountSort = (arr) =>{
let result = [], HashTable = {}, max = 0
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 z=0;z<HashTable[j];z++){
result.push(j)
}
}
}
return result
}
let a = CountSort.call(null,[1,3,2,4,2,2,5,6,6,14,1,8,4,9,12])
console.log(a)
console.log(HashTable[2])
表示数组中的2 ,出现了几次
所以使用HashTable[j],查看j出现的次数