排序算法——单链表快速排序(划分函数从一边划分)

这篇博客介绍了如何在单链表上实现快速排序算法。通过从前向后进行划分,解决了链表中无法像数组那样方便地从两侧进行比较的问题。文章提供了完整的C++代码示例,包括链表初始化、打印、快速排序的实现以及主函数,展示了单链表快速排序的详细步骤。
摘要由CSDN通过智能技术生成

我们知道了普通的快速排序利用的划分函数是从两边向中间划分,但是对于单链表,这种划分函数可就显得不这么适用了。原因在于单链表每个节点只存在存放后一个结点的指针域,找到后一个节点容易,但是想要找到前一个结点的话,可就显得力不从心了。
所以,我们可以借用普通划分函数的思想,来写一个都从前向后划分的划分函数。
首先我们的i和j肯定都指向前面,我们仍然以第一个值为划分标准 。

ListNode* LinkParition(ListNode* left, ListNode* right)
{
	ListNode* ip = left;
	ListNode* jp = left->next;
	int tmp = left->data;
	while (jp != right)
	{
		if (jp->data <= tmp)
		{
			ip = ip->next;
			std::swap(ip->data, jp->data);
		}
		jp = jp->next;
	}
	std::swap(left->data, ip->data);
	return ip;
}

在这里插入图片描述
如果j指向的值大于标准值,就j向后走,当j指向的值小于等于划分标准值,这时i向后走一个,交换i和j指向的值,然后j继续向后走…直到j指向了right结点。此时完成一次划分。
剩下代码和普通快排 一样,递归执行。

void QuickPass(ListNode* left, ListNode* right)
{
	if (left != right)
	{
		ListNode* p = LinkParition(left, right);
		QuickPass(left, p);
		QuickPass(p->next, right);
	}
}

void ListQuickSort(ListNode* head)
{
	QuickPass(head, nullptr);
}

给一个完整单链表示例:

typedef int ElemType;
typedef struct ListNode
{
	ElemType data;
	ListNode* next;
}ListNode, * LinkList;

ListNode* Init_List(const vector<int>& ar)
{
	ListNode* head = (ListNode*)malloc(sizeof(ListNode));
	head->data = ar[0];
	head->next = nullptr;
	ListNode* p = head;
	for (int i = 1; i < ar.size(); ++i)
	{
		ListNode* s = (ListNode*)malloc(sizeof(ListNode));
		if (s == nullptr) return nullptr;

		s->data = ar[i];
		s->next = nullptr;
		p->next = s;
		p = s;
	}
	return head;
}

void Print_List(ListNode* p)
{
	while (p != nullptr)
	{
		cout << p->data << " ";
		p = p->next;
	}
	cout << endl;
}

ListNode* LinkParition(ListNode* left, ListNode* right)
{
	ListNode* ip = left;
	ListNode* jp = left->next;
	int tmp = left->data;
	while (jp != right)
	{
		if (jp->data <= tmp)
		{
			ip = ip->next;
			std::swap(ip->data, jp->data);
		}
		jp = jp->next;
	}
	std::swap(left->data, ip->data);
	return ip;
}

void QuickPass(ListNode* left, ListNode* right)
{
	if (left != right)
	{
		ListNode* p = LinkParition(left, right);
		QuickPass(left, p);
		QuickPass(p->next, right);
	}
}

void ListQuickSort(ListNode* head)
{
	QuickPass(head, nullptr);
}

int main()
{
	vector<int>ar = { 56,34,23,78,90,12,45,67,89,100 };
	LinkList head= Init_List(ar);
	Print_List(head);
	ListQuickSort(head);
	Print_List(head);

	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

孟小胖_H

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值