携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第14天,点击查看活动详情
前言
排序与搜索
排序:把某个乱序的数组变成升序或降序的数组
搜索:找出数组中某个元素的下标
时间复杂度
空间复杂度
排序
1. 冒泡排序(时间复杂度n^2)
//冒泡排序
for(var i = 0; i < nums.length - 1; i++) {
for(var j = 0; j < nums.length - i - 1; j++) {
if(nums[j] > nums[j+1]) {
[nums[j],nums[j+1]] = [nums[j+1],nums[j]]
}
}
}
return nums
2. 选择排序(时间复杂度n^2)
for(var i = 0; i < nums.length; i++) {
for(var j = i + 1; j < nums.length; j++) {
if(nums[i] > nums[j]) {
[nums[i],nums[j]] = [nums[j],nums[i]]
}
}
}
return nums
3. 插入排序(时间复杂度n^2)
从数组第二个元素开始,往前比较
for(var i = 1; i < nums.length; i++) {
for(var j = 0; j < i; j++) {
if(nums[i] < nums[j]) {
[nums[i],nums[j]] = [nums[j],nums[i]]
}
}
}
return nums
4. 归并排序mergeSort(时间复杂度nlogn)
比前面的排序更好,时间复杂度更低
分:把数组劈成两半,再递归对子数组进行“分”操作,直到分成一个个单独的数
合:把两个数组合并为有序数组,再对有序数组进行合并,直到全部子数组合并为一个完整数组
- 新建一个空数组res,用于存放最终排序后的数组
- 比较两个有序数组的头部,较小者出队并推入res中
- 如果两个数组还有值,就重复第二步
rec = (nums) => {
//首先把数组劈成两半,再递归对子数组进行“分”操作, let mid = Math.floor(nums.length / 2)
let left = nums.slice(0,mid)
let right = nums.slice(mid,nums.length)
//直到分成一个个单独的数 //递归终止条件
if(nums.length === 1) {
return nums;
}
let orderLeft = rec(left)
let orderRight = rec(right)
//把两个数组合并为有序数组,再对有序数组进行合并,直到全部子数组合并为一个完整数组
//新建一个空数组res,用于存储最终排序后的数组
let res = []
//比较两个有序数组的头部,较小者出队并推入res中
//如果两者还有值,就重复第二步
while(orderLeft.length || orderRight.length) {
if(orderLeft.length && orderRight.length) {
res.push(orderLeft[0] < orderRight[0] ? orderLeft.shift() : orderRight())
}else if(orderLeft.length) {
res.push(orderLeft.shift())
}else if(orderRight.length){
res.push(orderRight.shift())
}
}
return res
}
let nums = rec(nums)
return nums
5. 快速排序(时间复杂度:O(nlogN))
快速排序采用了分而治之思想
分而治之是算法设计中的一种方法,对于一个规模为n的问题,若该问题可以容易地解决(如说规模n较小),则直接解决;否则将其分解为k个规模较小的子问题,这些子问题互相独立且与原问题形式相同,递归地解决这些子问题,然后将各子问题的解合并得到原问题的解。
分区:从数组中任意选择一个“基准”,所有比基准小的元素放在基准前面,比基准大的元素放在基准的后面。
递归:递归地对基准前后的子数组进行分区
var len = arr.length
if(len < 2){ return arr }
var basis = arr[0]
var left = []
var right = []
for(let i = 1; i < len; i++) {
if(arr[i] < basis) {
left.push(arr[i])
} else {
right.push(arr[i])
}
}
return MySort(left).concat([basis], MySort(right))
搜索算法
1. 顺序搜索sequentialSearch(时间复杂度O(n))
- 遍历数组
- 找到跟目标值相等的元素,就返回它的下标
- 遍历结束后,如果没有搜索到目标值,就返回-1
2. 二分搜索binarySearch(时间复杂度O(logn))
注意:前提:数组是有序的
- 从数组中间元素开始,如果中间元素正好是目标值,则搜索结束
- 如果目标值大于或小于中间元素,则在大于或小于中间元素的那一半数组中搜索
let low = 0
let high = this.length - 1
while(low <= hign) {
const mid = Math.floor((low + high) / 2)
const element = this[mid]
if (element < item) {
low = mid + 1
} else if(element > item) {
high = mid - 1
}else {
return mid
}
return -1
}
总结
最后
排序算法只写了一部分,不完整,后续可能会补上,最后,感谢观看!