单链表实现快排
该方法通过前后指针的方式实现。
通过后指针不停的走,获取数据只要小于哨兵值,就交换到前指针。所以该方法也就不需要链表的前序节点。下面是具体实现。
#include<iostream>
#include<ctime>
using namespace std;
struct ListNode {
int val;
ListNode *next;
ListNode(int x) : val(x), next(NULL) {}
};
ListNode *ghead = NULL;
class Solution {
public:
ListNode * sortList(ListNode *head) {
ListNode * phead = head;
qSortList(phead, NULL);
return head;
}
void qSortList(ListNode * head, ListNode * tail) {
// 如果没有头说明该范围只有0个数据.
// 如果头的下一个节点空说明该范围只有1个数据.
// 如果head->next == tail说明该范围只有1个数据.
// 如果head == tail说明该范围只有0个数据.
if (!head || !head->next || head->next == tail || head == tail) return;
ListNode * pfront = head, *pafter = head->next;
ListNode * ptmp = head;
while (pafter && pafter != tail) {
if (ptmp->val > pafter->val) {
pfront = pfront->next;
// 如果前后指针是同一个,那就没有必要交换
if (pfront != pafter) {
// 将后指针的数据交换到前指针
swap(pafter->val, pfront->val);
}
}
pafter = pafter->next;
}
// 将哨兵的值与前指针数据交换
swap(pfront->val, ptmp->val);
// 打印出来方便观察变化
print(ghead);
qSortList(head, pfront);
// 此时pafter有可能是空
qSortList(pfront->next, pafter);
}
void print(ListNode *head) {
ListNode *phead = head;
ListNode *ptmp = NULL;
while (phead) {
std::cout << phead->val << " ";
phead = phead->next;
}
std::cout << endl;
}
};
// 测试数据个数
#define SIZE_TEST 100
int main()
{
ListNode* head0 = new ListNode(15);
ListNode* head = head0;
ghead = head0;
srand(time(NULL));
// 初始化节点
for (int i = 0; i < SIZE_TEST; i++)
{
ListNode* mNode = new ListNode(rand() % 100);
head0->next = mNode;
head0 = head0->next;
}
Solution sln;
sln.print(head);
ListNode*res = sln.sortList(head);
while (res != NULL)
{
cout << res->val << " ";
res = res->next;
}
return 0;
}
运行结果