JS-part4.2-快速排序/插入排序 和 数组去重

递归二分法排序(快速排序)

思想:
	1. 将数组的length除以2取整的值作为中间值,左右分别放置两个数组
	2. 对于数组中的数据,小于该中间值的数据放左边的数组中, 大于该中间值的数据放右边的数组中
	3. 逐层递进
	4. 归

步骤1
在这里插入图片描述
步骤2
在这里插入图片描述

步骤3: ‘递’
在这里插入图片描述

步骤4: ‘归’
在这里插入图片描述

/*递归二分法排序(快速排序)

   1. 准备一个函数,接收一个数组
   2. 准备递归
       => 先找停的条件
           -> 只要数组的 length <= 1,就停下来,直接返回原数组
       => 停以外的行为
           -> 找到一个数组长度一半的取整
           -> 从数组里把这个数据拆出来
           -> 准备两个新数组,一个表示左边,一个表示右边
           -> 循环遍历被拆除一个数字的数组
           -> 判断大小,选择一个数组放进去
*/

var arr = [8, 4, 3, 2, 6, 7, 1, 5, 9];

// 1. 准备一个函数
function quickSort(arr){
    // arr 就是要排序的数组
    // 2-1. 递归停的条件
    if(arr.length <= 1){
        return arr;
    }

    // 2-2. 不到停的时候
    var centerIndex = parseInt(arr.length / 2);
    var center = arr.splice(centerIndex, 1)[0];  // 获取[0]位置上的数字6 而不是数组[6]

    // 准备两个数组
    var left = []; // 小
    var right = []; // 大

    // 循环遍历 arr
    for(var i = 0; i < arr.length; i++){
        // 判断大小,决定放在哪个数组里面
        if(arr[i] < center){
            left.push(arr[i]);
        }else{
            right.push(arr[i]);
        }
    }
    
    // 向里面递归
    // concat 不改变原始数组
    return quickSort(left).concat(center, quickSort(right));
}
var res = quickSort(arr);
console.log(res);
console.log(arr);

在这里插入图片描述

插入排序

可以类比打牌

简单版如下:

/*
    插入排序

    1. 从 1 开始循环原始数组
        => 因为第一个数字不用比
    2. 把当前这个数字复制一份
        => 为了覆盖以后还能有这个数字
    3. 留下一个从哪里开始比的索引
        => 开始比较的索引就是当前索引的前一个
    4. 向前比较
        => 遇到比我小的,就停下
        => 如果前一个比我大,就用前一个把我覆盖掉
*/
var arr = [8, 4, 3, 2, 6, 7, 1, 5, 9];

// 1. 从 [1] 开始遍历数组
for(var i = 1; i < arr.length; i++){
    var tmp = arr[i];
    var j = i - 1;
    while(arr[j] > tmp){
        arr[j + 1] = arr[j];
        j--;
    }
    arr[j + 1] = tmp;
}
console.log(arr);

在这里插入图片描述

数组去重

去除数组中重复的数据
/*
    方案1
        1. 循环遍历数组
            => 从 [0] 开始,拿到每一个
            => 向后面去比较,只要后面还有一个和我一样的
            => 把我删除掉
*/

// 1. 准备一个数组
var arr = [1, 2, 3, 5, 6, 4, 3, 2, 1, 1, 2, 3, 4, 5];

// 方案1:
for(var i = 0; i < arr.length; i++){
    // 第一个数字开始比较,向后比较
    for(var j = i + 1; j < arr.length; j++){
        if(arr[i] === arr[j]){
            arr.splice(j, 1);
            j--;   // 删除一个后使索引-1, 不然后面的索引会往前移
        }
    }
}
console.log(arr);
var arr = [1, 2, 3, 5, 6, 4, 3, 2, 1, 1, 2, 3, 4, 5];
/*
     方案2
         1. 准备一个新的数组
         2. 循环遍历数组
             => 一个一个地向新数组里面添加
             => 只要新数组没有这个数据,那么就加进去
             => 如果新数组里面有这个数据,就算了
 */

// 1. 准备一个新的数组
var newArr = [];

// 2. 遍历原始数组
for(var i = 0; i < arr.length; i++){
     // 查看原始数组里面有没有 arr[i] 这个数据
     // if(newArr.indexOf(arr[i]) === -1){
         // 表示 newArr 里面没有这个数据
     if(!newArr.includes(arr[i])){
         // 能执行 if 条件,说明!newArr.includes(arr[i]) 是 true
         // newArr.includes(arr[i])是 false
         // 放进去
         newArr.push(arr[i]);
     }
}
console.log(newArr);
/*
    方案3
        + 对象
            -> obj.name = 'xxx';
            -> 对象成员名不重名
        
        1. 准备一个空对象
        2. 循环遍历数组,把每一个成员当成对象的key来使用
            -> 值填充什么无所谓
        3. 循环遍历对象,把每个 key 添加到新数组里
*/
// 1. 准备一个空对象
var obj = {};

// 2. 循环遍历数组
for(var i = 0; i < arr.length; i++){
    //把数组里面的每一个值当成 obj 的 key 来添加成员
    obj[arr[i]] = '值不重要';
}

// 3. 准备一个新数组
var newArr = [];
for(var key in obj){
    // key 就是对象里的每一个数据
    // key 一定是字符串类型
    newArr.push(key - 0);
}
console.log(obj);
console.log(newArr);

在这里插入图片描述

练习

在这里插入图片描述

/*
逻辑:
  1.判断一下这个数字
    1-1. 如果我的这个数字小于等于数组的第一个数字,直接unshift()
    1-2. 如果我这个数字大于等于数组的最后一个数字,直接push()

  2. 判断数组是空的,直接push()
  3. 循环遍历数组,找一个合适的位置插入
    => 找到合适的位置
    => 比较,大于前一个数字,并且小于后一个数字,放在前一个的后面(后一个的前面)
        -> 大于和小于不合适
        -> 换成 >= 和 <,如果这样使用,需要 break
        -> 换成 > 和 <=,这样使用可以不加 break

思考:
  + 按照现在的代码思考
  + 有没有一个情况能满足两个 if 条件
    => 有
  + 当出现这个情况以后,会不会插入两次
    => 不会
  + 如果我的数组是空的,会不会报错
    => 不会
    => 如果是空的,到下面的循环也不执行
    => 这个数字插入不进去
  + 判断数组为空的位置,需不需要return
    => 需要 return

小技巧:
  + insert 函数不需要返回值,只是对数组进行操作
  + return 后面有没有内容无所谓
  + 如果 if 条件后面只有一句话,并且需要 return
  + 可以直接写一行
  + 写成 return 你要执行的这句话
*/
var arr = [1, 20, 33, 44, 67, 89, 100];

function insert(arr, num){
    // 1. 判断一下数字
    // 1-1. 小于等于数组的第一个
    // if(num <= arr[0]){
    //     arr.unshift(num);
    //     return;
    // }
    if(num <= arr[0]) return arr.unshift(num);
    
    // 1-2. 大于等于数组的最后一个
    if(num >= arr[arr.length - 1]){
        arr.push(num);
        return;
    }
    // 2. 判断数组为空
    if(!arr.length){
        arr.push(num);
        return;
    }
    // 3. 数组遍历
    // console.log('循环遍历');
    for(var i = 0; i < arr.length; i++){
        if(num > arr[i] && num <= arr[i + 1]){
            // 放在后一个的前面
            // splice 方法,从哪里截取,从哪里插入
            // 把后面的数字向后顺延,把插入的数字放进去
            arr.splice(i + 1, 0, num);
            break;
        }
    }

}
insert(arr, 20)
console.log(arr);

/*
  >= 和 < 死循环
  循环第一次 i === 0
    num >= arr[0] && num < arr[1];
    20 >= 1 && 20 < 20
  循环第二次 i === 1
    num >= arr[1] && num < arr[2]
    20 >= 20 && 20 < 33
    把 33 向后顺延一个, 20 插进去
    [1, 20, 20, 33, 44, 67, 89, 100]
  循环第三次 i === 2
    num >= arr[2] && num < arr[3]
    20 >= 20 && 20 < 33
    [1, 20, 20, 20, 33, 44, 67, 89, 100]
    死循环

  > 和 <= 死循环
  循环第一次 i === 0
    num > arr[0] && num <= arr[1];
    20 > 1 && 20 <= 20
    把 33 向后顺延一个, 20 插进去
    [1, 20, 20, 33, 44, 67, 89, 100]
  循环第二次 i === 1
    num > arr[1] && num <= arr[2]
    20 > 20 && 20 <= 20
    继续循环
    但是因为插入以后,后面的循环已经没必要了
    最好还是加一个 break
*/
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值