前端算法

4大算法:

  1. 贪心算法:局部最优解
  2. 分治算法:将一个问题分成多个小模块
  3. 动态规划:每一个状态都是过去历史的总结
  4. 回溯算法:不是最优选择的时候退回重新选

一、排序算法

1. 冒泡排序:数字越大越往上

第一次循环 比较当前元素与下一个元素,如果比下一个元素大 就换位置,反之不动

function bubbleSort(arr) {
  let length = arr.length;
  // 外层循环用控制 排序进行多少轮
  for (let i = 0; i < length; i++) {
    // 内层循环用于每一轮的数据比较
    // 注意j的长度范围 length - i - 1
    for (let j = 0; j < length - i - 1; j++) {
      // 相邻元素,大的放到后面
      if (arr[j] > arr[j + 1]) {
        // 交换位置
        [arr[j], arr[j + 1]] = [arr[j + 1], arr[j]];
      }
    }
  }
  return arr;
}

2. 选择排序

遍历自身以后的元素,选择最小的元素跟自己换位置

chooseSort(arr){
      let len = arr.length;
      for(let i=0;i<len-1;i++){
        for(let j=i+1;j<len;j++){
          if(arr[i]>arr[j]){
            [arr[i], arr[j]] = [ arr[j], arr[i]]
          }
        }
      } 
      return arr
    }

3. 插入排序

把将要排序的元素插入到已经排好的元素中去

 insertSort(arr){
      for(let i=1;i<arr.length;i++){
      //外循环从1开始,默认arr[0]已经排序
        for(let j=i;j>0;j--){
        //j = i,将arr[j]依次插入有序段中
          if(arr[j]<arr[j-1]){
            [arr[j],arr[j-1]] = [arr[j-1],arr[j]]
          }
        }
      }
      console.log(arr);
      return arr
    }

4. 快速排序

通过一趟排序 将数组分成两个部分,其中一边的值比另一边的小,递归调用函数,遍历这两部分进行排序,最后按顺序合并数组

function quickSort(arr){
    if(arr.length<=1){
        return arr;
    }
    let left=[],right=[];
    let current=arr.splice(0,1);
    for(let i=0;i<arr.length;i++){
        if(arr[i]<current){
            left.push(arr[i]);
        }else{
            right.push(arr[i]);
        }
    }
    return quickSort(left).concat(current,quickSort(right))
}
let arr1=[5,7,1,6,2,3,9,4,8];
quickSort(arr1);//[1,2,3,4,5,6,7,8,9]

5. 归并排序

采用分治法:

  1. 将所有数组项无限细分,得到1个个独立的单元,也就是不断分解。
  2. 将相近的两两进行比较,按照已排序数组合并,形成(n/2)个序列,每个序列包含2个数字。
  3. 将上述两个序列递归合并,按照已排序数组合并,形成(n/4)个序列,每个序列包含4个数字。
  4. 重复步骤2,直到所有元素合并排序完毕。
function MergeSort(array) {
  let len = array.length;
 
  // 当每个子序列中仅有1个元素时返回
  if (len <= 1) {
    return array;
  }
  // 将给定的列表分为两半
  let num = Math.floor(len / 2);
  let left = MergeSort(array.slice(0, num));
  let right = MergeSort(array.slice(num, array.length));
  return merge(left, right);
 
  function merge(left, right) {
    let [l, r] = [0, 0];
    let result = [];
    // 从 left 和 right 区域中各个取出第一个元素,比较它们的大小
    while (l < left.length && r < right.length) {
      // 将较小的元素添加到result中,然后从较小元素所在的区域内取出下一个元素,继续进行比较;
      if (left[l] < right[r]) {
        result.push(left[l]);
        l++;
      } else {
        result.push(right[r]);
        r++;
      }
    }
    // 如果 left 或者 right 有一方为空,则直接将另一方的所有元素依次添加到result中
    result = result.concat(left.slice(l, left.length));
    result = result.concat(right.slice(r, right.length));
    return result;
  }
}

二、列表转成树

输入一组列表如下,转化成树形结构

// 输入
[
	{ id: 1, title: "chil1", parentId: 0 },
	{ id: 2, title: "chil2", parentId: 0 },
	{ id: 3, title: "chil1-1", parentId: 1 },
	{ id: 4, title: "chil1-2", parentId: 1 },
	{ id: 5, title: "chil2-1", parentId: 2 },
]
// 输出
tree = [
	{
		"id": 1,
		"title": "chil1",
		"parentId": 0,
		{
			"id": 3,
			"title": "chil1-1",
			"parentId": 1,
		},
		{
			"id": 4,
			"title": "chil1-2",
			"parentId": 1,
		},
	},
	{
		"id": 2,
		"title": "chil2",
		"parentId": 0,
		{
			"id": 5,
			"title": "chil1-1",
			"parentId": 2,
		},
	},
]
listToTree(arr){
      // 使用对选哪个重新存储数据
      let map = {}
      // 最终结果
      let treeData = []
      // 遍历元原始数据 存到map中,值为数据
      for(let i=0;i<arr.length;i++){
        map[data[i].id] = data[i]
      }
      // 遍历对象
      for(let i in map){
        // 根据parentId找到父节点
        if(map[i].parentId){
          if(!map[map[i].parentId].children){
            map[map[i].parentId].children = []
          } else {
            // 将子节点放到父节点的children中
            map[map[i].parentId].children.push(map[i])
          }
        } else {
          // 没有父节点 说明是根节点 直接插到跟数组中
          treeData.push(map[i])
        }
      }
    }

三、深度优先遍历

对树进行遍历,然后对他的第一个子节点进行遍历,直到所有的子节点都遍历完毕,然后遍历它所有的兄弟节点


四、广度优先遍历

对树进行遍历,然后对他的第一个子节点进行遍历,遍历他的所有兄弟节点,再遍历第一个节点的子节点 一层层往下遍历


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值