前端面试手写题系列 IX
1.手写深拷贝
定义:
什么是深拷贝:拷贝的是对象
什么是浅拷贝:拷贝的是引用
实现:
我们有两种方式实现深拷贝:
// 手写深拷贝
// 1. 使用 JSON.parse(JSON.stringify(obj)) 但是这种方法有局限性,不能拷贝函数
function deepClone(obj) {
return JSON.parse(JSON.stringify(obj))
}
// 2. 使用递归,可以实现真正意义上的深拷贝
function deepClone1(obj) {
if (typeof obj !== 'object') return obj
// 判断是数组还是对象
let res = obj instanceof Array ? [] : {}
for (let key in obj) {
// 判断是否是自身属性,如果不是自身属性,就不需要拷贝
if (obj.hasOwnProperty(key)) {
res[key] = deepClone1(obj[key])
}
}
return res
}
// 测试
let obj = {
name: 'zhangsan',
age: 18,
hobby: ['eat', 'sleep', 'play'],
home: {
city: 'beijing',
province: 'beijing'
},
say: function () {
console.log('hello')
}
}
let objClone = deepClone(obj)
let objClone1 = deepClone1(obj)
// 分别看看结果
console.log(objClone)
console.log(objClone1)
结果:
2.手写快排
什么是快速排序:
快速排序的最坏时间复杂度:
O(nlogn),最坏为 O(n^2)
最坏的情况是每次选取的元素都是最大值或者最小值。
实现思路:
每次选取一个值作为基准,然后将比他小的放在他的左边,比他大的放在他的右边,如此循环。
// 手写快速排序
function quickSort(arr) {
if (arr.length < 2) {
return arr
}
// 选取基准值,我们一般选取数组的中间值,此时就可以将数组分为左右两份
let mid = Math.floor(arr.length / 2)
let temp = arr.splice(mid, 1)[0]
// 我们将比这个值小的放在左边,比这个值大的放在右边
let left = []
let right = []
for (let i = 0; i < arr.length; i++) {
if (arr[i] < temp) {
left.push(arr[i])
} else {
right.push(arr[i])
}
}
// 实际上这里是由一个递归调用的
return [...quickSort(left), temp, ...quickSort(right)]
}
// 测试
let arr = [1, 3, 2, 5, 4, 6, 9, 8, 7]
console.log(quickSort(arr))
结果: