提高链表随机访问效率的一种方案

一、问题的描述

    链表由于各个元素之间是通过指针方式连接在一起,所以增加删除都非常方便,但是在随机访问却远不如数组。数组的下标是可以通过算法直接定位的,但链表却不行。

二、问题的方案
    我们定义一种组织方式,以链表为基础,但是将相连的若干元素组成一个簇,和一个节点相关联。这个节点只负责管理链表元素的指针头部,和这个簇的所有元素的数量。当链表增加删除元素时,可以通过改变节点所记录的簇的头部和簇的数量来重新管理簇。如果这个节点没有簇元素,那么将这个节点删除,如果这个节点记录的簇元素数量超出最高限度,那么将进行分裂。当簇中元素作为链表的元素删除时,只需要减少节点记录簇元素的数量。
    我们通过树来管理这些节点,将这些节点作为树的叶子。树的节点可以支持N个分支,对于每个分支,只记录分支下所有的簇元素数量。
    我们这个方案的核心方案是通过树的方式来组织每个元素的下标,利用树的节点访问速度来拉近链表和数组之间的下标访问效率,同时保持链表增删元素的灵活性。我们打个比方,1个1K个节点的链表,如果要访问第500个节点,必须遍历500次,如果有个中间节点记录第500个节点的位置,那么我们只要遍历一次。

三、问题的分析
    现在我们来计算添加树管理下标所需要的节点访问次数。包括树高度和叶子节点的数量,如果叶子节点只有一个,那这个树就退化成二叉树了,所以叶子节点包含的链表节点数是个很关键的问题。实际访问次数等于树的层高加上叶子的链表节点数。

一、链表元素结构
    typedef struct _elem_st elem_t
    struct _elem_st{
           elem_t *prev ;
           elem_t *next;
           int len ;
           char *buf ;
    } ;

    这是个双向链表,在增加删除时要方便多了。

二、索引结构
    1、叶子结构
    typedef struct _leaf_st leaf_t ;
    struct _leaf_st{
           elem_t *header ;
           int count ;
    } ;

    2、节点结构
    typedef struct _node_st node_t
    struct _node_st{
          leaf_t *leafs[1024] ;
          int count ;
    } ;

    3、树结构
    typedef struct _tree_st tree_t ;
    struct _tree_st{
           node_t *nodes[1024] ;
           int count ;
    } ;

    上面定义的结构很笨,但是很容易说明思路。我们现在来模拟增加删除一个元素,看这个过程。

一、定位元素
    elem_t *find_elem(int index) ;
    1、顺序遍历tree->nodes数组,直到count
    2、累计node->count,直到index在两个node之间
    3、找到对应的leaf_t,很容易返回。

二、删除元素
    1、判断下标小于数的总节点数
    2、定位元素下标
    3、从树的顶层开始,到该元素的每个路经的节点,计数器减1。
    4、删除链表中该元素。

三、增加元素
    2、定位元素下标
    3、从树的顶层开始,到该元素的每个路经的节点,计数器加1。
    4、在链表中添加该元素。

我们访问的方式比数组多很多,但是链表要少很多。



  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值