数据结构和算法知识汇总

综述:数据结构和算法对于前端人员来说很重要,特别是一线大厂,将常见的问题做一个总结,巩固自己的知识

前端必须了解的数据结构和算法知识:

  • 算法的基本概念
  • 时间复杂度和空间复杂度的计算
  • 线性表数据结构
  • 栈和队列数据结构
  • 串数据结构
  • 树数据结构
  • 图数据结构

两种常见的算法问题(各自有非常多的实现方式):

  • 查找算法
  • 排序算法

1.去重的方法有哪些?越多越好,扩宽自己的知识面?

  • 创建新数组去重法(性能不是非常的好)

var arr=[1,1,1,2,3];
var newArr=new Array();
for(var i in arr){
  if(newArr.indexOf(arr[i])==-1){  //如果新数组中不存在这个元素
      newArr.push(arr[i]);
  }
}
console.log(newArr);
  • 使用es6中的集合Set + Array.from()方法实现去重

Array.from()方法就是将一个类数组对象或者可遍历对象转换成一个真正的数组,set对象并不是一个完整的数组;

var arr=new Set([1,1,1,2,3]);
var newArr=Array.from(arr);
console.log(newArr);    //[1,2,3]
  • es6中的 …[拓展运算符] +Set

拓展运算符:扩展运算符( spread )是三个点(...),将一个数组转为用逗号分隔的参数序列。

var arr=[...new Set([1,1,1,2,3])];  
console.log(arr);      //1,2,3

var arr=[new Set([1,1,1,2,3])];  
console.log(arr);   //1,2,3
  • 将数组中的值以对象属性的方式传给一个对象,如果对象中没有这个属性则将其添加到对象中,仔细分析代码中的问题

//在数组的原型上添加方法
   Array.prototype.unique=function(){
     var arr2=[];
     var obj={};
     for(var i in this){  //这样写返回的数组中就是6个元素,包括函数自身
       /*if(!obj.this[i]){
         arr2.push(this[i]);
         obj.this[i]=1;    //为什么通过这种方式是会出错的
       }*/
       if(!obj[this[i]]){
         arr2.push(this[i]);
         obj[this[i]]=12;  //如果不给默认值有啥影响
       }
     }
     for(var i=0;i<this.length;i++){  //这里返回的就是5个元素
       if(!obj[this[i]]){
          arr2.push(this[i]);
          obj[this[i]]=12;  //如果给值为0或者不给值,则就不会满足!obj[this[i]]这个条件;
        }
     }
      return  arr2;
   };
   var arr=[1,2,1,1,3];
   console.log(arr.unique());  //[1,2,3];

后来在一个网页中查到,原来对象访问属性有两种方式。有一个对象Obj = {"Name":"Langshen","AGE":"28"}

  • 用点访问,Obj.Name ;

  • 用中括号访问,Obj["Name"];

  • 上述两种方式得到的结果都是属性Name的值Langshen;


上面2中访问的方式可以获得同样的效果,是因为对象的属性是已经存在的,这里在延伸一下上述两种方式为对象新建属性时用法的区别。

首先,回到文章的开头。代码o[char] 表示的是o对象的一个属性值。那能不能用o.char表示呢?答案是否定的

详细内容参考链接:https://blog.csdn.net/shuren1991/article/details/67639250

2.排序相关方法汇总?快速排序,冒泡排序,选择排序算法非常常见,必须要熟悉其实现思想,十种常见的排序算法实现;

冒泡排序算法实现,时间复杂度为O(n²),时间复杂度是指计算方法执行的次数,因为这里做了两次的遍历:

function bubbleSort(arr) {
    var len = arr.length;
    for (var i = 0; i < len - 1; i++) {
        for (var j = 0; j < len - 1 - i; j++) {
            if (arr[j] > arr[j+1]) {        // 相邻元素两两对比
                var temp = arr[j+1];        // 元素交换
                arr[j+1] = arr[j];
                arr[j] = temp;
            }
        }
    }
    return arr;
}

快速排序算法实现:

参考链接:https://zhuanlan.zhihu.com/p/45418184

/* 快速排序(二分法)
* 1.先从数列中取出一个数作为基准数。
* 2.分区过程,将比这个数大的数全放到它的右边,小于或等于它的数全放到它的左边。
* 3.再对左右区间重复第二步,直到各区间只有一个数。 
*/

let arr3 = [62,12,23,4,443,5,6,14,21,45,3,75,68,11,22,4,43,56,1,2,84,3,565,1,25,4,3,566,1,276,4,37,56,1,2,4,3,565,1,2,4,377,5,40,49,28]
console.time("time_quickSort")
let nn = 0;
 function quickSort(arr){
      if(arr.length<2){return arr};
      var left=[],right=[],mid=arr.splice(Math.floor(arr.length/2),1);
      for(var i=0;i<arr.length;i++){
            if(arr[i]<mid){
                left.push(arr[i]);
            }else {
                right.push(arr[i])
            }
			nn++;
      }
	  
      return [...quickSort(left),...mid,...quickSort(right)]
  }
 console.log(quickSort(arr3))
 console.log(nn)
 console.timeEnd("time_quickSort")

选择排序:

/* 
* 选择排序
* 在一个长度为N的无序数组中,
* 在第一趟遍历N个数据,找出其中最小的数值与第一个元素交换,
* 第二趟遍历剩下的N-1个数据,找出其中最小的数值与第二个元素交换,
* ……
* 第N-1趟遍历剩下的2个数据,找出其中最小的数值与第N-1个元素交换,
* 至此选择排序完成。 
*/
let arr2 = [62,12,23,4,443,5,6,14,21,45,3,75,68,11,22,4,43,56,1,2,84,3,565,1,25,4,3,566,1,276,4,37,56,1,2,4,3,565,1,2,4,377,5,40,49,28]
console.time("time_selectSort")
function selectSort(arr){
	let n = 0;
	let newArr = arr;//拷贝一份做修改
	for(let i=0;i<newArr.length;i++){
		minIndex = i;
		for(let j=i+1;j<newArr.length;j++){	
			if(newArr[j]<newArr[i]){
				n++;
				let min = newArr[j];
				newArr[j] = newArr[i];
				newArr[i] = min;
			}
		}
	}
	console.log(n)
	return newArr;
}
console.log(selectSort(arr2))
console.timeEnd("time_selectSort")

3.将关系型数据库的标准数据结构转化成树状机构的算法?trie树的使用

4.动态规划问题

  • 在数组中找到最大和的子数组问题
  • 将一个数组分割成N分,使N份 之间的和之间的差最小
  • 斐波那契数列的使用,使用递归和使用动态规划方法之间性能是完全不同的
  /* 使用递归的方法实现斐波那契数列的方法,时间复杂度为 */
            var a=0;
            function feibo(n){
                if(n<2){
                return 1;
                }else{
                     ++a
                    console.log(a)
                    return feibo(n-1)+feibo(n-2);
                }
            }
            console.log(feibo(10))  

          /* 使用动态规划的思想,每次存储上次的计算结果,这样时间复杂度为O(n-2) 当n=10时,是8次*/
           function dynFib(n) {
                let val = [];
                for(let i = 0; i <= n; ++i){
                    val[i]=0;
                }
                if(n ===1 || n  === 2){
                    return 1;
                }
                else {
                    //在数组中对计算的结果进行缓存,避免多次计算,降低算法的时间复杂度
                    val[1] =1;
                    val[2] = 2;
                    for(let i = 3; i <= n; ++i){
                        console.log(n)
                        val[i] = val  [i-1] +val[i-2] ;
                    }
                }
                return val[n-1]
        }
        console.log(dynFib(10))

5.主要的数据结构有?

数组,集合(set),字典(map),链表,哈希表,队列,栈,树,图

6.主要的算法有?

十大排序算法,搜索算法。

 

 

 

 

 

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值