有序双链表搜索
ordered doubly linked list search
假设我们有一个按整数值排序的双链表:
struct ListItem
{
int value;
ListItem *prev, *next;
};
struct List
{
ListItem *first, *last;
int count;
};
我们可以使用更快的搜索算法,如二进制搜索来定位List
中的ListItem
,如何定位?
对于大多数实际用途,不需要。如果您想要更快的搜索,那么链表是一个糟糕的数据结构选择。可以考虑vector、deque、set或multiset。
编辑:也许提供一些关于哪些是有意义的指导会很好。如果有两个基本独立的阶段,那么向量最有意义:要么按顺序插入所有数据,要么插入并排序,然后在数据排序后,数据保持静态,只需在其中进行搜索。deque几乎是一样的,除了你可以在任意一端插入,所以如果你可能会让数据乱序,但新数据总是属于集合的一端或另一端,它可能是一个很好的选择。
一个set
或multiset
工作更好,如果你要混合插入/删除与查找。它始终保持排序,因此搜索总是相当快。在这两者之间(set vs. multiset),选择非常简单:如果你需要确保集合中的每个道具都是唯一的,你就会选择set。如果可能有多个具有相同键的项,则需要使用multiset。
如果节点之间没有基于这些值的排序,则没有其他选择,只能单独检查所有。因此O (n)。
是的,你可以,但除非"比较值"的操作比"移动指针"的操作成本高得多,否则它完全没有意义。由于"move"的代价通常与"compare"差不多,因此使用普通搜索:
- O (N)动作
- O (N)比较
- O(N)移动以确定列表的大小
- O(N)移动定位元素
- O (log (N))比较。
在你的例子中,value是"int",这意味着比较比移动更便宜,所以二进制算法将会更昂贵。
如果您知道列表的大小,二进制可能会(有争议地)变得更便宜,但是双向逻辑传输和元素计数增加的复杂性将抵消减少值比较次数带来的任何好处。
当然,如果需要多次搜索,最简单的方法是将链表转换为数组或创建索引——指针数组。如果值比int
复杂得多,比较起来也困难得多,当然更需要更快的算法。
好吧,你仍然需要循环遍历所有元素直到中间的元素。因为这个原因,我不确定二分查找是否会加快链表的搜索速度。例如,在这种情况下,元素在中间元素之前,从逻辑上讲,循环遍历这些元素似乎更快。否则,你只需要走到中间,看看你的元素与它的关系,然后再循环一次,是的……骑车才是真正的致命伤。我想这也取决于你的元素在列表中的确切位置
如果只需要执行几次搜索,我认为从头到尾搜索列表是最好的选择。也许有一些算法可以更有效,但它只会稍微好一点。
但是,如果您必须执行多次搜索,则将列表复制到支持二进制搜索的有序随机访问容器中是一种可行的方法。
- 为什么当我尝试搜索双链表中第一个数据条目之外的数据时,程序崩溃了?
- Sinlge 链表,C++,删除所有和搜索功能的问题
- 这是在传递 int num 时创建搜索函数的正确方法吗?使用链表库
- 快速搜索链表未编译,需要返回语句
- 搜索链表时出现隔离错误
- 双向链表插入方法实现 - 正在搜索哪个节点
- 不太确定如何从这里继续前进.是否使用链表进行搜索
- 在双向链表中搜索
- 搜索链表
- C++有序链表搜索函数算法逻辑
- 链表中的搜索功能 - C++
- 有没有人知道如何在C++的链表上运行插值搜索
- 双链表并使用反向搜索
- 如何使用信号和插槽从qt表单中获取id,然后在链表中搜索它并使用另一个表单显示结果
- 链表中的线性搜索[语言:C++编译器:Dev Cpp 4.9.9.2]
- 将节点插入二进制搜索树/链表
- C++链表搜索错误:STATUS_ACCESS_VIOLATION
- 正在搜索“链表”是否为空
- 使用c++在链表中搜索操作
- 转换二叉搜索树到链表