想知道链表里插入点的操作错在哪里了

现在有一个链表,链表顺序是按照节点里的权值weight从小到大排序的。函数功能是每次将两边前两个点的权值相加,然后删去前两个点,将相加后的权值赋值到新的节点里,再把这个节点插入到链表里,并且保持从小到大顺序不变,但程序一直报错,又不知道错在哪里,想让大家帮忙看看哪一步错了
程序里要插入的节点是r,链表头指针是head,以下代码里的一次循环

 void HuffmanCode::getMin(int& first, int& second, int parent, sequence* head)
{
    sequence* p, * q, * r;
    p = head, q = p->next;
    head = q->next;
    first = p->number;
    second = q->number;
    r = new sequence;
    r->weight = p->weight + q->weight;
    r->number = parent;
    delete p;
    delete q;

    cout << parent - leafSize << endl;
    sequence* s;//将新节点插入到链表里
    if (head != NULL)
    {
        if (r->weight < head->weight)//最小权值两个数相加之后权值还是最小,则新节点插入到表头之前
        {
            r->next = head;
            head = r;
        }
        else
        {
            for (s = head; s->next != NULL; s = s->next)
            {
                if (r->weight >= s->weight && r->weight <= s->next->weight)//插入到链表中间
                {
                    r->next = s->next;
                    s->next = r;
                    break;
                }
            }
            if (s->next == NULL)//插入到链表最后
            {
                s->next = r;
                r->next = NULL;
            }
        }
    }
    else
        head = r;
}

TechWhizKid参考GPT回答:


修改以解决上述问题:

void HuffmanCode::getMin(int& first, int& second, int parent, sequence*& head)
{
    sequence* p, * q, * r;
    p = head, q = p->next;
    head = q->next;
    first = p->number;
    second = q->number;
    r = new sequence;
    r->weight = p->weight + q->weight;
    r->number = parent;
    delete p;
    delete q;
 
    cout << parent - leafSize << endl;
    sequence* s;//将新节点插入到链表里
    if (head != NULL)
    {
        if (r->weight < head->weight)//最小权值两个数相加之后权值还是最小,则新节点插入到表头之前
        {
            r->next = head;
            head = r;
        }
        else
        {
            for (s = head; s != NULL; s = s->next)
            {
                if (s->next == NULL || r->weight <= s->next->weight)//插入到链表中间或者尾部
                {
                    r->next = s->next;
                    s->next = r;
                    break;
                }
            }
        }
    }
    else
        head = r;
}


主要的改动在于:

  • 修改了函数签名,将head的类型改为了sequence*&,这样对head的修改就可以反映到函数外部。

  • 修改了插入新节点的逻辑,现在即使新节点应该被插入到链表的尾部,这段代码也能正确地处理。

问题如下:

  • 插入新节点的逻辑是正确的,一个重要的问题可能会导致程序错误,那就是当新节点需要被插入到链表的尾部时。

问题出在这段代码:

if (s->next == NULL)//插入到链表最后
{
    s->next = r;
    r->next = NULL;
}


  • 这段代码是在你已经遍历完整个链表并未找到合适的插入位置时执行的,意味着新节点应该被插入到链表的尾部。但是,你的循环条件是s->next != NULL,当r的权值比链表中所有存在的节点的权值都大时,你的循环会在最后一个节点之前就结束,因此r永远不会被插入到链表的尾部。
  • 这就是你的问题所在。你可以通过改变循环条件来修复这个问题。这里是一种可能的解决方案:
for (s = head; s != NULL; s = s->next)
{
    if (s->next == NULL || r->weight <= s->next->weight)//插入到链表中间或者尾部
    {
        r->next = s->next;
        s->next = r;
        break;
    }
}


  • 将循环条件改为s != NULL,并在循环内部检查s->next == NULL。这样,如果我们到达了链表的尾部,我们就将新节点插入到链表的尾部。

  • 另外,你在函数开始时更改了head的值,但是这个变化没有反映到函数外部。C++中的参数传递默认是值传递,所以当你修改head的时候,实际上你只是修改了这个函数内的局部变量。如果你希望修改反映到函数外部,你应该使用指针的引用作为参数,像这样:

void HuffmanCode::getMin(int& first, int& second, int parent, sequence*& head)