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

C++ 将新节点插入已排序的链表时出现问题,c++,linked-list,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

我正在尝试将一个新节点插入到一个已排序的整数链表中,但在尝试添加到长度超过两个节点的列表时遇到问题。我使用下面的代码来实现这一点

// 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);
我已经检查了我的代码并运行了这些测试,但在逻辑上找不到任何错误。其他人能看出我哪里出了问题吗

完整的
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;
}
//插入新元素
模板
布尔列表::插入(常量类型和新元素)
{
节点*新节点;
节点*TempNext;
节点*TempPrevious;
NewNode=新节点;
NewNode->Element=NewElement;
if(Empty())//如果列表为空
{
头=新节点;
返回true;
}
else if(Head->Next==NULL)//如果列表中只有一个节点
{
//如果元素小于或等于新元素
如果(头->元素)
{
Head->Next=NewNode;
返回true;
}
//如果元素大于新元素
else if(Head->Element>NewNode->Element)
{
新建节点->下一步=头部;
头=新节点;
返回true;
}
}
//多节点列表-该列表至少有两个现有节点
//在第一个和第二个节点初始化占位符指针
TempPrevious=头部;
TempNext=头部->下一步;
//新节点是否在开始时启动?
if(NewNode->ElementElement)
{
新建节点->下一步=临时上一步;
头=新节点;
返回true;
}
进行//迭代,直到找到正确的位置
{       
//新节点是否适合当前选定的节点?
if((NewNode->Element>TempPrevious->Element)&&
(新建节点->元素<临时下一步->元素))
{
NewNode->Next=TempNext;
TempPrevious->Next=NewNode;
返回true;
}
//新节点是否更适合列表中的其他节点?
else if(新节点->元素->临时下一步->元素)
{
//是否已经到达列表的末尾?
如果(TempNext->Next==NULL)
{
TempNext->Next=NewNode;
返回true;
}
//还是还会有更多的节点?
else if(TempNext->Next!=NULL)
{
TempPrevious=TempNext;
TempNext=TempNext->Next;
}
}
}while(NewNode->Next!=NULL);
删除TempNext,TempPrevious;
}

您不必要地将问题过度复杂化了。在您的代码中有几点不太正确:

  • 循环不应该是
    do。。。而
    ——在触摸任何内容之前,您需要检查当前==NULL(以处理空列表)
  • 在循环中,您有一个测试“我在看
    NewNode
    的最终位置吗?”。你不需要任何其他条件,因为如果你不看最后的位置,是时候继续循环了
  • 您可以通过以下方式轻松完成:

    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;
    

    NewNode->Next!=NULL
    始终为false,因此只能通过一次循环

    事实上,该循环应该一直持续到插入节点为止。如果通过条件结束循环,则表示尚未插入节点


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

    我认为问题在于您的while条件,应该是:

    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;
    

    作业如果没有,下面是默认的建议:根据需要使用STL列表或向量类。抱歉,忘了将其标记为:PHave您是否尝试过绘制链表的图表,并逐行浏览代码,并更改图表以匹配代码正在执行的操作?当你有图片的时候,链表更容易理解(如果不画图片,我永远都搞不懂链表的算法!)啊,好地方。不幸的是,将其更改为'TempNext->Next!=NULL)没有修复它。@Chris–如果(
    TempPrevious
    TempNext
    )是最后一对,就在到达
    //列表的末尾是否已经到达?
    子句之前,这将打破循环。非常感谢代码,但它在最后一行的第二行出现了错误。你确定这一切都是正确的吗?
    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;