C 双链接列表中的冒泡排序导致尝试从NULL读取

C 双链接列表中的冒泡排序导致尝试从NULL读取,c,sorting,linked-list,C,Sorting,Linked List,我试图编码冒泡排序,通过比较来排序一个链表。问题是,在某个时刻,冒泡排序函数向比较函数发送一个空指针,这会导致运行时错误。具体来说,列表的最后一项指向NULL 其思想是分别进行第一次迭代。这样我就可以得到第一次比较列表的次数;然后,我可以使用这个数字在不同的循环中继续排序 这是代码。谢谢你的帮助 void SortItemList(Item* ptrFirstItem, int(*compare)(const Item*,const Item*)) {

我试图编码冒泡排序,通过比较来排序一个链表。问题是,在某个时刻,冒泡排序函数向比较函数发送一个空指针,这会导致运行时错误。具体来说,列表的最后一项指向NULL

其思想是分别进行第一次迭代。这样我就可以得到第一次比较列表的次数;然后,我可以使用这个数字在不同的循环中继续排序

这是代码。谢谢你的帮助

void SortItemList(Item* ptrFirstItem, 
                  int(*compare)(const Item*,const Item*))
{
  Item* currentItem=ptrFirstItem;
  Item* nextItem;
  int itemSize=0;
  int i,j;

  //in case no items or just one
  if (currentItem==NULL || currentItem->nextItem==NULL)
    return;
  else
    {
      //first iteration also checking how many items to compare
      nextItem=currentItem->nextItem;
      while(nextItem!=NULL)
        {
          itemSize++;

          if(compare(currentItem, nextItem)>0)
            swapItems(currentItem, nextItem);

          currentItem=nextItem;
          nextItem=nextItem->nextItem;
        }
      itemSize--;

      for(i=0;i<itemSize;i++)
        {
          currentItem=ptrFirstItem;
          nextItem=currentItem->nextItem;

          for(j=0;j<itemSize-i;j++)
            {
              if(compare(currentItem, nextItem)>0)
                swapItems(currentItem, nextItem);

              currentItem=nextItem;
              nextItem=nextItem->nextItem;
            }
        }
    }
return;
}
void SortItemList(项目*ptrFirstItem、,
int(*比较)(常数项*,常数项*)
{
项目*currentItem=ptrFirstItem;
项目*nextItem;
int itemSize=0;
int i,j;
//如果没有物品或只有一件
如果(currentItem==NULL | | currentItem->nextItem==NULL)
返回;
其他的
{
//第一次迭代还将检查要比较的项目数
nextItem=currentItem->nextItem;
while(nextItem!=NULL)
{
itemSize++;
如果(比较(currentItem,nextItem)>0)
swapItems(当前项,下一项);
currentItem=nextItem;
nextItem=nextItem->nextItem;
}
项目大小--;
对于(i=0;不精确;
对于(j=0;j0)
swapItems(当前项,下一项);
currentItem=nextItem;
nextItem=nextItem->nextItem;
}
}
}
返回;
}

当然,以下是一个问题。虽然DL列表已更新,但
currentItem
nextItem
的本地值未更新。发生交换时,这需要更改

if(compare(currentItem, nextItem) > 0) 
  swapItems(currentItem, nextItem);

currentItem = nextItem;
nextItem = nextItem->nextItem;
也许吧


第一个问题是功能:

void SortItemList(Item* ptrFirstItem, 
                  int(*compare)(const Item*,const Item*))
那是行不通的。你需要能够写信给ptrFirstItem

void SortItemList(Item** ptrptrFirstItem, 
                  int(*compare)(const Item*,const Item*))

交换也需要这种能力。

NPE问题的澄清
@Ryan假设我们有一个排序的列表,itemsize是4,即索引从0到3。所以“i”将从0循环到3。所以对于i=0,“j”将从0循环到4-0=4。所以当“i”=0时,currItem指向第0个元素,nextItem指向第1个元素。现在j将从0循环到3。对于j=0,因为列表已排序,所以没有交换。所以现在currentItem will指向第一个元素,nextItem指向第二个元素。对于当前结束时的j=1,Item指向第二个元素,nextItem指向第三个元素。对于当前结束时的j=2,Item指向第三个元素,nextItem指向第四个元素。因为第四个元素为空,所以现在nextItem具有空值。对于当前结束时的j=3,Item指向第四个元素Item将指向第4个元素,nextItem将导致NPE为null。nextItem将导致NPE

我怀疑您的j for循环将导致NPE,因为假设列表按升序排列,因此在currentItem和nextItem的比较条件值之后没有交换,因此对于j=0 currentItem=1/nextItem=2,j=1 currentItem=2/nextItem=3,j=2 currentItem=3/nextItem=4,现在由于nextItem已经为空,所以j=3,它将为nextItem提供NPE->nextItem。哪个调用比较有问题?你测试了什么数据?我不知道如何检查是哪个调用做的,我只知道它肯定是其中之一,这就是程序中断的地方。@jigar我不知道你的意思。j循环应该在它覆盖所有项目之前停止,为什么中断条件不起作用?现在当我思考它时,它是有意义的,那么我应该基本上做什么?这肯定是一个错误,但它会导致超限吗?我只能看到这也会导致进程前进slowly@Jasen,即
项对于后续的(i=0;i@Ryan希望更新对您有效。在不了解代码的DL细节的情况下,开始/结束情况可能会有其他微妙的问题。编写DL列表的方法不止一种。@chux,是的,我现在明白了,itemsize的初始计数将太高。您是对的,这是我遇到的另一个问题,第一项消失了。
void SortItemList(Item** ptrptrFirstItem, 
                  int(*compare)(const Item*,const Item*))