-
写在最前
最近在刷Leetcode的时候碰到一些题的解法是基于归并排序的,今天终于耐心地去学习了一下归并排序,为了加深自己的理解便来写篇文章总结一下归并排序,于是想着顺便把以前学的快速排序也一并总结,加深印象。本次介绍快速排序,下篇文章介绍归并排序。 -
快速排序(Quicksort)
又称分区交换排序(partition-exchange sortt),简称“快排”。快排使用分治(divide and conquer)的思想,每次排序时选择一个数,把一个序列分为大于(等于)该数的序列和小于该数的两个子序列,然后再递归地对两个子序列进行排序。
快排的步骤如下:
- 挑选基准值:从需要排序的序列中选取一个元素,将其作为基准(pivot)。
- 基于基准值分割序列:将序列基于步骤1挑选的基准分成大于(等于)该基准的序列和小于该基准的序列,返回基准值下标。
- 递归排序子序列:基于步骤2中得到两个子序列递归排序,当序列的长度为1或者0时结束排序。
图片说明排序过程如下图:
假设需要排序的序列为第一行的绿色区域。
完整的代码如下:
C语言版:
#include <stdio.h>
void quickSort(int nums[], int low, int high);
int partition(int nums[], int low, int high);
int main(){
int nums[8] = {3,5,9,6,2,8,2,6}; //待排序序列
quickSort(nums, 0, 8-1);
for(int i=0; i<8; i++) //输出排序后序列
printf("%d ", nums[i]);
printf("\n");
return 0;
}
int partition(int nums[], int low, int high){
int i, j, num, temp;
i = low - 1; //i:当前小于基准值数据的下标
num = nums[high];
for(j=low; j<high; j++){ //j:遍历序列
if(nums[j] <= num){ //小于基准值,交换到基准值左侧
i++;
temp = nums[i];
nums[i] = nums[j];
nums[j] = temp;
}
}
temp = nums[i+1]; //移动基准值位置
nums[i+1] = nums[high];
nums[high] = temp;
return i+1;
}
void quickSort(int nums[], int low, int high){
int index; //基准值下标
if(low < high){ //递归
index = partition(nums, low, high);
quickSort(nums, low, index-1);
quickSort(nums, index+1, high);
}
}
Python3版:
class Solution:
def patition(self, nums, low, high):
i = low - 1 #当前小于基准值数据的下标
pivot = nums[high]
for j in range(low, high):
if nums[j] <= pivot: #小于基准值,交换到基准值左侧
i += 1
nums[i], nums[j] = nums[j], nums[i]
nums[i+1], nums[high] = nums[high], nums[i+1] #移动基准值位置
return i + 1
def quickSort(self, nums, low, high):
if low < high:
index = self.patition(nums, low, high) #基准值下标
# 递归
self.quickSort(nums, low, index-1)
self.quickSort(nums, index+1, high)
return nums
nums = [1,4,7,2,5,1,4,3,8,6] #待排序序列
res = Solution().quickSort(nums, 0, len(nums)-1)
print(res) #输出排序后结果
- 复杂度分析
最好时间复杂度: O ( n l o g n ) O(nlogn) O(nlogn)
最差时间复杂度: O ( n 2 ) O(n^2) O(n2)
平均时间复杂度: O ( n l o g n ) O(nlogn) O(nlogn)
空间复杂度: O ( 1 ) O(1) O(1),使用输入数据直接进行位置交换
如果有哪里理解错的地方欢迎大家留言交流,如需转载请标明出处。
如果你没看懂一定是我讲的不好,欢迎留言,我继续努力。
手工码字码图码代码,如果有帮助到你的话留个赞吧,谢谢。
以上。