将新节点插入已排序的链接列表时出现问题

时间:2011-03-19 16:33:54

标签: c++ linked-list

我正在尝试将新节点插入到排序的整数链接列表中,但在尝试添加到长度超过两个节点的列表时遇到问题。我使用以下代码来执行此操作

// Initialise place-holder pointers at first and second nodes
TempPrevious = Head;
TempNext = Head -> Next;

do // Iterate until the right spot is found
{       
    // Does the new node fit between the currently selected nodes?
    if ((NewNode -> Element > TempPrevious -> Element) &&
            (NewNode -> Element < TempNext -> Element))
    {
        NewNode -> Next = TempNext;
        TempPrevious -> Next = NewNode;
        return true;
    }

    // Does the new node fit in further along the list?
    else if (NewNode -> Element > TempNext -> Element)
    {
        // Has the end of the list already been reached?
        if (TempNext -> Next == NULL)
        {
            TempNext -> Next = NewNode;
            return true;
        }

        // Or are there still more nodes to come?
        else if (TempNext -> Next != NULL)
        {
            TempPrevious = TempNext;
            TempNext = TempNext -> Next;
        }
    }
} while (TempNext -> Next != NULL);

我已经考虑了一个空列表,一个单节点列表和一个双节点列表,以及在列表开头插入新节点超过两个元素长,以及所有这些部分工作得很好。我已将此问题确定为所提供代码中的最终else if,因为似乎指针TempNextTempPrevious未随do-whilePrintList()的每次迭代一起移动1}}循环。在构建包含以下元素的列表并观察Input: 1,2,3,4,5 Output: 1,2,0 Input; 5,4,3,2,1 Output: 1,2,3,4,5 函数的输出后,我得出了这个结论:

list :: Insert()

我查看了我的代码并运行了这些测试,但在逻辑中找不到任何错误。任何人都可以看到我在这里出错的地方吗?

完整的// Insert new element template <class Type> bool list<Type> :: Insert (const Type& NewElement) { Node *NewNode; Node *TempNext; Node *TempPrevious; NewNode = new Node; NewNode -> Element = NewElement; if (Empty()) // If the list is empty { Head = NewNode; return true; } else if (Head -> Next == NULL) // If there is only a single node in the list { // If the element is less than or equal to the new one if (Head -> Element <= NewNode -> Element) { Head -> Next = NewNode; return true; } // If the element is greater than the new one else if (Head -> Element > NewNode -> Element) { NewNode -> Next = Head; Head = NewNode; return true; } } // Multi-node lists - the list has at least two existing nodes // Initialise place-holder pointers at first and second nodes TempPrevious = Head; TempNext = Head -> Next; // Does the new node go at the start? if (NewNode -> Element < TempPrevious -> Element) { NewNode -> Next = TempPrevious; Head = NewNode; return true; } do // Iterate until the right spot is found { // Does the new node fit between the currently selected nodes? if ((NewNode -> Element > TempPrevious -> Element) && (NewNode -> Element < TempNext -> Element)) { NewNode -> Next = TempNext; TempPrevious -> Next = NewNode; return true; } // Does the new node fit in further along the list? else if (NewNode -> Element > TempNext -> Element) { // Has the end of the list already been reached? if (TempNext -> Next == NULL) { TempNext -> Next = NewNode; return true; } // Or are there still more nodes to come? else if (TempNext -> Next != NULL) { TempPrevious = TempNext; TempNext = TempNext -> Next; } } } while (NewNode -> Next != NULL); delete TempNext, TempPrevious; } 功能

{{1}}

3 个答案:

答案 0 :(得分:2)

你不必要地过度复杂化了这个问题。您的代码中有几件事情不太正确:

  1. 循环不应该是do ... while - 您想在触摸任何内容之前检查是否Current == NULL(处理空列表)。
  2. 在循环内你测试“我在看NewNode的最终位置吗?”。您不需要任何其他条件,因为如果您查看最终位置,则需要继续循环。
  3. 你可以这么简单:

    Previous = NULL;
    for (Current = Head; Current != NULL; Previous = Current, Current = Current->Next) {
        if (NewNode->Element >= Current->Element) {
            continue;
        }
    
        // Perform the insertion    
        NewNode->Next = Current;
        if (Current == Head) {
            Head = NewNode;
        }
        else {
            Previous->Next = NewNode;
        }
        return;
    }
    
    // We haven't inserted yet after going through all the list
    // Previous now points to the last item, or NULL if the list was empty, so:
    NewNode->Next = NULL;
    if (Previous = NULL) {
        Head = NewNode;
    }
    else {
        Previous->Next = NewNode;
    }
    return;
    

答案 1 :(得分:1)

我认为问题在于你的状况,应该是:

while(TmpNext != NULL)

如果您已经测试了空元素或单个元素列表,则可以将所有其他情况减少为:

TempPrevious = Head;
TempNext = Head->Next;

while(TempNext != NULL)
{
    if (TempNext->Element > NewNode->Element) 
    {
        NewNode->Next = TempNext;
        TempPrevious->Next = NewNode;
        return true;
    }
    TempPrevious = TempNext;
    TempNext = TempNext->Next;
}

// At this point we are sure that we did not inserted the element 
// anywhere in the list so we can safely added to the end
TempPrevious->Next = NewNode;

答案 2 :(得分:0)

NewNode -> Next != NULL总是假的,所以你只能通过循环一次。

实际上,该循环应该继续,直到插入节点。如果您通过条件结束循环,则表示您尚未插入节点。

最后的delete TempNext, TempPrevious负责您的一个示例列表中的0。当您通过这些变量删除时,会销毁它们指向的列表的实际元素。