利用快排对单向链表进行排序,左右指针法和挖坑法都是不能使用的,因为这两种方法都要从最后往前进行查找,但是链表是双向的,往前面走是不可能的,所以只能采用前后指针法。
struct ListNode
{
int _val;
ListNode* _next;
ListNode(const int x)
:_val(x)
, _next(NULL)
{}
};
//快速排序(前后指针法)
//这里注意一定要传引用,如果不传引用会导致连接不上的问题
void sort_quick(ListNode* &head, ListNode* &end)
{
if (head == NULL&&head == end)
{
return;
}
//设置快排基准值,将基准值进行单独保存
int key = head->_val;
ListNode* ret = head->_next;
head->_next = NULL;
//标识两个分区的头尾,pre用来向后标识记录节点
ListNode* head1 = NULL;
ListNode* pre1 = NULL;
ListNode* end1 = NULL;
ListNode* head2 = NULL;
ListNode* pre2 = NULL;
ListNode* end2 = NULL;
//head1链表存放大于key的数值
while (ret != NULL)
{
if (ret->_val > key)
{
if (head1 == NULL)
{
head1 = ret;
pre1 = ret;
}
else
{
pre1->_next = ret;
pre1 = ret;
}
ret = ret->_next;
pre1->_next = NULL;
}
//head2存放小于基准值的数据
else
{
if (head2 == NULL)
{
head2 = ret;
pre2 = ret;
}
else
{
pre2->_next = ret;
pre2 = ret;
}
ret = ret->_next;
pre2->_next = NULL;
}
}
//记录尾节点
end1 = pre1;
end2 = pre2;
//对分区进行同样的操作
sort_quick(head1, end1);
sort_quick(head2, end2);
//将分区进行连接
if (head1 != NULL&&head2 != NULL)
{
end1->_next = head;
head->_next = head2;
head = head1;
end = end2;
}
else if (head1 != NULL)
{
end1->_next = head;
end = head;
head = head1;
}
else if (head2 != NULL)
{
head->_next = head2;
end = end2;
}
}