原理
选择一个基准线,利用二分法,使得基准线位于正确的位置(大于基准的在它右边,小于的在左边,直到分到最后一个元素)
复杂度
时间复杂度:O(nlog2n) 空间复杂度:O(nlog2n)第一个基准需要进行n-1次比较,之后二分进行log2n次
数组代码实现
首位设定为key,首位和末尾放指针i j ,从右开始找(j--)比key小的放到i 位置,再从左开始找比key大的,放到j位置,直到i j 相遇,将key放到相遇点。再利用二分法进行左右的快速排序。
图片来源:www.cnblogs.com/skywang1234…
就是一个把大的放右边 小的放左边的过程
int getStandard(int array[], int i, int j) {
// 基准数据
int key = array[i];
while (i < j) {
// 因为默认基准是从左边开始,所以从右边开始比较,
//因为如果从左边开始,第一个数就没法移动了
// 当队尾的元素大于等于基准数据 时,就一直向前挪动 j 指针
while (i < j && array[j] >= key) {
j--;
}
// 当找到比 array[i] 小的时,就把后面的值 array[j] 赋给它
if (i < j) {
array[i] = array[j];
}
// 当队首元素小于等于基准数据 时,就一直向后挪动 i 指针
while (i < j && array[i] <= key) {
i++;
}
// 当找到比 array[j] 大的时,就把前面的值 array[i] 赋给它
if (i < j) {
array[j] = array[i];
}
}
// 跳出循环时 i 和 j 相等,此时的 i 或 j 就是 key 的正确索引位置
// 把基准数据赋给正确位置
array[i] = key;
return i;
}
void QuickSort(int array[], int low, int high) {
// 开始默认基准为 low
if (low < high) {
// 分段位置下标
int standard = getStandard(array, low, high);
// 递归调用排序
// 左边排序
QuickSort(array, low, standard - 1);
// 右边排序
QuickSort(array, standard + 1, high);
}
}
代码来源:blog.csdn.net/weixin_4210…
链表代码
148.排序链表 给你链表的头结点 head ,请将其按 升序 排列并返回 排序后的链表 。
class Solution {
public ListNode sortList(ListNode head) {
if(head==null||head.next==null) return head;
// 没有条件,创造条件。自己添加头节点,最后返回时去掉即可。
ListNode newHead=new ListNode(-1);
newHead.next=head;
return quickSort(newHead,null);
}
// 带头结点的链表快速排序
private ListNode quickSort(ListNode head,ListNode end){
if (head==end||head.next==end||head.next.next==end) return head;
// 将小于划分点的值存储在临时链表中
ListNode tmpHead=new ListNode(-1);
// partition为划分点,p为链表指针,tp为临时链表指针
ListNode partition=head.next,p=partition,tp=tmpHead;
// 将小于划分点的结点放到临时链表中
while (p.next!=end){
if (p.next.val<partition.val){
// 将小于它的节点储存到 临时链表,并后移一位指针
tp.next=p.next;
tp=tp.next;
// 将小于partition的节点删除掉
p.next=p.next.next;
}else {
// 大的话不删除,后移指针
p=p.next;
}
}
// 合并临时链表和原链表,将原链表接到临时链表后面即可(这是的临时链表就是从小到大了)
tp.next=head.next;
// 将临时链表插回原链表,注意是插回!(不做这一步在对右半部分处理时就断链了)
head.next=tmpHead.next;
quickSort(head,partition);
quickSort(partition,end);
// 题目要求不带头节点,返回结果时去除
return head.next;
}
}