单链表实现快排

大耗子 2021年02月17日 16次浏览

单链表实现快排

该方法通过前后指针的方式实现。

通过后指针不停的走,获取数据只要小于哨兵值,就交换到前指针。所以该方法也就不需要链表的前序节点。下面是具体实现。

#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;
}

运行结果

单链表实现快排

数组的方式实现

https://codemouse.online/archives/2020-07-17171801