数据结构和算法实例

综述:数据结构和算法是高级前端的必备知识,贵在总结,坚持积累

1.将数据中的数据转成树状结构,实现前缀树trie,思考前缀树trie和tree之间的不同?

 var transObject = function(tableData,keys){
        let hashTable = {}, res = []
        for (let i = 0; i < tableData.length; i++) {
            let arr = res, cur = hashTable
            for (let j = 0; j < keys.length; j++) {
                let key = keys[j], filed = tableData[i][key];
                if (!cur[filed]) {
                    let pusher = {value:filed},tmp;
                    if (j !== (keys.length - 1)){
                        tmp = [];
                        pusher.children = tmp
                    }
                    cur[filed] ={$$pos: arr.push(pusher) - 1 };
                    cur = cur[filed];
                    arr = tmp;
                } else {
                    cur = cur[filed];
                    arr = arr[cur.$$pos].children
                }
            }
        }
        return res
    };
    var data = [{
        "province": "浙江",
        "city": "杭州",
        "name": "西湖"
    }, {
        "province": "四川",
        "city": "成都",
        "name": "锦里"
    }, {
        "province": "四川",
        "city": "成都",
        "name": "方所"
    }, {
        "province": "四川",
        "city": "阿坝",
        "name": "九寨沟"
    }];
    var keys = ['province', 'city', 'name'];
    console.log(transObject(data, keys));

2.使用js方法遍历html结构?收集所有的标签,使用数组存储所有的标签?




    
    
    
    
    基础信息
    
    
    




3.redux的使用,最简单的demo

function inc() {
        return { type: 'INCREMENT' };
    }
    function dec() {
        return { type: 'DECREMENT' };
    }
    function add10() {
        return { type: 'ADD10' };
    }
    function reducer(state, action) {
        // 首次调用本函数时设置初始 state
        state = state || { counter: 0 }; //这里是存储的数据值

        switch (action.type) {
            case 'INCREMENT':
                return { counter: state.counter + 1 };
            case 'DECREMENT':
                return { counter: state.counter - 1 };
            case 'ADD10':
                return { counter: state.counter+10};
            default:
                return state; // 无论如何都返回一个 state
        }
    }

    var store = Redux.createStore(reducer);
    console.log( store.getState() ); // { counter: 0 }

    store.dispatch(inc());
    console.log( store.getState() ); // { counter: 1 }

    store.dispatch(inc());
    console.log( store.getState() ); // { counter: 2 }

    store.dispatch(dec());
    console.log( store.getState() ); // { counter: 1 }

    store.dispatch(add10());
    console.log( store.getState() ); // { counter: 1 }

4.斐波那契数列,1,1,2,3,5,8......后一个数字是前两个数字之和?要使用动态规划的方法来实现,不然算法的时间复杂度太高。使用数组缓存上一次计算的结果才对。

 /**
   *time/author:2019/5/14 "mouyao"
   *desc:递归实现
   */
  console.time("递归");
  var feibo=function(n){
    if(n<2){
      return 1;
    }else{
        return  feibo(n-1) + feibo(n-2);
      //return arguments.callee(n-1)+arguments.callee(n-2);
    }
  };
  console.log(feibo(20));
  console.timeEnd("递归");
  
  /**
   *time/author:2019/5/14 "mouyao"
   *desc: 直接使用加法,使用for循环实现数字的多次叠加
   */
  console.time("加法实现斐波那契数列");
  function fibo(n){
    if (n < 2) {
       return 1;
    }
    var a = 1, b = 1,c=0;
    for (var i = 2; i <= n - 1 ;i++ ) {
        c=a+b;
        a=b;
        b=c;
    }
    return a + b;
  }
  console.log(fibo(20));
  console.timeEnd("加法实现斐波那契数列");
  
  /**
   *time/author:2019/5/14 "mouyao"
   *desc:非递归实现,数组缓存,这种方法在调用多次的时候,非常值得推荐,在明源云中,就存在大数据计算的缓存问题,这种思想十分值得分析,将所有的计算结果保存到函数中的数组中,后期
   */
  console.time("数组缓存");
  var IterMemoFib = function() {
    var cache = [1, 1];
    return function (n) {
      if (n >= cache.length) {
        for (var i = cache.length; i

5.爬梯子问题,1,2,3,5,8,9。。。。和第4题十分的相似,分别的代码如下。这里也要使用动态规划的思想来解决问题,缓存上一次的计算结果才对。


   // 爬梯子问题 
  var climbStairs = function(n) {
          if(n===1||n===2||n===3){
              return n;
          }else if(n>3){
              return climbStairs(n-2)+climbStairs(n-1);
              return arguments.callee(n-2)+arguments.callee(n-1);
          }
      };
      console.log(climbStairs(45));

6.实现两个大数相加,这两个大数有可能会超出存储空间,该怎样来实现(腾讯前端面试题目),实现两个大位数的相乘,想法几乎是一样的。

首先说明JavaScript中虽然是一门弱类型语言,其实Number类型的数据也是有存储范围的。其最大最小的存储范围是

最大安全数: Math.pow(2, 53) - 1     // 9007199254740991
最小安全数:Math.pow(-2, 53) + 1     // -9007199254740992

超出这个范围的运算都是不安全的,可以对这样的数据进行操作测试

7.前端大厂数据结构和算法面试题汇总,十个非常经典的问题,值得细细品味

https://zhuanlan.zhihu.com/p/57200821

8.排序算法实现(二叉树排序> 快速排序 >冒泡排序),一共有始终排序方法。

  •  快速排序(效率极高)
    //产生一个测试数组
    function makeRandomNumber(){
        var arr=[];
        for(var i=0;i<99999;i++){
            arr.push(Math.ceil(Math.random()*i));
        }
        return arr;
    }
/**
     *time/author:2019/5/7 "mouyao"
     *desc:快排序实现思路,选择一个数字为基准,将数字分成比他大和小的两个部分,递归排序
     * 拆分后的两个数字,直到数组长度为1为止,效率很高,当数据量很小的时候,看不出性能差异,
     * 当数据量为99999时,时间差了30多倍
     */
    console.time("快排序");
    var arr=makeRandomNumber();
    function quickSort(arr){
        var leftArr=[];
        var rightArr=[];
        var middleValue=arr[0];
        if(arr.length<=1){
            return arr;
        }else{
            for(var i=1;imiddleValue){
                    leftArr.push(arr[i]);
                }else{
                    rightArr.push(arr[i]);
                }
            }
        }
      //return [].concat(quickSort(leftArr),middleValue,quickSort(rightArr));
      return quickSort(leftArr).concat(middleValue,quickSort(rightArr));
    }
     console.log(quickSort(arr)); 
     console.timeEnd("快排序"); //725ms
  • 冒泡排序
/**
     *time/author:2019/5/7 "mouyao"
     *desc:冒泡排序实现,选择第一个数字为基准,分别遍历,如果比他大,则交换两个值,如果小,则不交换
     */
   var arr=makeRandomNumber();
    console.time("冒泡排序");
     function bubblingSort(arr){
         for(var i=0;iarr[j]){
                   [arr[i],arr[j]]=[arr[j],arr[i]];
               }
           }
       }
        return arr;
    }

    console.log(bubblingSort(arr));
    console.timeEnd("冒泡排序");//19055ms
  • 构建二叉树数据结构并对数据进行排序
 var arr=makeRandomNumber();
     console.time("二叉树排序");
     function BinaryTree(){
         var Node=function(key){
             this.key=key;
             this.left=null;
             this.right=null;
         };
         var root=null; //二叉树数据结构的值存储到这里
         var insertNode=function(node,newNode){
             if(newNode.key=99999){
            console.log(newArr);
            console.timeEnd("二叉树排序");//336ms
        }
    };
    binaryTree.inOrderTravers(callback);

通过上边的例子可以看出,对99999个数据进行排序,二叉树(336ms),快速排序(720ms),冒泡排序(12617ms),但是当数据量很小的时候,基本看不出来之间的差距。说明数据结构和算法对大数据量的处理非常重要,对高并发的业务场景十分重要;

9.给定线段A(x1,y1),(x2,y2)和线段B(x3,y3),(x4,y4),请两条线的交点的坐标?

 function hasSamePoint(a,b,c,d){
    var denominator = (b.y - a.y)*(d.x - c.x) - (a.x - b.x)*(c.y - d.y);
    if (denominator===0) {  //如果两个线条平行,则肯定不存在交点
         return false;
    }
    //线段所在直线的交点坐标(x,y)      
    var x = ( (b.x - a.x) * (d.x - c.x)*(c.y - a.y)
      + (b.y - a.y) * (d.x - c.x) * a.x
      - (d.y - c.y) * (b.x - a.x) * c.x )/denominator;
    var y = -( (b.y - a.y) * (d.y - c.y) * (c.x - a.x)
      + (b.x - a.x) * (d.y - c.y) * a.y
      - (d.x - c.x) * (b.y - a.y) * c.y )/denominator;

    // 判断交点是否在两条线段上
    if ((x - a.x) * (x - b.x) <= 0 && (y - a.y) * (y - b.y)<= 0&& (x - c.x)*(x-d.x)<=0&&(y-c.y)*(y-d.y)<=0){
        return{
          x:x,
          y:y
        }
    }
    return false
  }
  console.log(hasSamePoint({x:1,y:2}, {x:11,y:24},{x:4,y:22},{x:31,y:25}));

10.必须要会使用的数据结构和算法有哪些?

数组,链表,队列,栈,堆,树,图。这几种非常常见;

排序和搜索算法。动态规划,贪心算法,背包问题。

 

 

 

 

 

你可能感兴趣的:(数据结构和算法,计算机知识汇总)