数据结构算法在专网项目中的实践

简介: 数据结构与算法作为计算机学科中至关重要的一门课程,在日常业务代码中常常很难用到或者说很难进行相关的实践,我们常常在leetcode中练习的习题感到没有用武之地。实际上,我们可以通过优化页面中的一些代码及在需求实现过程中对之前阅读过的源码或者之前练习过的习题进行相关的举一反三和触类旁通。本文列举了一些作者在日常业务代码书写过程中进行的一些相关数据结构算法的实践以及对于算法与数据结构练习的思考。

前端 | 数据结构算法在专网项目中的实践.png

前言

数据结构与算法作为计算机学科中至关重要的一门课程,在日常业务代码中常常很难用到或者说很难进行相关的实践,我们常常在leetcode中练习的习题感到没有用武之地。实际上,我们可以通过优化页面中的一些代码及在需求实现过程中对之前阅读过的源码或者之前练习过的习题进行相关的举一反三和触类旁通。本文列举了一些作者在日常业务代码书写过程中进行的一些相关数据结构算法的实践以及对于算法与数据结构练习的思考。

业务需求

  • 自定义优先级规则展示
  • 切换时间粒度字段映射

探索方案

自定义优先级规则展示

在前端页面中,我们经常会遇到需要一排展示数量或者不同维度属性的需求,通常来说我们会将后端所有返回的字段都进行相关的展示,但是在一些轻交互重展示的场景中,比如可视化大屏,就需要我们对展示的内容进行取舍,而这个取舍就需要我们能够根据需求或者说产品数据的反馈进行优先级的选择排布,这里就会涉及到优先级的动态调整过程,也就是能够根据数据或者需求来自定义展示优先级。

方案一:函数式编程

第一个比较简单的想法就是根据产品需求进行数组的分流,然后合并数组进行截取展示

fn(arr) {
  let r = [], _r = [];
  for(let i=0; i < arr.length; i++) {
    // 数量展示优化
    if( 达到某个数量 ) return r;
    if(// 根据产品需求对数组进行分流) {
      r.push(arr[i])
    } else {
      _r.push(arr[i])
    }
  }

  return r.length > 5 ? r.slice(0,5) : r.concat(_r).slice(0,5);
};

gn() {
  this.resourceConfig.map(// 业务逻辑).sort((a,b) => a.structure - b.structure));
}

最后 fn(gn())

方案二:链表

方案二来源于链表的删除更新方便的特点,通过一个链表将所有的优先级进行串联起来,通过使用update操作进行相关的业务更新操作

// 构造一个节点
class Node {
  constructor(v, next){
    this.value = v;
    this.next = next;
  }
}
 
class LinkList {
  constructor(){
    // 链表的属性,长度和头部
    this.size = 0
    this.head = new Node(null, null)
  }
    
  // 是否为空
  isEmpty() {
    return this.size === 0
  }
  
  // 更新链表,进行相关业务的操作
  update() {

  }
}

方案三:优先队列

本方案来源于react的fiber的优先级调度,通过优先队列进行相关的操作

class PriorityQueue{
    // 取父节点索引 ~~((index - 1) / 2)
    constructor(arr){
        if (arr.length){
            this.tree = []
            this._build_tree(arr);
            return;
        }
        this.tree = [];
    }

    // 入队
    enqueue(val){
        this.tree.push(val);
        // 上浮
        this._up(this.tree.length - 1);
    }

    // 出队
    dequeue(){
        // 取树根元素
        this.tree.shift();
        // 最后一个元素放树根,进行下沉
        let last = this.tree.pop();
        this.tree.unshift(last);
        // log(n)下沉
        this._down(0);
    }

    // 取队首的值
    getFirst(){
        return this.tree[0];
    }

    _build_tree(arr){
        let tree = this.tree;
        tree.push(arr[0]);
        for (let i = 1; i < arr.length; i++){
            tree.unshift(arr[i]);
            this._down(0);
        }
    }

    // 对index号元素执行下沉操作. 也叫heapify
    _down(index){
        let tree = this.tree;
        // 本身就是叶子节点,无需下沉
        let last_no_leaf = ~~((tree.length - 2) / 2);
        if (index > last_no_leaf) return;
        while(index <= last_no_leaf){
            let l = tree[index * 2 + 1];
            let r = tree[index * 2 + 2] || tree[index * 2 + 1]; // 有可能没有右儿子
            let max = l >= r ? l : r;
            let maxIndex = l >= r ? index * 2 + 1: index * 2 + 2
            if (tree[index] < max){
                [tree[index], tree[maxIndex]] = [tree[maxIndex], tree[index]]
                index = index * 2 + 1
            }else{
                return;
            }
        }
    }

    // 对index号元素执行上浮操作
    _up(index){
        let tree = this.tree;
        while(index !== 0){
            let p = ~~((index - 1) / 2);
            if (tree[index] > tree[p]){
                [tree[index], tree[p]] = [tree[p], tree[index]];
                // let tmp = index;
                // this._down(tmp);
                index = p;
            } else {
                return;
            }
        }
    }
}

切换时间粒度字段映射

在前端页面中,对于动态下拉选择框选项,我们通常通过接口进行获取,但是对于多级联动的下拉选择选项,对于不同的时间粒度选择通常返回的数据名称相同但是id确实不同的,这时通常需要对数据进行映射处理

方案:栈

在时间粒度进行切换时,需要记录前后最终前后两个时间粒度的值,通过接口进行时间粒度的数据映射,这里可以通过栈进行时间粒度的记录,获取最初和最后的时间粒度,最后进行数据映射

const timeSizeList = [];

// 进行入栈操作
timeSizeList.push(...)

总结

日常进行数据结构习题练习或者阅读源码过程中,除了为了应付面试之外,最重要的还是要学习源码或者习题中解决问题的思路以及想法,在日常的业务代码中,虽然很难写出框架代码那种优雅简洁的实现方案,但是也应该在日常工作中多思考如何利用数据结构与算法来优化代码的时空复杂度,更好的优化代码的执行,从而提升用户体验,这才是一个高级工程师应该关注的细节点,不能只是为了完成业务代码而完成业务代码,这样虽然写了很多代码,但其实其对个人代码能力及计算机素养的提升都是很有限的,事倍却工半,希望在重复的业务代码书写过程中,也能做到优雅与高效并存,共勉!!!

参考

[

](https://segmentfault.com/a/1190000022131550)

相关文章
|
1月前
|
机器学习/深度学习 算法 搜索推荐
从理论到实践,Python算法复杂度分析一站式教程,助你轻松驾驭大数据挑战!
【10月更文挑战第4天】在大数据时代,算法效率至关重要。本文从理论入手,介绍时间复杂度和空间复杂度两个核心概念,并通过冒泡排序和快速排序的Python实现详细分析其复杂度。冒泡排序的时间复杂度为O(n^2),空间复杂度为O(1);快速排序平均时间复杂度为O(n log n),空间复杂度为O(log n)。文章还介绍了算法选择、分而治之及空间换时间等优化策略,帮助你在大数据挑战中游刃有余。
57 4
|
1月前
|
存储 人工智能 算法
数据结构与算法细节篇之最短路径问题:Dijkstra和Floyd算法详细描述,java语言实现。
这篇文章详细介绍了Dijkstra和Floyd算法,这两种算法分别用于解决单源和多源最短路径问题,并且提供了Java语言的实现代码。
69 3
数据结构与算法细节篇之最短路径问题:Dijkstra和Floyd算法详细描述,java语言实现。
|
28天前
|
存储 算法 C语言
通义灵码在考研C语言和数据结构中的应用实践 1-5
通义灵码在考研C语言和数据结构中的应用实践,体验通义灵码的强大思路。《趣学C语言和数据结构100例》精选了五个经典问题及其解决方案,包括求最大公约数和最小公倍数、统计字符类型、求特殊数列和、计算阶乘和双阶乘、以及求斐波那契数列的前20项和。通过这些实例,帮助读者掌握C语言的基本语法和常用算法,提升编程能力。
|
1月前
|
机器学习/深度学习 存储 缓存
数据结构与算法学习十:排序算法介绍、时间频度、时间复杂度、常用时间复杂度介绍
文章主要介绍了排序算法的分类、时间复杂度的概念和计算方法,以及常见的时间复杂度级别,并简单提及了空间复杂度。
24 1
数据结构与算法学习十:排序算法介绍、时间频度、时间复杂度、常用时间复杂度介绍
|
29天前
|
存储 算法 Java
Set接口及其主要实现类(如HashSet、TreeSet)如何通过特定数据结构和算法确保元素唯一性
Java Set因其“无重复”特性在集合框架中独树一帜。本文解析了Set接口及其主要实现类(如HashSet、TreeSet)如何通过特定数据结构和算法确保元素唯一性,并提供了最佳实践建议,包括选择合适的Set实现类和正确实现自定义对象的hashCode()与equals()方法。
32 4
|
1月前
|
机器学习/深度学习 人工智能 算法
【玉米病害识别】Python+卷积神经网络算法+人工智能+深度学习+计算机课设项目+TensorFlow+模型训练
玉米病害识别系统,本系统使用Python作为主要开发语言,通过收集了8种常见的玉米叶部病害图片数据集('矮花叶病', '健康', '灰斑病一般', '灰斑病严重', '锈病一般', '锈病严重', '叶斑病一般', '叶斑病严重'),然后基于TensorFlow搭建卷积神经网络算法模型,通过对数据集进行多轮迭代训练,最后得到一个识别精度较高的模型文件。再使用Django搭建Web网页操作平台,实现用户上传一张玉米病害图片识别其名称。
54 0
【玉米病害识别】Python+卷积神经网络算法+人工智能+深度学习+计算机课设项目+TensorFlow+模型训练
|
1月前
|
机器学习/深度学习 算法 Python
探索机器学习中的决策树算法:从理论到实践
【10月更文挑战第5天】本文旨在通过浅显易懂的语言,带领读者了解并实现一个基础的决策树模型。我们将从决策树的基本概念出发,逐步深入其构建过程,包括特征选择、树的生成与剪枝等关键技术点,并以一个简单的例子演示如何用Python代码实现一个决策树分类器。文章不仅注重理论阐述,更侧重于实际操作,以期帮助初学者快速入门并在真实数据上应用这一算法。
|
1月前
|
机器学习/深度学习 人工智能 Rust
MindSpore QuickStart——LSTM算法实践学习
MindSpore QuickStart——LSTM算法实践学习
40 2
|
1月前
|
搜索推荐 算法
数据结构与算法学习十四:常用排序算法总结和对比
关于常用排序算法的总结和对比,包括稳定性、内排序、外排序、时间复杂度和空间复杂度等术语的解释。
19 0
数据结构与算法学习十四:常用排序算法总结和对比
|
1月前
|
存储 缓存 分布式计算
数据结构与算法学习一:学习前的准备,数据结构的分类,数据结构与算法的关系,实际编程中遇到的问题,几个经典算法问题
这篇文章是关于数据结构与算法的学习指南,涵盖了数据结构的分类、数据结构与算法的关系、实际编程中遇到的问题以及几个经典的算法面试题。
29 0
数据结构与算法学习一:学习前的准备,数据结构的分类,数据结构与算法的关系,实际编程中遇到的问题,几个经典算法问题