哪种数据结构最能结合字典和列表的优势

如何解决哪种数据结构最能结合字典和列表的优势

| 我最近问的一个问题使我对以下内容感到疑惑: 存储这样的集合(键,值)对的数据结构是什么: 其元素是有序的
d[key] -> val
具有复杂度
O(dict)
d(index) -> (key,val)
具有复杂度
O(list)
提供反向查找
d{val} -> (index,key)
,复杂度
O(dict)
使用最少的存储空间 当我键入“ 6”时,表示操作的复杂性与数据结构“ 7”相同。 例如,如果有序集合是:
c = {key_1:val_1,key_2:val_2,key_3:val_3}
我想获得
 c[key_1] # returns val_1,as in a dictionary
 c(1)     # returns val_2,as in a list
 c{val_3} # returns (2,key_3) as in a sort of \"indexed dictionary\"
    

解决方法

        您正在通过键和索引以及O(1)值查询来请求O(1)查询。您可以通过维护键/值的哈希数据结构,反向查找的第二个哈希结构以及有序列表->键映射的列表数据结构来做到这一点。不过,您仍然会有O(n)个插入和删除,而且您的空间复杂度将是通常情况下的3倍。 如果您愿意牺牲速度,可以节省空间,那么有很多基于树的设置数据结构(例如Java中的TreeSet),其操作具有复杂度log(n)。 总是要权衡     ,        您没有提到插入成本,这也是一个重要的问题。您可以使用按词法排序的字典来执行此操作,并使用二进制搜索(
log(n)
)处理查找。但是,您将需要维护两个这样的结构,一个结构为key-> val,一个结构为val-> key,因此插入成本将增加一倍,并且在中间插入元素的费用为
O(n)
(即与列表相同)。     ,        我有同样的问题。因此,我采用了java.util.TreeMap的源代码并编写了IndexedTreeMap。它实现了我自己的IndexedNavigableMap:
public interface IndexedNavigableMap<K,V> extends NavigableMap<K,V> {
   K exactKey(int index);
   Entry<K,V> exactEntry(int index);
   int keyIndex(K k);
}
该实现基于更改时更改红黑树中的节点权重。权重是给定节点下的子节点数加上一个-self。例如,当树向左旋转时:
    private void rotateLeft(Entry<K,V> p) {
    if (p != null) {
        Entry<K,V> r = p.right;

        int delta = getWeight(r.left) - getWeight(p.right);
        p.right = r.left;
        p.updateWeight(delta);

        if (r.left != null) {
            r.left.parent = p;
        }

        r.parent = p.parent;


        if (p.parent == null) {
            root = r;
        } else if (p.parent.left == p) {
            delta = getWeight(r) - getWeight(p.parent.left);
            p.parent.left = r;
            p.parent.updateWeight(delta);
        } else {
            delta = getWeight(r) - getWeight(p.parent.right);
            p.parent.right = r;
            p.parent.updateWeight(delta);
        }

        delta = getWeight(p) - getWeight(r.left);
        r.left = p;
        r.updateWeight(delta);

        p.parent = r;
    }
  }
updateWeight只是将权重更新为根:
   void updateWeight(int delta) {
        weight += delta;
        Entry<K,V> p = parent;
        while (p != null) {
            p.weight += delta;
            p = p.parent;
        }
    }
当我们需要按索引查找元素时,这里是使用权重的实现:
public K exactKey(int index) {
    if (index < 0 || index > size() - 1) {
        throw new ArrayIndexOutOfBoundsException();
    }
    return getExactKey(root,index);
}

private K getExactKey(Entry<K,V> e,int index) {
    if (e.left == null && index == 0) {
        return e.key;
    }
    if (e.left == null && e.right == null) {
        return e.key;
    }
    if (e.left != null && e.left.weight > index) {
        return getExactKey(e.left,index);
    }
    if (e.left != null && e.left.weight == index) {
        return e.key;
    }
    return getExactKey(e.right,index - (e.left == null ? 0 : e.left.weight) - 1);
}
查找键的索引也非常方便:
    public int keyIndex(K key) {
    if (key == null) {
        throw new NullPointerException();
    }
    Entry<K,V> e = getEntry(key);
    if (e == null) {
        throw new NullPointerException();
    }
    if (e == root) {
        return getWeight(e) - getWeight(e.right) - 1;//index to return
    }
    int index = 0;
    int cmp;
    if (e.left != null) {
        index += getWeight(e.left);
    }
    Entry<K,V> p = e.parent;
    // split comparator and comparable paths
    Comparator<? super K> cpr = comparator;
    if (cpr != null) {
        while (p != null) {
            cmp = cpr.compare(key,p.key);
            if (cmp > 0) {
                index += getWeight(p.left) + 1;
            }
            p = p.parent;
        }
    } else {
        Comparable<? super K> k = (Comparable<? super K>) key;
        while (p != null) {
            if (k.compareTo(p.key) > 0) {
                index += getWeight(p.left) + 1;
            }
            p = p.parent;
        }
    }
    return index;
}
您可以在http://code.google.com/p/indexed-tree-map/中找到这项工作的结果     

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


依赖报错 idea导入项目后依赖报错,解决方案:https://blog.csdn.net/weixin_42420249/article/details/81191861 依赖版本报错:更换其他版本 无法下载依赖可参考:https://blog.csdn.net/weixin_42628809/a
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下 2021-12-03 13:33:33.927 ERROR 7228 [ main] o.s.b.d.LoggingFailureAnalysisReporter : *************************** APPL
错误1:gradle项目控制台输出为乱码 # 解决方案:https://blog.csdn.net/weixin_43501566/article/details/112482302 # 在gradle-wrapper.properties 添加以下内容 org.gradle.jvmargs=-Df
错误还原:在查询的过程中,传入的workType为0时,该条件不起作用 &lt;select id=&quot;xxx&quot;&gt; SELECT di.id, di.name, di.work_type, di.updated... &lt;where&gt; &lt;if test=&qu
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct redisServer’没有名为‘server_cpulist’的成员 redisSetCpuAffinity(server.server_cpulist); ^ server.c: 在函数‘hasActiveC
解决方案1 1、改项目中.idea/workspace.xml配置文件,增加dynamic.classpath参数 2、搜索PropertiesComponent,添加如下 &lt;property name=&quot;dynamic.classpath&quot; value=&quot;tru
删除根组件app.vue中的默认代码后报错:Module Error (from ./node_modules/eslint-loader/index.js): 解决方案:关闭ESlint代码检测,在项目根目录创建vue.config.js,在文件中添加 module.exports = { lin
查看spark默认的python版本 [root@master day27]# pyspark /home/software/spark-2.3.4-bin-hadoop2.7/conf/spark-env.sh: line 2: /usr/local/hadoop/bin/hadoop: No s
使用本地python环境可以成功执行 import pandas as pd import matplotlib.pyplot as plt # 设置字体 plt.rcParams[&#39;font.sans-serif&#39;] = [&#39;SimHei&#39;] # 能正确显示负号 p
错误1:Request method ‘DELETE‘ not supported 错误还原:controller层有一个接口,访问该接口时报错:Request method ‘DELETE‘ not supported 错误原因:没有接收到前端传入的参数,修改为如下 参考 错误2:cannot r
错误1:启动docker镜像时报错:Error response from daemon: driver failed programming external connectivity on endpoint quirky_allen 解决方法:重启docker -&gt; systemctl r
错误1:private field ‘xxx‘ is never assigned 按Altʾnter快捷键,选择第2项 参考:https://blog.csdn.net/shi_hong_fei_hei/article/details/88814070 错误2:启动时报错,不能找到主启动类 #
报错如下,通过源不能下载,最后警告pip需升级版本 Requirement already satisfied: pip in c:\users\ychen\appdata\local\programs\python\python310\lib\site-packages (22.0.4) Coll
错误1:maven打包报错 错误还原:使用maven打包项目时报错如下 [ERROR] Failed to execute goal org.apache.maven.plugins:maven-resources-plugin:3.2.0:resources (default-resources)
错误1:服务调用时报错 服务消费者模块assess通过openFeign调用服务提供者模块hires 如下为服务提供者模块hires的控制层接口 @RestController @RequestMapping(&quot;/hires&quot;) public class FeignControl
错误1:运行项目后报如下错误 解决方案 报错2:Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile (default-compile) on project sb 解决方案:在pom.
参考 错误原因 过滤器或拦截器在生效时,redisTemplate还没有注入 解决方案:在注入容器时就生效 @Component //项目运行时就注入Spring容器 public class RedisBean { @Resource private RedisTemplate&lt;String
使用vite构建项目报错 C:\Users\ychen\work&gt;npm init @vitejs/app @vitejs/create-app is deprecated, use npm init vite instead C:\Users\ychen\AppData\Local\npm-