[英]Singly Linked List
我有一个来自https://hotfile.com/dl/253309046/133284f/4_SinglyLinkedList.rar.html的项目
函数insertOrdered()
按顺序插入分数。
我的问题是:可以在不使用“上一个”变量的情况下重写此循环吗?
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。
一个简单的解决方案是首先检查是否应将其插入头部。 如果不是,则使用类似于您的循环,但将其与current->next
比较(如果不是NULL
),则当循环结束时,应在current
和current->next
之间插入新节点,即current
用作代码中的previous
你现在有。 如果current->next
为NULL
则在末尾插入。
无法对此进行测试,但是将新的节点设置代码移动到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;
}
这应该工作:
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;
}
您不能消除“上一个”变量,但是可以掩饰它; 而且,您可以构造循环,使其成为唯一的迭代变量。
当然要插入新节点,您需要更新前一个节点以指向它。
您可以通过在列表中向前看并处理各种情况从当前节点执行此操作。
另一种方法是将指针保留到上一个节点中的指针字段。
node **ppnode;
for (ppnode = &head;
*ppnode != NULL && (*ppnode)->value >= newnode->value;
ppnode = &(*ppnode)->next)
; /* empty body */
newnode->next = (*ppnode) ? (*ppnode)->next : NULL;
*ppnode = newnode;
在这里,我们使用一个ppnode
指针间接指向当前节点,而不是使用current
指针指向当前节点。 它不是指向该节点,而是指向指向该节点的指针(因此必须正确键入:它是指向指针:双星的指针)。
指向第一个节点的指针是列表head
变量,因此ppnode
最初指向该head
变量。 指向此后每个其他节点的指针是上一个节点的next
字段:这些next
字段中的每个字段实际上都像列表其余部分的head
。 因此,使用这个ppnode
变量,我们可以跟踪必须更新的上一个节点中的位置,而不必跟踪上一个节点本身。 这使我们能够处理没有前一个节点的列表开头的情况。
让我们追溯一下head
为null(列表为空)的情况。
ppnode
指向head
。 但是*ppnode
为null,因此循环体从不执行。
由于ppnode
指向head
,因此行:
newnode->next = (*ppnode) ? (*ppnode)->next : NULL;
*ppnode = newnode;
具有以下含义:
newnode->next = head ? head->next : NULL;
head = newnode;
这些行中的条件检查处理了将新节点添加到空列表或非空列表尾部的情况。 如果列表为空,或者列表中的所有值都小于新值,则循环终止, ppnode
指向列表的空终止符,如果列表为空,则终止符为head
,否则为尾节点的next
字段。 由于*ppnode
为null,因此我们无法参考(*ppnode)->next
。 没有下一个; 新节点是最后一个节点, next
必须为空。
现在,让我们看一下在存在头节点的情况下会发生什么,并且其值更大,因此必须在前面插入新节点。 在这种情况下, ppnode
像以前ppnode
指向head
,并且*ppnode != NULL
条件为true。 但是(*ppnode)->value >= newnode->value
条件失败,因此循环永远不会执行。
现在,我们再次执行以下代码:
newnode->next = head ? head->next : NULL;
head = newnode;
但是这次head
不为空,因此newnode->next = head->next
,和以前一样, newnode
成为新的head
。
所有其他情况都从这两种情况出发:除了代替head
,该动作使用上next
节点的next
指针进行播放,就像该列表的其余部分的头一样。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.