为单连锁列表增加价值
Adding value to singly-linked list
我在C 数据结构类中,最近的作业已经困扰了我几天。它必须处理与单连锁列表一起工作,而我们必须写的方法之一与将值添加到列表中有关。
首先,我们创建虚拟节点head
:
template<typename T>
SLList<T>::SLList()
{
head = new Node; // Node() is ok too
}
如果我正确,这不应该拥有一个价值,应该吗?因此头应为NULL
。到目前为止,这就是我设法创建的(在教授的帮助下)。
template<typename T>
void SLList<T>::add(const T& val) {
bool duplicate = false;
//Node *ptr = head->next;
//cout << head->data;
for (Node *ptr = head->next; ptr != NULL; ptr = ptr->next) {
//while (ptr == NULL) {
//ptr = ptr->next;
// if ptr is initialized as head, the first node, then ptr != NULL
// if ptr is initialized as head->next, which it should in order to
// traverse from the node AFTER the head, then ptr == NULL
// not exactly sure why.
if (ptr->data == val) {
duplicate = true;
break;
}
}
//Node *temp = new Node(val); // create new node with new element.
//temp->next = ptr->next;
//ptr->next = temp;
if (duplicate) {
cout << "Duplicate entry found: " << val << endl;
}
}
我已经尝试使用for
和while
循环,因为许多Google结果都使用了while
循环。我要做的是尝试在列表中添加一个值。如果该值已经在该列表中,则不会添加。我正在尝试以下方式:
SLList<int> iList;
iList.add(5);
iList.add(6);
iList.add(6);
当我寻求帮助时,我被告知我应该将*ptr
初始化为head->next
,以开始在虚拟节点后开始遍历节点的列表。我使用了Visual Studio的调试器,发现将其初始化为head->next
后,该程序从未进入for循环,我认为这是因为虚拟节点后的节点失败了IF语句ptr != NULL
。我不确定为什么这样做,就像我有Node *ptr = head
时一样,它会遍历列表,尽管以下行if (ptr->data == val)
将每个条目都视为重复条目)。
我可能理解这是错误的,但是head
节点不应该具有NULL
的值吗?因此,它不应通过for
循环中的if
语句。
for
循环之后的三行似乎也有问题,因为当程序到达那里时,它只是崩溃了,未能在列表中添加任何值一次踩踏。
我在这里可能有很多误解,因此任何帮助都将不胜感激。
尝试这样的东西:
template<typename T>
void SLList<T>::add(const T& val) {
Node<T>* prev = head;
for (Node<T>* ptr = head->next; ptr; ptr = ptr->next) {
if (ptr->data == val) {
std::cout << "Duplicate: " << val << 'n';
return;
}
prev = ptr;
}
prev->next = new Node<T>(val);
}
您的主要设计缺陷似乎就是这样:您将进入列表的尽头并从那里拿走,但结束是无效的,因此您需要回溯一次以找到并非零的东西。例如(基本示例)
Node<T>* last = head;
for(Node<T>* ptr = head->next; ptr != NULL ; ptr = ptr->next){
last = ptr;
//do something
}
因此,当循环结束时,您知道如果ptr==NULL
,则last
是您的列表的尾巴,您要添加的任何内容都必须遵循。
这也是for
循环之后的三行代码中的问题:如果我正确理解您,则在没有重复的情况下,您会迭代,直到ptr
为NULL
。因此,退出for时,ptr->next
将失败。这意味着,当添加元素时,如果该元素不在列表中 - 您的函数失败(设计而不是偶然)。
head
当列表为空时,头必须为空。这发生在创建或添加和删除相等数量的节点之后。在所有其他情况下,头部必须是非零的,并且必须指向第一个添加的节点。
add(典型)
Node * ptr = new Node;
ptr->next = head;
head = ptr;
添加(仅添加非曲子)
bool const exists = std::find( list, element );
if( ! exists ) {
Node * ptr = new Node;
ptr->next = head;
head = ptr;
}
您在这里有几个选项。最常见的是,您将head
指针设置为NULLPTR,直到添加节点为止。在这种情况下,您根本没有(或需要)虚拟节点。
另一种可能性是创建最初包含虚拟节点的列表。这可以在某种程度上简化代码的其余部分,因为它避免了将第一个节点添加到空列表中的任何特殊案例代码。您还可以将虚拟节点用作"哨兵",其中包含一些在列表其余部分中不允许的数据项。在正确的情况下,这可以通过允许您查看包含的数据而不是检查列表末端的空指针来简化列表遍历。一个主要示例是您按顺序排序的浮点数列表,其中包含infinity
的虚拟节点。在这种情况下,找到一个数字可以从:
while (ptr != nullptr && ptr->data < search_item) {
// ...
ptr=ptr->next;
}
...仅:
while (ptr->data < search_item) {
// ...
ptr = ptr->next;
}
列表末尾的infinity
可确保如果列表中的其他任何内容都不大于search_item
,则虚拟节点将是(尽管这显然需要您确保以infinity
作为其值将项目插入列表中)。
但是,这与您在问题中建议的用法不同 - 它要求虚拟节点始终保留为列表中的 last 项目,因此您永远不会在其之后插入任何内容。但是,至少根据我的经验,这比始终在列表开始的虚拟节点更为普遍。
- 数组索引的值没有增加
- Pybind11:将元组列表从Python传递到C++
- 从链接列表c++中删除一个项目
- 如何(从固定列表中)选择一个数字序列,该序列将与目标数字相加
- C++如何通过用户输入删除列表元素
- 读取文件的最后一行并输入到链接列表时出错
- 复制列表初始化的隐式转换的等级是多少
- 为什么我的代码在输出中增加了93天
- LNK2038、MSVS2017 MAGMA的原因列表
- 不能在初始值设定项列表中将非常量表达式从类型 'int' 缩小到'unsigned long long'
- 没有为自己的结构调用列表推回方法
- 使用简单类型列表实现的指数编译时间.为什么
- 一对向量构造函数:初始值设定项列表与显式构造
- 标准是否使用多余的大括号(例如 T{{{10}}})定义列表初始化?
- 有效地使用std::unordered_map来插入或增加键的值
- 通过for循环使用用户输入填充列表
- 为单连锁列表增加价值
- 在C++中增加列表的所有元素
- 编写布尔表达式以判断列表是否在增加
- 在增加一个元素后对列表进行排序