Я пытаюсь реализовать сортировку пузыря в связанном списке. Однако я получаю ошибки доступа:
Unhandled exception at 0x001A8C7B in program.exe: 0xC0000005: Access violation reading location 0xCCCCCCCC.
Эта ошибка возникает в моем методе сортировки пузырьков:
if (current->data > nextElement->data)
звонить в основной
list1.SortList();
структура
struct IntNode
{
int data;
IntNode * next;
};
сортировка пузырьков
void NodeSLList::SortList()
{
if (head == NULL || head->next == NULL)
return;
IntNode * current = head;
IntNode * nextElement = current->next;
IntNode * temp = NULL;
int changed = 1;
while (changed)
{
changed = 0;
for (current; current != NULL; current = current->next)
{
if (current->data > nextElement->data) //ACCESS ERROR
{
temp = current;
current = nextElement;
nextElement = temp;
changed = 1;
}
nextElement = nextElement->next;
}
}
}
Я изменил внутреннюю часть цикла:
for (current; (current != NULL) && (nextElement = NULL); )
{
if (current->data > nextElement->data)
{
temp = current->next;
current->next = nextElement->next;
nextElement->next = temp;
changed = 1;
}
current = current->next;
nextElement = nextElement->next;
}
Однако мой список продолжает выводить тот же список.
Вам нужно проверить, является ли следующий nextElement
равно NULL. Рассмотрим список из двух элементов:
A --> B --> NULL
На вашей первой итерации через в while
цикл, сначала вы будете иметь current == A
и nextElement == B
... и тогда вы будете иметь current == B
и nextElement == NULL
, что вы все еще пытаются захватить data
и, следовательно, нарушение вашего доступа.
Просто измените условие цикла:
for (current; current != NULL; current = current->next)
в
for (current; current != NULL && nextElement = NULL; current = current->next)
И, возможно, даже переместите следующий nextElement = nextElement->next
в линию цикла, для большей ясности.
Это решает ваше нарушение доступа, но оно не решает проблему "на самом деле не сортировать". Это потому, что вы ничего не меняете в своем цикле. Снова рассмотрите вышеприведенный цикл и примите его обратно, и вам нужно его переключить:
A --> B --> NULL
^ ^
crt next
После вашего свопа вы получите
A --> B --> NULL
^ ^
next current
Вы успешно поменяли указатели, но на самом деле вы не изменили порядок списка. То, что вам нужно изменить, - это next
указатели. В частности, три из них: current
, следующий nextElement
и current
родительский.
for (current; current != NULL; current = current->next)
Здесь ток может указывать на последний узел, в этот момент nextElement = NULL.
поэтому данные nextElement->data
недействительны.
temp = current->next; current->next = nextElement->next; nextElement->next = temp;
однако список все тот же.next
указателя, вы должны изменить три.