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

简介: 数据结构与算法作为计算机学科中至关重要的一门课程,在日常业务代码中常常很难用到或者说很难进行相关的实践,我们常常在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)

相关文章
机器学习/深度学习 算法 自动驾驶
1149 0
|
6月前
|
消息中间件 缓存 NoSQL
Redis各类数据结构详细介绍及其在Go语言Gin框架下实践应用
这只是利用Go语言和Gin框架与Redis交互最基础部分展示;根据具体业务需求可能需要更复杂查询、事务处理或订阅发布功能实现更多高级特性应用场景。
393 86
|
6月前
|
算法 API 数据安全/隐私保护
深度解析京东图片搜索API:从图像识别到商品匹配的算法实践
京东图片搜索API基于图像识别技术,支持通过上传图片或图片URL搜索相似商品,提供智能匹配、结果筛选、分页查询等功能。适用于比价、竞品分析、推荐系统等场景。支持Python等开发语言,提供详细请求示例与文档。
|
8月前
|
存储 监控 安全
企业上网监控系统中红黑树数据结构的 Python 算法实现与应用研究
企业上网监控系统需高效处理海量数据,传统数据结构存在性能瓶颈。红黑树通过自平衡机制,确保查找、插入、删除操作的时间复杂度稳定在 O(log n),适用于网络记录存储、设备信息维护及安全事件排序等场景。本文分析红黑树的理论基础、应用场景及 Python 实现,并探讨其在企业监控系统中的实践价值,提升系统性能与稳定性。
424 1
|
8月前
|
存储 监控 算法
基于跳表数据结构的企业局域网监控异常连接实时检测 C++ 算法研究
跳表(Skip List)是一种基于概率的数据结构,适用于企业局域网监控中海量连接记录的高效处理。其通过多层索引机制实现快速查找、插入和删除操作,时间复杂度为 $O(\log n)$,优于链表和平衡树。跳表在异常连接识别、黑名单管理和历史记录溯源等场景中表现出色,具备实现简单、支持范围查询等优势,是企业网络监控中动态数据管理的理想选择。
211 0
|
9月前
|
监控 算法 安全
公司电脑监控软件关键技术探析:C# 环形缓冲区算法的理论与实践
环形缓冲区(Ring Buffer)是企业信息安全管理中电脑监控系统设计的核心数据结构,适用于高并发、高速率与短时有效的多源异构数据处理场景。其通过固定大小的连续内存空间实现闭环存储,具备内存优化、操作高效、数据时效管理和并发支持等优势。文章以C#语言为例,展示了线程安全的环形缓冲区实现,并结合URL访问记录监控应用场景,分析了其在流量削峰、关键数据保护和高性能处理中的适配性。该结构在日志捕获和事件缓冲中表现出色,对提升监控系统效能具有重要价值。
256 1
|
10月前
|
监控 算法 数据处理
基于 C++ 的 KD 树算法在监控局域网屏幕中的理论剖析与工程实践研究
本文探讨了KD树在局域网屏幕监控中的应用,通过C++实现其构建与查询功能,显著提升多维数据处理效率。KD树作为一种二叉空间划分结构,适用于屏幕图像特征匹配、异常画面检测及数据压缩传输优化等场景。相比传统方法,基于KD树的方案检索效率提升2-3个数量级,但高维数据退化和动态更新等问题仍需进一步研究。未来可通过融合其他数据结构、引入深度学习及开发增量式更新算法等方式优化性能。
247 17
|
10月前
|
存储 算法 安全
如何控制上网行为——基于 C# 实现布隆过滤器算法的上网行为管控策略研究与实践解析
在数字化办公生态系统中,企业对员工网络行为的精细化管理已成为保障网络安全、提升组织效能的核心命题。如何在有效防范恶意网站访问、数据泄露风险的同时,避免过度管控对正常业务运作的负面影响,构成了企业网络安全领域的重要研究方向。在此背景下,数据结构与算法作为底层技术支撑,其重要性愈发凸显。本文将以布隆过滤器算法为研究对象,基于 C# 编程语言开展理论分析与工程实践,系统探讨该算法在企业上网行为管理中的应用范式。
274 8
|
10月前
|
存储 监控 算法
基于 C# 时间轮算法的控制局域网上网时间与实践应用
在数字化办公与教育环境中,局域网作为内部网络通信的核心基础设施,其精细化管理水平直接影响网络资源的合理配置与使用效能。对局域网用户上网时间的有效管控,已成为企业、教育机构等组织的重要管理需求。这一需求不仅旨在提升员工工作效率、规范学生网络使用行为,更是优化网络带宽资源分配的关键举措。时间轮算法作为一种经典的定时任务管理机制,在局域网用户上网时间管控场景中展现出显著的技术优势。本文将系统阐述时间轮算法的核心原理,并基于 C# 编程语言提供具体实现方案,以期深入剖析该算法在局域网管理中的应用逻辑与实践价值。
246 5
|
存储 机器学习/深度学习 算法
C 408—《数据结构》算法题基础篇—链表(下)
408考研——《数据结构》算法题基础篇之链表(下)。
453 30