【发布时间】:2021-08-23 04:09:40
【问题描述】:
我有一个用于循环链表的自定义数据结构。它的目的非常小众,所以想知道有没有办法让每个节点都指向一块连续的内存块中的一个地址,从而实现随机访问。该列表在初始填充后根本不会被修改(插入/删除),因此连续块不会妨碍我认为的任何事情。
我怎样才能做到这一点?
另外,我不使用向量的原因是因为我正在基于指针重新排列对列表执行旋转。但是,我正在按 O(n) 重新排列指针,而如果我使用连续的内存空间,我相信我可以通过指针算法按 O(1) 重新排列指针。
为了更清楚而编辑: 我的“名单”是这样的
// barebones circular list structure
class List
{
private:
struct Node
{
Node* next;
int data;
};
// beginning of list
Node* start;
// end of list which POINTS to beginning as well
Node* end;
// number of list elements
int size;
public:
List()
{
start = NULL;
end = NULL;
size = 0;
}
~List();
// populates the list using size parameter and uses stdin for the values
void populate_list(const int &size);
// moves the starting pointer of a list, effectively rotating it
void move_start(int n, char d);
// print contents of list
void print();
};
正如我所说,列表的所有元素(节点)都是通过填充列表填充的。人口的约定是从 1 开始的顺序。因此,假设您的大小为 5,则列表填充为 {1,2,3,4,5}。然后,给定一个旋转列表的数量,我通过move_start()旋转
// moves starting node by n spaces in d direction
void List::move_start(int n, char d)
{
// left rotation procedure
if (d == 'L')
{
// move the start pointer the given rotation amount
for (int i = 0; i < n; i++)
start = start->next;
}
// right rotation procedure
else if (d == 'R')
{
// move the start pointer by the size of the list minux the given rotation amount
for (int i = 0; i < size-n; i++)
start = start->next;
}
return;
}
也许我的理解是错误的,但我相信我在 O(n) 处“旋转”,因为我将 start 指针从 1 到 size-1 次(。但如果我有一个连续的块Nodes,然后我可以简单地将 start 分配到一个新位置,而不是走到那里 (O(1))。希望这能解决问题。
【问题讨论】:
-
如果你想让你的节点是连续的,那么为什么不直接使用数组或向量呢?
-
@JamesNewman 仅供参考——在广泛使用使用指针的语言之前,链表是使用数据/下一个对的数组实现的,其中“下一个”将是下一个节点所在位置的索引位于链表中。我不知道这是否适合您,但它就是这样做的。至少,你会得到你正在寻找的连续性。
-
要求不明确。理由尚不清楚。对我来说,可能类似于
deque,但我不确定。 -
“我将指针重新排列为 O(n),而我相信我可以通过指针算法将指针重新排列 O(1)” 这是一个相当神秘的陈述。你能显示一些代码吗?
-
看起来你需要一个循环缓冲区而不是链表。
标签: c++ memory-management linked-list