单链表

时间:2013-11-02 15:03:26

标签: c++ data-structures 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;  

5 个答案:

答案 0 :(得分:0)

在另一个变量(比如x)中获取前一个变量(比如p)的值,并使用x而不是p。

答案 1 :(得分:0)

一个简单的解决方案是首先检查是否应该在头部之前插入。如果没有,那么使用类似于你的循环但与current->next进行比较(如果不是NULL),那么当循环结束时,应在currentcurrent->next之间插入新节点,即current在您现在的代码中用作previous。如果current->nextNULL,则插入结尾。

答案 2 :(得分:0)

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

答案 3 :(得分:0)

这应该有效:

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;  
}

答案 4 :(得分:0)

你无法消除“先前”变量,但你可以伪装它;此外,您可以构造循环,使其成为唯一迭代变量。

当然要插入新的,您需要更新上一个节点以指向它。

您可以通过查看列表并处理各种情况从当前节点执行此操作。

另一种方法是保持指向前一节点中指针字段的指针。

node **ppnode;

for (ppnode = &head;
     *ppnode != NULL && (*ppnode)->value >= newnode->value;
     ppnode = &(*ppnode)->next) 
   ; /* empty body */

newnode->next = (*ppnode) ? (*ppnode)->next : NULL;
*ppnode = newnode;

这里,我们使用current指针间接指向当前节点,而不是使用ppnode指针指向当前节点。它指向指向该节点的指针,而不是指向该节点(因此它必须适当地键入:它是指向指针的指针:双星)。

指向第一个节点的指针是列表head变量,因此ppnode最初指向head变量。之后每个其他节点的指针是前一个节点的next字段:这些next字段中的每一个都非常类似于列表其余部分的head。因此,使用这个ppnode变量,我们可以跟踪上一个节点中必须更新的位置,而无需跟踪前一个节点本身。这让我们可以处理没有上一个节点的列表大小写的前面。

让我们来看看head为空(列表为空)的情况。

ppnode指向head。但*ppnode为空,因此循环体永远不会执行。

由于ppnode指向head,所以行:

newnode->next = (*ppnode) ? (*ppnode)->next : NULL;
*ppnode = newnode;

具有与以下相同的含义:

newnode->next = head ? head->next : NULL;
head = newnode;

这些行中的条件检查处理将新节点添加到空列表或非空列表尾部的情况。如果列表为空或者其中的所有值都小于新值,则循环终止,ppnode指向列表的空终止符,如果列表为空则为head,否则尾节点的next字段。由于*ppnode为空,因此我们无法尊重(*ppnode)->next。没有下一个;

表示新节点是最后一个节点,其next必须为空。

现在让我们看看在有一个头节点的情况下会发生什么,并且它的值更大,以便必须在前面插入新节点。在这种情况下,ppnode指向head,与之前一样,*ppnode != NULL条件为真。但是(*ppnode)->value >= newnode->value条件失败,因此循环永远不会执行。

现在,我们再次执行相当于此代码:

newnode->next = head ? head->next : NULL;
head = newnode;

但是这次head不是空的,因此newnode->next = head->nextnewnode一样,head成为新的head

所有其他情况都从这两个开始:除了next之外,使用前一个节点的{{1}}指针进行操作,这类似于列表其余部分的头部。