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