单链表快速排序

这篇博客探讨了如何将快速排序算法应用于单链表。在数组中,快速排序通过选定一个key并使用两个指针左右移动来分区。而在单链表中,由于不能反向遍历,指针p和q从头结点开始,寻找合适的位置来分区。通过这样的方式,实现了单链表上的快速排序功能,并以序列 [7, 9, 6, 1, 2, 3, 8, 5] 为例进行了说明。" 81747540,7481868,Angular6.x动态表单FormArrayName深入解析,"['Angular', '前端开发', '表单控件', '动态表单']
摘要由CSDN通过智能技术生成

假设对一组序列进行升序快速排序.

对于数组进行快速排序的基本思想:

对于每一轮迭代, 选定一个目标元素key(通常选第一个)用来做partition, 定义两个指针left、right分别指向数组的头和尾, left指针从左往右移动, 遇到比key大的值暂停, right指针从右往左移动, 遇到比key小的值暂停, 两个指针都停下时交换两个指针指向的元素, 然后两个指针继续移动, 直到两个指针相遇, 然后交换key与相遇处的元素, 这样通过一次迭代就把key对应的元素交换到了排序后它应该处于的正确位置, 然后以key当前所处的位置为临界点把序列分割成两部分, 对这两部分分别重复上面的操作, 以此类推.

在单链表上实现快速排序算法:

与数组很大的一个区别就是单链表不能从后往前进行遍历, 因此在做partition的时候, 两个指针都只能从前往后进行遍历.

具体思路是: 两个指针p、q都从头结点开始往后遍历, 开始的时候p指针指向头结点(key), q指针指向p的下一个结点, q指针从前往后查找比key值小的元素, 当q指针遇到比key值小的元素的时候, p前进一位, 交换p、q指向的元素, 如果q指针遇到的元素比key大, 则p指针不动, q指针继续向前查找, 直到q指针查找到链表末端. 显然q指针比p指针移动速度快, 这就保证了p指针前面的元素都比key小, 此时p指针指向的位置就是key对应的元素在排序后的正确位置, 也就是partition的位置, 因此交换key对应的元素与p指针当前指向的元素, 并以此位置作为partition的临界点.

Example:

假设对序列 [7, 9, 6, 1, 2, 3, 8, 5] 进行快速排序, 下面对比数组和单链表下一次迭代的过程.

  • 数组:
初始状态: a=[7, 9, 6, 1, 2, 3, 8, 5], key = 7, left = 1, right = 7  (key对应的为实际值, left, right分别是两个指针所处的位置, 下面分别简写为l, r)
1. a[l] = a[1] = 9 > key, a[r] = a[7] = 5 < key --> swap(a[l], a[r]) --> l++, r-- --> 得到序列 [7, 5, 6, 1, 2, 3, 8, 9], 此时l = 2, r = 6.
2. a[l] = a[2] = 6 < key, a[r] = a[6] = 8 > key --> l++, r-- --> 序列不变, 此时 l = 3, r = 5.
3. a[l] = a[3] = 1 < key, a[r] = a[5] = 3 < key --> l++, r不变 --> 序列不变, 此时 l = 4, r = 5.
4. a[l] = a[4] = 2 < key, a[r] = a[5] = 3 < key --> l++, r不变 --> 序列不变, 此时 l = 5, r = 5.
5. 由于l == r --> swap(a[5], a[0]) (l = 5, key对应a[0]) --> 得到序列 [3, 5, 6, 1, 2, 7, 8, 9] --> 该轮迭代结束, 以 位置5 为临界点做partition进行下一次迭代.
  • 单链表:
初始状态: a=[7, 9, 6, 1, 2, 3, 8, 5], key = 7, p -> 0, q -> 1 (key对应实际值, p, q为两个指针, 对应的值为其所处位置, 如p -> 0表示p指向0位置, 头结点位置认为是0, 后面一次递增, 为了与上面数组的情况做区分, 用p->val、q->val分别表示p、q指向的元素的值)
1. q->val = 9 > key --> q = q->next, 序列不变, 当前p -> 0, q -> 2
2. q->val = 6 < key --> p = p->next --> swap(p->val, q->val) --> q = q->next --> 得到序列[7, 6, 9, 1, 2, 3, 8, 5], 此时p -> 1, q -> 3
3. q->val = 1 < key --> p = p->next --> swap(p->val, q->val) --> q = q->next --> 得到序列[7, 6, 1, 9, 2, 3, 8, 5], 此时p -> 2, q -> 4
4. q->val = 2 < key --> p = p->next --> swap(p->val, q->val) --> q = q->next --> 得到序列[7, 6, 1, 2, 9, 3, 8, 5], 此时p -> 3, q -> 5
5. q->val = 3 < key --> p = p->next --> swap(p->val, q->val) --> q = q->next --> 得到序列[7, 6, 1, 2, 3, 9, 8, 5], 此时p -> 4, q -> 6
6. q->val = 8 > key --> q = q->next, 序列不变, 此时p -> 4, q -> 7
7. q->val = 5 < key --> p = p->next --> swap(p->val, q->val) --> q = q->next --> 得到序列[7, 6, 1, 2, 3, 5, 8, 
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值