1、插入排序
function insertSort(arr) {
for (let i = 1; i < arr.length; i++) { //下标从1开始,从后向前比较
let current = arr[i]; //记录当前元素
let pre_index = i - 1; //记录前一个元素下标
while (current < arr[pre_index] && pre_index >= 0) {
arr[pre_index + 1] = arr[pre_index];
pre_index--;
}
arr[pre_index + 1] = current; //确定位置后,赋值
}
return arr;
}
2、快速排序
function quickSort(arr) {
if (arr.length <= 1) return arr;
let left = [],middle = [arr[0]], right = []; //定义三个数组,middle为哨兵元素
for (let index = 1; index < arr.length; index++) {
if (arr[index] < middle[0]) {
left.push(arr[index])
}else {
right.push(arr[index]) //本身一样大的元素也放入右边
}
}
return quickSort(left).concat(middle, quickSort(right)) // 递归并连接
}
3、二分查找(递归和非递归)
//非递归
function BianrySearch(arr,key){
let left = 0,right = arr.length-1;
while(left<=right){
let mid = (left+right)/2;
if(arr[mid]===key) return mid;
if(key > arr[mid]){
left = mid + 1;
}else{
right = mid - 1;
}
}
return -1;
}
//递归
function BianrySearch(arr,left,right,key){
if(left > right) return -1;
let mid = parseInt((left+right)/2);
if(key === arr[mid]) return mid;
if(key > arr[mid]){
BianrySearch(arr,mid+1,right,key);
}else{
BianrySearch(arr,left,mid-1,key);
}
}
4、链表反转
1、链表反转可以一次查找链表保存到数组中,然后数组取反操作
2、(c)1 -> 2 -> 3 -> 4 -> 5
function reserveList(ListNode head){
if (head != null && head.next != null) {
ListNode c = head; //一直指向第一个元素(1)
ListNode b = null; //反转过程中活动的指针,暂存指针
while (c.next != null) {
b = c.next; //第一次执行时:b保存 ‘3’ 元素
c.next = c.next.next; //直接让 1 指向 3
b.next = head; //把2调到最前面,让 2 指向 1
head = b; //调整head指针,由指向 1 变为指向 2
//一次执行后:2 -> 1(c) -> 3 -> 4 -> 5
}
}
return head; //返回反转后的头指针
}
5、命名方式的转换
1、dom_abc => domAbc
const str = 'dom_one'
const reg = /\_(\w)/g;
//all第一个参数代表匹配的全部(_o),第二个参数是匹配的下一个(o)
const str1 = str.replace(reg,(all,letter)=>{
return letter.toUpperCase();
})
console.log(str1) //domOne
//还有一种方法是split('_')分割后,保存到数组中,然后遍历
2、domAbc => dom_abc
function toLine(name) {
return name.replace(/([A-Z])/g,"_$1").toLowerCase();
}
6、实现bind方法
Function.prototype.bind2 = function(context) {
//bind绑定的必须是函数
if(typeof this !== 'function') throw new Error('this is not function!')
var self = this;
var args = [...arguments].slice(1);;
return function() {
var args1 = [...args,...arguments]; //转化成数组并合并参数
self.apply(context, [...args1]); //也可以使用call实现
};
}
7、分析打印结果
function fun(n,o) {
console.log(o);
return {
fun: function (m) {
//这里的fun调用的是最外层的函数fun,不是return中的
return fun(n,m);//n==0,利用了闭包,保存了第一次传的值
}
}
}
var a = fun(0); //undefined
a.fun(1);//1
a.fun(2);//2
a.fun(3);//3
8、变量提升和函数提升问题
函数提升优先级高于变量提升,其中函数提升前提是不能声明为函数表达式:var fun = function(){},且函数提升不会被变量提升覆盖,可以被变量声明可以覆盖。
console.log(a) //打印函数a
function a() {
return 'this is function';
}
console.log(a) //打印函数a
var a = 10;
console.log(a); //10
var b = 20;
var b; //若重复声明的语句无初始值,那么不会对原先变量有任何影响
console.log(b) //20
if(!(c in window)) { // c in window 返回true
var c = 10;
console.log('in')
}
console.log(c) //undefined
9、查找字符串出现的次数
function appear(str,target_str){
let arr = [];
let n = 0;
while(str.indexOf(target_str,n) != -1 && n<str.length){
arr.push(str.indexOf(target_str,n)); //第二个参数是开始查找的位置
n = str.indexOf(target_str,n) + target_str.length; //更改位置,从下一个地方开始查找
}
return arr;
}
var arr = appear('abascbascbabasbascbascascbab','s');
10、不借助辅助空间,找出数组中不重复的元素
// [0,0,1,1,1,2,3,4,5]
let i = 0,j=0;
for(i = 0;i<arr.length;i++){
for(j = 0;j<arr.length;j++){
if(arr[i]==arr[j] && i!=j) break;
}
if(j==arr.length) console.log(arr[i]) //3 4 5
}