[英]Singly Linked List
I have a project from https://hotfile.com/dl/253309046/133284f/4_SinglyLinkedList.rar.html 我有一个来自https://hotfile.com/dl/253309046/133284f/4_SinglyLinkedList.rar.html的项目
The function insertOrdered()
inserts scores in order. 函数insertOrdered()
按顺序插入分数。
My questions is: can this loop be rewritten without using a "previous" variable? 我的问题是:可以在不使用“上一个”变量的情况下重写此循环吗?
SinglyNode* current = head;
SinglyNode* previous= NULL;
while (current != NULL)
{
if(newNode->score >= current->score)
previous = current;
else
break;
current = current->next;
}
newNode->next = previous->next;
previous->next = newNode;
获取另一个变量(例如x)中先前变量的值(例如p),并使用x代替p。
A simple solution is to first check if it should be inserted before the head. 一个简单的解决方案是首先检查是否应将其插入头部。 If not then use a loop similar to your but compare against current->next
(if not NULL
), then when the loop ends the new node should be inserted between current
and current->next
, ie current
is used as previous
in the code you have now. 如果不是,则使用类似于您的循环,但将其与current->next
比较(如果不是NULL
),则当循环结束时,应在current
和current->next
之间插入新节点,即current
用作代码中的previous
你现在有。 If current->next
is NULL
then insert at end. 如果current->next
为NULL
则在末尾插入。
Not able to test this, but moving the new node setup code into the if block should allow you to remove the previous variable. 无法对此进行测试,但是将新的节点设置代码移动到if块中应该可以删除以前的变量。
SinglyNode* current = head;
while (current != NULL)
{
if(newNode->score >= current->score) {
newNode->next = current->next;
current->next = newNode;
}
else break;
current = current->next;
}
if(current == NULL) { // got to end of list
current->next = newNode;
newNode->next = NULL;
}
This should work: 这应该工作:
SinglyNode* current = head;
if(current == NULL) {
head = newNode;
}
else if(newNode->score < current->score) {
newNode->next = current;
head = newNode;
}
else {
while (current->next != NULL)
{
if(newNode->score < current->next->score)
break;
current = current->next;
}
newNode->next = current->next;
current->next = newNode;
}
You cannot eliminate the "previous" variable, but you can disguise it; 您不能消除“上一个”变量,但是可以掩饰它; and furthermore, you can structure the loop so that it is the only iteration variable. 而且,您可以构造循环,使其成为唯一的迭代变量。
Of course to insert the new, you need to update the previous node to point to it. 当然要插入新节点,您需要更新前一个节点以指向它。
You can do that from the current node by looking ahead in the list and handling various cases. 您可以通过在列表中向前看并处理各种情况从当前节点执行此操作。
Another way is to keep a pointer to the pointer field in the previous node. 另一种方法是将指针保留到上一个节点中的指针字段。
node **ppnode;
for (ppnode = &head;
*ppnode != NULL && (*ppnode)->value >= newnode->value;
ppnode = &(*ppnode)->next)
; /* empty body */
newnode->next = (*ppnode) ? (*ppnode)->next : NULL;
*ppnode = newnode;
Here, instead of using a current
pointer to point to the current, we use a ppnode
pointer which points to the current node indirectly. 在这里,我们使用一个ppnode
指针间接指向当前节点,而不是使用current
指针指向当前节点。 Instead of pointing to that node, it points to the pointer which points to that node (and so it must be suitably typed: it is a pointer to pointer: double star). 它不是指向该节点,而是指向指向该节点的指针(因此必须正确键入:它是指向指针:双星的指针)。
The pointer to the first node is the list head
variable, so ppnode
points to that head
variable initially. 指向第一个节点的指针是列表head
变量,因此ppnode
最初指向该head
变量。 The pointer to every other node after that is the next
field of the previous node: each one of these next
fields is really like a head
of the rest of the list. 指向此后每个其他节点的指针是上一个节点的next
字段:这些next
字段中的每个字段实际上都像列表其余部分的head
。 So with this one ppnode
variable, we keep track of the location within the previous node that must be updated, without keeping track of the previous node itself. 因此,使用这个ppnode
变量,我们可以跟踪必须更新的上一个节点中的位置,而不必跟踪上一个节点本身。 And this lets us handle the front of list case where there is no previous node. 这使我们能够处理没有前一个节点的列表开头的情况。
Let's trace through the case that head
is null (the list is empty). 让我们追溯一下head
为null(列表为空)的情况。
ppnode
points to head
. ppnode
指向head
。 But *ppnode
is null, and so the loop body never executes. 但是*ppnode
为null,因此循环体从不执行。
Since ppnode
points to head
, the lines: 由于ppnode
指向head
,因此行:
newnode->next = (*ppnode) ? (*ppnode)->next : NULL;
*ppnode = newnode;
have the same meaning as: 具有以下含义:
newnode->next = head ? head->next : NULL;
head = newnode;
The conditional check in these lines handles the case when the new node is added to an empty list or to the tail of a nonempty list. 这些行中的条件检查处理了将新节点添加到空列表或非空列表尾部的情况。 If the list is empty or all the values in it are smaller than the new value, then the loop terminates with ppnode
pointing at the list's null terminator, which is head
if the list is empty, or else the next
field of the tail node. 如果列表为空,或者列表中的所有值都小于新值,则循环终止, ppnode
指向列表的空终止符,如果列表为空,则终止符为head
,否则为尾节点的next
字段。 Since *ppnode
is null, we cannot deference (*ppnode)->next
. 由于*ppnode
为null,因此我们无法参考(*ppnode)->next
。 There is no next; 没有下一个; the new node is the last node and its next
must be nulled. 新节点是最后一个节点, next
必须为空。
Now let's look what happens in the case that there is a head node, and its value is greater so that the new node must be inserted at the front. 现在,让我们看一下在存在头节点的情况下会发生什么,并且其值更大,因此必须在前面插入新节点。 In this case ppnode
points to head
, as before, and the *ppnode != NULL
condition is true. 在这种情况下, ppnode
像以前ppnode
指向head
,并且*ppnode != NULL
条件为true。 However the (*ppnode)->value >= newnode->value
condition fails and so the loop never executes. 但是(*ppnode)->value >= newnode->value
条件失败,因此循环永远不会执行。
Now, again, we are executing the equivalent of this code: 现在,我们再次执行以下代码:
newnode->next = head ? head->next : NULL;
head = newnode;
But this time head
is not null, and so newnode->next = head->next
, and, as before, newnode
becomes the new head
. 但是这次head
不为空,因此newnode->next = head->next
,和以前一样, newnode
成为新的head
。
All the other cases proceed from these two: except instead of head
, the action plays out using the next
pointer of the previous node, which is like the head of the rest of the list. 所有其他情况都从这两种情况出发:除了代替head
,该动作使用上next
节点的next
指针进行播放,就像该列表的其余部分的头一样。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.