繁体   English   中英

单链表

[英]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 ),则当循环结束时,应在currentcurrent->next之间插入新节点,即current用作代码中的previous你现在有。 如果current->nextNULL则在末尾插入。

无法对此进行测试,但是将新的节点设置代码移动到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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM