为什么对链表使用动态分配

Why is dynamic allocation used for Linked lists?

本文关键字:动态分配 链表 为什么      更新时间:2023-10-16
Struct node { char ch; node *link;};
node * temp = new node;
node *temp1;

我的问题是,为什么我们使用第一种方法来声明动态结构,而不是第二种方法。我试着使用第二个,再加上一个类来模拟堆栈,但display()函数将其变成了一个无限循环,而使用前者则纠正了它。为什么?

您的问题还不完全清楚,但这个

Node *temp1;

只是创建一个不指向Node对象的指针。事实上,它指向一个你可以认为是随机的位置。您不能取消引用此指针,必须先使其指向Node

另一方面,

Node * temp = new Node;

在RHS上动态分配一个Node,返回一个指向Node的指针,其值用于初始化temp。所以temp指向一个有效的Node对象。请记住,在某个时刻,您将不得不对分配给new的所有内容调用delete。在现代C++中,您可以避免这种手动内存管理,并将其委托给智能指针之类的类型。

注意以上假设所讨论的类型称为Node,而不是node

可以在不使用new的情况下构建链表,但在大多数情况下,这不是一个非常实用的解决方案。我们使用链表(以及树和其他"链接"数据结构)的原因是为了有某种方法在结构中存储任意数量的元素,在结构中可以很容易地添加/删除在中间的元素。如果不是这样的话,我们也可以使用数组或向量。

我们可以这样做来制作一个简短的链接列表:

Node a, b, c;
Node *head = &a;  // Head is the pointer to the first element. 
a.link = &b;
b.link = &c;
c.link = NULL; 
// Clearly we want to set ch in each node as well, but I'm ignoring it for shortness.

但如果我们不知道需要多少链接,这会变得非常混乱。

因此,我们使用堆来分配元素,因为我们事先不知道它们有多少。

链表使用指向列表中"下一个"(或"上一个")节点的指针——这样,我们可以很容易地在列表的中间插入一个元素。或者从中间移除一个元素。

在1000个元素的向量中,删除第一个元素意味着将999个元素"上移一步"。要删除链接列表中的第一个元素,基本上需要一个更改:将列表的标题移动到下一个元素。

移除向量的第500个元素需要移动499个元素"向上一步"。删除链接列表的第500个元素需要从第499个链接循环指向第501个元素。这需要一次手术。(当然,我们还需要找到要删除的正确元素,但除非向量中的元素以某种有助于搜索的方式进行排序,否则这基本上是相同的工作)。