概述
桶排序:
引入include
核心代码:
int a[10]= {9,6,3,8,5,2,7,4,1,0};
for(int i=0; i<10; i++)
cout<<a[i]<<" “;
cout<<endl;
sort(a,a+10); #注意这是a+10
for(int i=0; i<10; i++)
cout<<a[i]<<” ";
return 0;
冒泡排序:
思路:如果是升序,相邻的两个数进行比较,比较大的放在后面,比较了n-1次,第一次循环结束后,最大数被排在了最后面,一次进行循环,需要进行n-1次循环,
#include
using namespace std;
int main () {
int n;
int temp;
int a[100];
cin>>n;
for(int i=0;i<n;i++) {
cin>>a[i];
}
for(int i=0;i<n-1;i++) {
for (int j = 1;j<n-i;j++) {
if(a[j-1] > a[j]) {
temp = a[j];
a[j] = a[j-1];
a[j-1] = temp;
}
}
}
for(int i=0;i<n;i++) {
cout<<a[i];
}
return 0;
}
选择排序(升序):
具体思路:第一次循环,将第一个数与后面的n-1个数进行比较,选出最小的放在第一个位置,;下一轮,从第二个数开始,与剩下的n-2个数进行比较,以此类推;
#include
using namespace std;
void print(int array[],int n) {
for(int i=0;i<n;i++) {
cout<<array[i]<<" ";
}
cout<<endl;
}
int selectsort(int array[],int n) {
int count = 0;//记录交换次数
int temp;
int min_index = 0;//假设最小值所在的位置,默认为0,即第一个元素
for(int i=0;i<n-1;i++) {
//假设当前的元素是第i小的元素,保存当前位置
min_index = i;
for(int j = i+1;j<n;j++) {
cout << “第” << (i + 1) << “趟第” << (j + 1) << “次排序” << endl;
//判断当前的元素是否小于假设的第i小元素
if (array[min_index]>array[j]) {
//重新设置第i小的元素位置
min_index = j;
}
}
//判断当前位置的元素是否等于假设的第i小元素,如果不等于则交换这两个元素
if (min_index != i)
{
temp = array[min_index];
array[min_index] = array[i];
array[i] = temp;
count++;
}
}
return count;
}
int main () {
// 定义排序的数组
int array[] = {1,3,8,5,9,4,10,7,2,6};
// 对数组进行排序
int count = selectsort(array,10);
// 对排序后的数组进行输出
print(array,10);
cout<<count;
return 0;
}
快速排序:
先看这样一个未排序之前的数列 6 1 2 7 9 3 4 5 10 8 ,然后再看一下它的变形:3 1 2 5 4 6 9 7 10 8。
会发现这十个数以6为基准分成了两个阵营:左边都比6小,右边都比6大。这里将6称为基准数,它将扮演重要的角色。
快速排序正是这样一个利用基准数不断分阵营的过程。
#include
using namespace std;
int a[100],n;
void quicksort(int left,int right) {
int i,j,t,temp;
if(left>right)
return;
temp=a[left];
i=left;
j=right;
while(i!=j) {
while(a[j]>=temp&&j>i)
j--;
while(a[i]<=temp&&j>i)
i++;
if(i<j) {
t=a[i];
a[i]=a[j];
a[j]=t;
}
}
a[left]=a[i];
a[i]=temp;//交换基数
quicksort(left,i-1);
quicksort(i+1,right);
}
int main() {
cout<<“排几个数:”;
cin>>n;
for(int i=0; i<n; i++) {
cin>>a[i];
}
quicksort(0,n-1);
for(int i=0; i<n; i++) {
cout<<a[i]<<" ";
}
}
一、数组扁平化
const bianping = (array) => {
return bianping.reduce((result,item) => {
return arrar.concat(Array.isArray(item) ? bianping(item):item)
})
}
let arr = [1,2,3,[22,5]];
console.log(bianping(arr));
二、深拷贝浅拷贝
function deepClone(target) {
// 基本数据类型直接返回
if (typeof target !== 'object') {
return target
}
// 引用数据类型特殊处理
// 判断数组还是对象
const temp = Array.isArray(target) ? [] : {}
for (const key in target) {
// 递归
temp[key] = deepClone(target[key])
}
return temp
}
const a = {
name: 'sunshine_lin',
age: 23,
hobbies: { sports: '篮球', tv: '雍正王朝' },
works: ['2020', '2021']
}
const b = deepClone(a)
console.log(b)
三、数组去重
let set = new Set([1,2,5,4,4,4,5,3]);
let a = [...set];
console.log(a);
for(let item of a){
console.log(item)
}
console.log(Object.prototype.stringfl.call(a));
四、各类数组方法
filter:一个新的、由通过测试的元素组成的新数组,如果没有数组元素通过测试,则 返回空数组
map:由原数组的每个元素执行回调函数后的结果组成的新数组
foreach: 方法对数组的每个元素执行一次给定的函数。
**concat:**用于合并两个或者多个数组,此方法不会改变现有数组,而是返回一个新数组
**entries:**返回一个新的数组迭代对象,该对象包含数组中每个索引的键值对
const array1 = ['a', 'b', 'c'];
const iterator1 = array1.entries();
console.log(iterator1.next().value);
// expected output: Array [0, "a"]
console.log(iterator1.next().value);
// expected output: Array [1, "b"]
**every:**测试一个数组内的所有元素是否都能通过某个指定函数的测试,返回一个布尔值
**fill:**用一个固定值填充数组中从起始索引到终止索引内的全部元素,不包括终止索引
**find:**返回数组中满足提供等我函数测试的第一个元素的值,否则返回undefined
findIndex:返回数组中满足提供等我函数测试的第一个元素的索引,没有则返回-1
**flat:**按照一个可以指定的深度递归遍历数组,并将所有元素与遍历到的子数组中的元素合并为一个新数组返回。
**foreach:**对数组的每一个元素执行一次给定的函数
**Array.from():**从一个类似数组或者可迭代对象(类似数组的对象(array-like object)和可遍历(iterable)的对象(包括 ES6 新增的数据结构 Set 和 Map))创建一个新的,浅拷贝的数组实例
**includes:**判断一个数组是否包含指定的值,返回的是一个bool类型
shift:从数组中删除第一个元素,并返回该元素的值。此方法更改数组的长度。
unshift:将一个或多个元素添加到数组的开头,并返回该数组的新长度(该方法修改原有数组**)**
五、apply()、bind()、call()
call:
call
核心:
1.它接受一个参数obj,这个参数就是函数的作用域,这个obj参数是一个Object类型,如果_call()方法没有传递任何参数,则默认执行作用域为window对象,代码实现如下:
// 全局添加一个_call方法
Function.prototype._call = function(obj) {
// 参数是否存在,如果存在则转为Object类型,否则直接取window对象为默认对象
var _obj = obj ? Object(obj) : window
}
2.重要的步骤来了,要让函数的执行作用域为参数obj,那么这个函数必须是obj的一个属性或方法,因此这里为_obj添加一个fn方法,并把这个函数赋给这个方法:
// 全局添加一个_call方法
Function.prototype._call = function(obj) {
// 参数是否存在,如果存在则转为Object类型,否则直接取window对象为默认对象
var _obj = obj ? Object(obj) : window
_obj.fn = this
}
3.接下来该获取其他函数参数了,因为这里正在实现call方法,我们只好去遍历arguments对象,把这些参数转为真正的数组,并拆分为参数传给函数并执行:
var argArr = []
// 遍历参数,因为首项是obj,所以要从次项开始遍历才是参数
for (var i = 1; i < arguments.length; i++) {
argArr.push('arguments['+ i + ']')
}
// 执行obj的fn方法,把arg拆分
eval("_obj.fn(" + argArr + ")")
// _obj.fn(...argArr)
也可以用es6的数组方法Array.from()去遍历arguments对象
完整代码:
// 全局添加一个_call方法
Function.prototype._call = function(obj) {
// 参数是否存在,如果存在则转为Object类型,否则直接取window对象为默认对象
var _obj = obj ? Object(obj) : window
// 把调用_call()方法的那个函数保存在目标对象中
_obj.fn = this
// 保存参数的数组
// var argArr = [...arguments].slice(1)
var argArr = Array.from(arguments).slice(1)
// 遍历参数,因为首项是obj,所以要从次项开始遍历才是参数
/* for (var i = 1; i < arguments.length; i++) {
argArr.push('arguments['+ i + ']')
} */
// 执行obj的fn方法,把arg拆分
// eval("_obj.fn(" + argArr + ")")
_obj.fn(...argArr)
// 执行完之后删除这个方法
delete _obj.fn
}
apply:
Function.prototype._apply = function(obj, argArr) {
// 如果obj不存在则默认window对象
var _obj = obj ? obj : window
// 给_obj添加fn方法
_obj.fn = this
// 获取第二个数组参数
var arg = []
// 当这个参数数组不存在或者为空时,直接执行函数,否则把数组拆分后传递给函数并执行
if (!argArr || argArr.length == 0) {
_obj.fn()
} else {
for (var i = 0; i < argArr.length; i++) {
arg.push('argArr['+ i + ']')
}
// 执行obj的fn方法,把arg拆分
eval("_obj.fn(" + arg + ")")
}
// 移除这个方法
delete _obj.fn
}
bind():
太難了 孩子放棄了
六、防抖
七、节流
<body>
<input id="search" type="text" placeholder="请输入要查询的内容">
<script>
var search = document.getElementById('search');
function getUserAction() {
console.log('执行查询操作', +new Date());
};
function debounce(func, wait) {
var timeout;
return (args) => {
if (timeout) clearTimeout(timeout)
timeout = setTimeout(func, wait);
}
}
const debounceAjax = debounce(getUserAction, 1000)
search.addEventListener('keyup', debounceAjax)
</script>
</body>
八、实现一个New操作符
function New(func) {
var res{};//因为New创建的是一个对象,所以新建一个空对象
if(func.prototype !== null){
res._proto_ = func.prototype;//设置原型
}
//更改this指向
var ret = func.apply(res,Array.prototype.slice.call(arguments,1))//Array.prototype.slice.call(arguments,1);这句话的意思就是说把调用方法的参数截取出来。
if ((typeof ret === "object" || typeof ret === "function") && ret !== null) {
return ret;
}
return res;
}
最后
以上就是现实机器猫为你收集整理的手撕代码ing的全部内容,希望文章能够帮你解决手撕代码ing所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复