Data structures 具有pull-first和Elest-java的数据结构

Data structures 具有pull-first和Elest-java的数据结构,data-structures,map,Data Structures,Map,我正在寻找具有以下功能的数据结构: -有重点和价值 -可以在O(n)>t>O(logn)或O(1)中找到值 -可以拉动我插入的第一个元素和最后一个元素 TreeMep不好,因为如果我插入键(作为字符串)“b”,然后插入键“a”,如果我拉动第一个键,我将得到“a”而不是“b” ConcurrentSkipListMap不好,因为我不能依赖于size func' 非常感谢您的帮助 谢谢您可以使用一个deque(双端队列)与一个multimap(特别是一个二进制搜索树)交叉引用,它允许重复键 队列的每

我正在寻找具有以下功能的数据结构: -有重点和价值 -可以在O(n)>t>O(logn)或O(1)中找到值 -可以拉动我插入的第一个元素和最后一个元素

TreeMep不好,因为如果我插入键(作为字符串)“b”,然后插入键“a”,如果我拉动第一个键,我将得到“a”而不是“b”

ConcurrentSkipListMap不好,因为我不能依赖于size func'

非常感谢您的帮助


谢谢

您可以使用一个
deque
(双端队列)与一个
multimap
(特别是一个二进制搜索树)交叉引用,它允许重复键

队列的每个元素都有一个对映射的相应元素的引用(迭代器),反之亦然

通过这种方式,您可以在O(logn)中的映射中进行搜索,并且可以在O(logn)中的序列两端进行推/拉操作

您可以决定将字符串存储在映射或队列中

下面是C++中的一个实现:

#include <string>
#include <map>
#include <deque>

typedef int         my_key_type;       // Key type
typedef std::string my_value_type;     // Value type

struct queueitem;                                   // Queue element

typedef std::deque<queueitem> my_queue;             // Queue

typedef std::multimap <my_key_type,               
                       my_queue::iterator> my_map;  // Map

typedef std::pair <my_key_type,                  
                   my_queue::iterator> my_map_pair; // Map element

struct queueitem
{
    my_value_type value;
    my_map::iterator mapitem;

    queueitem (const my_value_type & val) : value(val) {}
};

class mapqueue
{
    public:

        mapqueue () {}

        my_value_type find (my_key_type key) const;
        size_t index_of (my_key_type key) const;

        my_value_type front_value () const { return Q.front().value; }
        my_value_type back_value () const { return Q.back().value; }

        my_key_type front_key () const
        { return Q.front().mapitem->first; }

        my_key_type back_key () const
        { return Q.back().mapitem->first; }

        void push_front (my_key_type key,
                         const my_value_type & value);

        void push_back (my_key_type key,
                        const my_value_type & value);

        void pop_front ();
        void pop_back ();

    private:

        my_queue Q;
        my_map M;

        mapqueue (const mapqueue &) {}
        mapqueue & operator= (const mapqueue &) { return *this; }
};

using namespace std;

my_value_type mapqueue::find (my_key_type key) const
{
    my_map::const_iterator it = M.find (key);

    if (it==M.end())
        throw "Not found";

    return it->second->value;
}

size_t mapqueue::index_of (my_key_type key) const
{
    my_map::const_iterator it = M.find (key);

    if (it==M.end())
        throw "Not found";

    return it->second - Q.begin();
}

void mapqueue::push_front (my_key_type key,
                           const my_value_type & value)
{
    Q.push_front (queueitem(value));
    my_queue::iterator qit = Q.begin ();
    qit->mapitem = M.insert (my_map_pair(key,qit));
}

void mapqueue::push_back (my_key_type key,
                          const my_value_type & value)
{
    Q.push_back (queueitem(value));
    my_queue::iterator qit = Q.end () - 1;
    qit->mapitem = M.insert (my_map_pair(key,qit));
}

void mapqueue::pop_front ()
{
    M.erase (Q.front().mapitem);
    Q.pop_front ();
}

void mapqueue::pop_back ()
{
    M.erase (Q.back().mapitem);
    Q.pop_back ();
}
#包括
#包括
#包括
typedef int my_key_type;//键类型
typedef std::string my_value_type;//值类型
结构queueitem;//队列元素
typedef std::定义我的队列;//队列
typedef std::multimap my_map;//地图
typedef std::pair my_map_pair;//地图元素
结构队列项
{
我的值类型值;
我的地图::迭代器地图项目;
queueitem(const my_value_type&val):值(val){}
};
类映射队列
{
公众:
映射队列(){}
my_value_type find(my_key_type key)常量;
(我的密钥类型密钥)常量的大小索引;
my_value_type front_value()常量{return Q.front().value;}
my_value_type back_value()常量{return Q.back().value;}
我的钥匙类型前钥匙()常数
{返回Q.front().mapitem->first;}
my_key_type back_key()常量
{返回Q.back().mapitem->first;}
无效向前推(我的钥匙类型钥匙,
const my_value(类型和值);
无效推回(我的钥匙类型钥匙,
const my_value(类型和值);
void pop_front();
void pop_back();
私人:
我的Q;
我的地图;
mapqueue(常量mapqueue&){}
mapqueue&运算符=(const mapqueue&){return*this;}
};
使用名称空间std;
我的值类型映射队列::查找(我的键类型键)常量
{
mymap::const\u迭代器it=M.find(key);
如果(it==M.end())
抛出“未找到”;
返回->秒->值;
}
大小映射队列::(我的密钥类型密钥)常量的索引
{
mymap::const\u迭代器it=M.find(key);
如果(it==M.end())
抛出“未找到”;
返回它->秒-Q.begin();
}
void mapqueue::push_front(my_key_type key,
常量我的值(类型和值)
{
Q.push_front(队列项(值));
我的队列::迭代器qit=Q.begin();
qit->mapitem=M.insert(我的映射对(key,qit));
}
void mapqueue::push_back(我的_键类型键,
常量我的值(类型和值)
{
Q.push_back(queueitem(value));
我的队列::迭代器qit=Q.end()-1;
qit->mapitem=M.insert(我的映射对(key,qit));
}
void mapqueue::pop_front()
{
M.erase(Q.front().mapitem);
Q.pop_front();
}
void mapqueue::pop_back()
{
M.erase(Q.back().mapitem);
Q.pop_back();
}
这还支持在O(logn)中的任何给定键的队列中查找索引。如果不需要,可以简化将字符串存储在映射中并删除映射到队列的引用的设计

更新:现在通过
typedef
s指定键和值类型。这样很容易改变它们。在一个由这两种类型参数化的模板中转换整个内容会很有趣。这样,即使在同一个程序中,相同的代码也可以用于不同的键值类型对


更新:有一个用于一般情况的工具:更新。请参见文档中的。

或者您可以使用映射,只需将插入的第一个和最新元素存储在一对变量中:)否,这还不够好,数据结构将在hashmap中,所以我不想为每个值保存第一个值和第二个值。一个与列表交叉引用的映射如何?有人能将其翻译成Java吗?我想OP需要一个java解决方案,但我是C++的人;键需要是字符串,所以我需要像objectEasy一样的键;-)只需更改第五行中
std::string
int