zoukankan      html  css  js  c++  java
  • lua-设计与实现-4表

    1 表

    typedef struct Table {
      CommonHeader;
      //表示这个表中提供了哪些元方法 最开始这个flags 的,也就是 ,当查找一次之后,如果该表中存在某个元方法
      lu_byte flags;  /* 1<<p means tagmethod(p) is not present */ 
      lu_byte lsizenode;  /* log2 of size of `node' array *///散列桶数组的大小的 log2(size)
      struct Table *metatable;
      TValue *array;  /* array part */
      Node *node;	//散列桶数组起始位置的指针
      Node *lastfree;  /* any free position is before this position *///散列桶数组最后位置的指针
      GCObject *gclist; //GC相关的链表
      int sizearray;  /* size of `array' array */
    } Table;
    
    • 桶中链地址实现的单链表靠key关联

    确定数组部分大小的标准是什么呢?

    • 希望在调整过后,**数组在每一个2次方位置(1开始)容纳的元素数量都超过该范围的50% ** (认为这个数组范围发挥了最大的效率)

    未解疑问

    • 如何触发rehash。(代码逻辑是mainPositions没有free-nil位置触发,待求证)
    • hash部分的表查询如果实现??

    nums数组解释:

    // 只有利用率超过50%的数组元素会进入数组,否则进去hash
    static int computesizes (int nums[], int *narray) {
      int i;
      int twotoi;  /* 2^i */
      int a = 0;  /* number of elements smaller than 2^i */
      int na = 0;  /* number of elements to go to array part */
      int n = 0;  /* optimal size for array part */
    
      // 这个循环完毕后,最重要的na存放的是数组部分的数据数量,而n是
      // na满足这个条件:在
      for (i = 0, twotoi = 1; twotoi/2 < *narray; i++, twotoi *= 2) {
        if (nums[i] > 0) {
          // 加上当前数量
          a += nums[i];
          // 如果数量已经超过半数, 那么数组的尺寸可以设置为这个大小
          if (a > twotoi/2) {  /* more than half elements present? */
            n = twotoi;  /* optimal size (till now) */
            // 记录下当前的数组大小
            na = a;  /* all elements smaller than n will go to array part */
          }
        }
        if (a == *narray) break;  /* all elements already counted */
      }
      *narray = n;
      lua_assert(*narray/2 <= na && na <= *narray);
      return na;
    }
    

    举例:
    1,2,5,7,8,9
    数组部分的长度为4时,就不符合大于50%的使用率了。(只有1,2落入数组)

    表查找

    在数组部分查找数据:

    • 查找成功,返回该key 的下一个数据

    否则在散列桶部分查找数据:

    • 查找成功,返回该key 的下一个数据
    • 注意点:
      1,key为1,1.0这两种情况,如何确保算出的hash值一样。答:底层都是用double来表示number。

    2 扩展笔记

    2.1 表"#"特性总结

    • 对数组table,#取长度,底层直接获取(此时的前提是hash部分的头部node为nil),并不是遍历 (时间复杂度O(1))--luaH_getn
    • 对混合型table,#取长度,结果不可靠。 并不是返回前面数组的长度(这是误解,而是根据元素情况不定,可能会使用二分查找遍历或者其他--具体不纠缠)
      Lua源码阅读笔记 - table的长度

    总结:

    数组在每一个2次方位置(1开始)容纳的元素数量都超过该范围的50%

    表的hash部分和C#的Dictionary原理大同小异

    对数组table,#取长度,底层直接获取 -时间复杂度O(1)

    对混合型table,#取长度,结果不可靠。

  • 相关阅读:
    手机缺失sqlite3时操作数据库的多种解决方案 ----adb命令科普
    adb root错误信息adbd cannot run as root in production builds问题解决
    Android Studio中导入v4,v7和recyclerview-v7包的方法
    AndroidStudio项目提交到github最详细步骤
    Android微信开放平台,申请移动应用的 应用签名 如何获取
    利用Intent.ACTION_SEND进行分享
    51nod 1737配对
    UTR#2 T1
    bzoj4571: [Scoi2016]美味
    bzoj2006: [NOI2010]超级钢琴
  • 原文地址:https://www.cnblogs.com/Jaysonhome/p/13420211.html
Copyright © 2011-2022 走看看