zoukankan      html  css  js  c++  java
  • 一种高效的可变行高列表行定位算法

    列表控件是数据显示时使用的一种常用的控件。

    刚发现有网友把这个算法说得更清楚,推荐大家去它的博客看https://www.jianshu.com/p/76827322f33f

    下面是我提供的原始的版本 :)

    一般情况下列表中的行是等高的,这种情况下无论列表包含多少行,都能够在O(1)的时间定位到指定行。

    但是当显示的内容格式不一致时,使用相等的行高可能就意味着显示空间的浪费,也意味说用户需要更多的滚动操作,影响用户体验。

    要实现一个支持可变行高的列表控件,首先要解决的问题就是快速定位列表行。

    假定一个列表中的表项按照下面的高度排列:

    1,2,3,1,2,3,1,2,3,1,2,3,4,5

    可以知道总高度为:33

    程序员需要解决从一个随机的[0,32]的值(x)定位到哪一行的问题。

    当然最简单的办法就是从第一行开始逐行的数,直到数到的那一行正好包含x,可以知道这个算法的时间复杂度为O(n)。

    当n很大时,这个算法基本上不可行。

    一行一行的数显然是很浪费时间的,解决的办法就是一段一段的数。

    要实现分段数,一个前提就是我们需要为这些数据提前建立好索引表。对于上面序列假定以3个元素一组为单位建立索引表就可以获得:(6),(6),(6),(6),(9),如此一来,要定位一行,我们最多需要数5+3次就能找到一行。

    对于数据量比较少的情况,可能上述分组方法就能解决问题了。

    但是对于数据量更大的情况如何处理呢?方法很简单,那就是分组再分组,直到最后所有的分组数据形成一棵索引树。树上每一个结点代表该结点下所有子节点的高度和。

    通过构造索引树,无论多少数据量,都可以在O(log(n))的时间定位到任意行。

    另外,对于大量数据,我们可能在初始化的时候并不知道总数有多少,而是在显示到哪一行时再通过计算获得。

    对于这种情况,我们需要动态更新索引树。更新过程也很简单,当一行更新高度时,只需要找到该行所在的叶节点,更新叶节点高度,再逐级更新父节点即可,时间复杂度同样是O(log(n))。

    具体实现可以参考SOUI的ListView中用于可变行高支持的类:SListViewItemLocatorFlex

  • 相关阅读:
    移动端阻止事件冒泡需要注意!
    JavaScript闭包
    JS原型与原型链终极讲解
    逐行分析jQuery源码
    jQuery源码分析-03构造jQuery对象-源码结构和核心函数
    screenX clientX pageX的区别
    JSON.stringify 语法实例讲解
    pipenv 简要指南
    webpy简单使用
    初识Dash -- 构建一个人人都能够轻松上手的界面,操控数据和可视化
  • 原文地址:https://www.cnblogs.com/setoutsoft/p/4711139.html
Copyright © 2011-2022 走看看