C++ 对单链表排序时出现运行时错误
我已经编写了一个链表(针对数据类型int)实现。 似乎工作正常,但当我尝试对列表进行排序时,所有的奇数 元素应位于所有偶数元素之后,并保留偶数和奇数的原始顺序 在MS Visual Studio中调试时,我发现在C++ 对单链表排序时出现运行时错误,c++,sorting,infinite-loop,singly-linked-list,C++,Sorting,Infinite Loop,Singly Linked List,我已经编写了一个链表(针对数据类型int)实现。 似乎工作正常,但当我尝试对列表进行排序时,所有的奇数 元素应位于所有偶数元素之后,并保留偶数和奇数的原始顺序 在MS Visual Studio中调试时,我发现在oddevenSort()函数中,for循环似乎在无限地进行……好像tail->next没有被更新为nullptr。 我似乎无法理解我的逻辑错误在哪里 #include<iostream> template<class T> class SLL_Node { p
oddevenSort()
函数中,for循环似乎在无限地进行……好像tail->next
没有被更新为nullptr
。
我似乎无法理解我的逻辑错误在哪里
#include<iostream>
template<class T>
class SLL_Node
{
public:
T info;
SLL_Node* next;
SLL_Node();
SLL_Node(T el, SLL_Node<T>* n = nullptr);
};
template<class T>
class SLL
{
private:
SLL_Node<T>* head, * tail;
size_t size;
public:
SLL();
~SLL();
bool isEmpty() const;
size_t get_size() const;
void add_to_head(T el);
void add_to_tail(T el);
void delete_at(size_t); //delete at a certain index. Index starting from 1. Throws an error //message if index out of bounds or list empty.
void display()const; //the logic is for mostly primitive data types and not user defined data //types (including classes)
void oddevenSort();
};
template<class T>
bool SLL<T>::isEmpty() const
{
if (tail == nullptr)
return true;
else
return false;
}
template<class T>
SLL_Node<T>::SLL_Node() : next{ nullptr }
{}
template<class T>
SLL_Node<T>::SLL_Node(T el, SLL_Node<T>* n) : info{ el }, next{ n }
{}
template<class T>
SLL<T>::SLL()
{
size = 0;
head = tail = nullptr;
}
template<class T>
void SLL<T>::add_to_tail(T el)
{
++size;
if (!isEmpty())
{
tail->next = new SLL_Node<T>(el);
tail = tail->next;
}
else
head = tail = new SLL_Node<T>(el);
}
template<class T>
void SLL<T>::add_to_head(T el)
{
head = new SLL_Node<T>(el, head);
if (tail == nullptr) //if empty
{
tail = head;
}
++size;
}
template<class T>
void SLL<T>::display()const
{
std::cout << '\n';
for (SLL_Node<T>* tmp{ head }; tmp != nullptr; tmp = tmp->next)
{
std::cout << tmp->info << "->";
}
std::cout << "NULL\n";
}
template<class T>
void SLL<T>::delete_at(size_t index)
{
if (index >= 1 && index <= size) //bound checking
{
if (!isEmpty()) //we dont need is empty since size takes care of that but still adding it for clarity
{
if (head == tail && index == 1) //if list only has one node and we delete head node
{
delete head;
head = tail = nullptr;
}
//otherwise if list more than one node
else if (index == 1) //if deleting head node
{
SLL_Node<T>* tmp{ head };
head = head->next;
delete tmp;
tmp = nullptr;
}
else //deleting other nodes
{
SLL_Node<T>* tmp{ head->next }, * pred{ head };
for (size_t i{ 2 }; i < index; ++i)
{
tmp = tmp->next;
pred = pred->next;
}
pred->next = tmp->next;
if (tmp == tail)
{
tail = pred;
}
delete tmp;
tmp = nullptr;
}
}
}
else
{
std::cout<<"\nError! Either the list is empty or the index entered is out of bounds!\n";
}
}
template<class T>
void SLL<T>::oddevenSort()
{
SLL_Node<T>* t=head;
size_t count{1};
for (; t != nullptr; t = t->next)
{
if (((t->info) % 2) != 0)
{
add_to_tail(t->info);
delete_at(count);
}
++count;
}
}
#包括
模板
类SLL_节点
{
公众:
T信息;
SLL_节点*下一步;
SLL_节点();
SLL_节点(tel,SLL_节点*n=nullptr);
};
模板
类SLL
{
私人:
SLL_节点*头部,*尾部;
大小;
公众:
SLL();
~SLL();
bool isEmpty()常量;
size\u t获取\u size()常量;
无效添加到头(T el);
无效添加到尾部(T el);
void delete_at(size_t);//在某个索引处删除。索引从1开始。如果索引超出范围或列表为空,则抛出错误//消息。
void display()const;//逻辑主要用于基本数据类型,而不是用户定义的数据//类型(包括类)
void oddevenSort();
};
模板
bool SLL::isEmpty()常量
{
if(tail==nullptr)
返回true;
其他的
返回false;
}
模板
SLL_节点::SLL_节点():下一个{nullptr}
{}
模板
SLL_节点::SLL_节点(tel,SLL_节点*n):信息{el},下一个{n}
{}
模板
SLL::SLL()
{
尺寸=0;
头=尾=空PTR;
}
模板
void SLL::将_添加到_尾(T el)
{
++大小;
如果(!isEmpty())
{
tail->next=新SLL_节点(el);
tail=tail->next;
}
其他的
头部=尾部=新的SLL_节点(el);
}
模板
void SLL::将_添加到_头(T el)
{
head=新的SLL_节点(el,head);
if(tail==nullptr)//如果为空
{
尾=头;
}
++大小;
}
模板
void SLL::display()常量
{
std::cout(下一步)
{
std::cout info next},*pred{head};
for(size_t i{2};inext;
pred=pred->next;
}
pred->next=tmp->next;
如果(tmp==尾部)
{
tail=pred;
}
删除tmp;
tmp=nullptr;
}
}
}
其他的
{
标准::coutinfo)%2)!=0)
{
添加到尾部(t->info);
在(计数)处删除_;
}
++计数;
}
}
main:
int main()
{
SLL<int> a;
a.add_to_head(1);
a.add_to_head(2);
a.add_to_tail(3);
a.add_to_tail(4);
a.add_to_head(6);
a.add_to_tail(7);
a.add_to_head(5);
a.display();
//a.oddevenSort();
a.display();
return 0;
}
intmain()
{
slla;
a、 将_添加到_头(1);
a、 将_添加到_头(2);
a、 将_添加到_尾(3);
a、 将_添加到_尾(4);
a、 将_添加到_头(6);
a、 将_添加到_尾(7);
a、 将_添加到_头(5);
a、 显示();
//a、 oddevenSort();
a、 显示();
返回0;
}
考虑一个示例输入oddevenSort
a(1)->b(2)->c(3)->null
t
指向a(1)
使用
数据1
附加在列表末尾,如
b(2)->c(3)->d(1)->null
t
将指向节点b(2)
,并且没有做任何更改
在名单上t
将指向节点c(3)
创建新节点
数据3
,附加在列表末尾,如
b(2)->d(1)->e(3)->null
t
将指向d(1)
,它将在列表末尾创建新节点。迭代在不中断循环的情况下递归地进行template<class T>
void SLL<T>::oddevenSort()
{
SLL_Node <T>tempOddHeader;
SLL_Node <T> *tempOddPtr = &tempOddHeader;
SLL_Node <T> tempEvenHeader;
SLL_Node <T> *tempEvenPtr = &tempEvenHeader;
SLL_Node<T>* t = head;
tempOddHeader.next = nullptr;
tempEvenHeader.next = nullptr;
while(t)
{
if (((t->info) % 2) != 0) {
//append to the odd list
tempOddPtr->next = t;
tempOddPtr = tempOddPtr->next;
t = t->next;
tempOddPtr->next = nullptr;
}
else {
//append to the even list
tempEvenPtr->next = t;
tempEvenPtr = tempEvenPtr->next;
t = t->next;
tempEvenPtr->next = nullptr;
}
}
tempEvenPtr->next = tempOddHeader.next;
head = tempEvenHeader.next;
tail = tempOddPtr;
}
模板
void SLL::oddevenSort()
{
SLL_节点tempOddHeader;
SLL_节点*tempOddPtr=&tempOddHeader;
SLL_节点tempEvenHeader;
SLL_节点*tempEvenPtr=&tempEvenHeader;
SLL_节点*t=头部;
tempOddHeader.next=nullptr;
tempEvenHeader.next=nullptr;
while(t)
{
如果((t->info)%2)!=0){
//追加到奇数列表
tempOddPtr->next=t;
tempOddPtr=tempOddPtr->next;
t=t->next;
tempOddPtr->next=nullptr;
}
否则{
//追加到偶数列表
tempEvenPtr->next=t;
tempEvenPtr=tempEvenPtr->next;
t=t->next;
tempEvenPtr->next=nullptr;
}
}
tempEvenPtr->next=tempOddHeader.next;
head=tempEvenHeader.next;
tail=tempOddPtr;
}
删除(计数)
这是否会导致t
指向的内容出现问题?@drescherjm我现在已经添加了delete\u at()
定义。请看一看问题不在于删除,而在于t
所指的内容。您删除了t指向的节点,然后尝试在删除的节点上执行t=t->next
。在调用delete_at(count)
之前,我应该执行t=t->next
?您可能不应该在该函数中使用delete_at()。并从for(;;)中删除t=t->next
,而将t=t->next
放在循环体中,仅在不删除时使用。