基础算法--快速排序

快速排序

算法原理

1. 取一个元素p(第一个元素,最后一个元素,中间元素,随机 都可以),使元素p归位。
2. 列表被p分成两部分,左边都比p小,右边都比p大。
3. 递归完成排序。

基础算法--快速排序_第1张图片

算法原理

注意【边界的确定】
当基准元素从最左侧left取值时,需要先从右边向左边扫描,否则不准确 反之,当基准元素从最右侧取值时,需要先从左边向右边扫描

这是一个无序数列:4、5、8、1、7、2、6、3,我们要将它按从小到大排序。按照快速排序的思想,我们先选择一个基准元素,进行排序
在这里插入图片描述
我们选取4为我们的基准元素,并设置基准元素的位置为index,设置两个指针leftright,分别指向最左和最右两个元素
基础算法--快速排序_第2张图片

接着,从right指针开始,把指针所指向的元素和基准元素做比较,如果大于等于基准元素,则right指针向左移动,如果小于基准元素,则把right所指向的元素填入left下标位置中

先从right开始,3和4比较,3比4小,将3填入index中,right指针不动,从右侧向左侧扫描结束。
基础算法--快速排序_第3张图片
然后从左侧向右侧扫描,原来3的位置成为了新的index,如果小于等于基准元素,则left指针向右移动,如果大于基准元素,则把left所指向的元素填入right下标位置中。

5和4比较,5比4大,将5填入index中,原来5的位置成为了新的index。
基础算法--快速排序_第4张图片
接下来,我们再切换到right指针进行比较,5和4比较,5比4大,right指针左移一位,6和4比较,6比4大,right指针左移一位

基础算法--快速排序_第5张图片
2和4比较,2比4小,将2填入index中,原来2的位置成为新的index。
基础算法--快速排序_第6张图片
随着left右移,right左移,最终left和right重合

基础算法--快速排序_第7张图片
此时,我们将基准元素填入index中,这时,基准元素左边的都比基准元素小,右边的都比基准元素大,这一轮交换结束
基础算法--快速排序_第8张图片

  1. 第一轮,基准元素4将序列分成了两部分,左边小于4,右边大于4,第二轮则是对拆分后的两部分进行比较
    此时,我们有两个序列需要比较,分别是3、2、1和7、8、6、5,重新选择左边序列的基准元素为3,右边序列的基准元素为7
    在这里插入图片描述
    第二轮排序结束后,结果如下所示
    在这里插入图片描述
    此时,3、4、7为前两轮的基准元素,是有序的,7的右边只有8一个元素也是有序的,因此,第三轮,我们只需要对1、2和5、6这两个序列进行排序
    在这里插入图片描述
    第三轮排序结果如下所示
    在这里插入图片描述
    至此所有的元素都是有序的

python代码实现

import sys
import time

# 修改递归最大深度
sys.setrecursionlimit(100000)

def partition(li, left, right):
    tmp = li[left]
    while left < right:
        while left < right and li[right] >= tmp:
            right -= 1
        li[left] = li[right]
        
        while left < right and li[left] <= tmp:
            left += 1
        li[right] = li[left]

    li[left] = tmp  
    return left

def quick_sort(li, left, right):
    if left < right:
        mid = partition(li, left, right)
        quick_sort(li, left, mid - 1)
        quick_sort(li, mid + 1, right)


li = [5, 7, 4, 6, 3, 1, 2, 9, 8]
print(li)
quick_sort(li, 0, len(li) - 1)
print(li)

C++代码实现 同上方python代码

#include 
using namespace std;

const int N = 1000010;
int a[N];
 
int partition(int a[], int left, int right)
{
    int tmp = a[left];
    while(left < right)
    {
        while(left < right && a[right] >= tmp) {
        	right --;
		}
        a[left] = a[right];
  
        while(left < right && a[left] <= tmp) {
        	left ++;
		}
        a[right] = a[left];
    }  
    a[left] = tmp;

    return left;
}

void quick_sort(int a[],int left,int right)
{
    if(left < right)
    {  
        int mid = partition(a, left, right);
        quick_sort(a, mid + 1, right);
        quick_sort(a, left, mid - 1);
    }
}
int main()
{
    int n;
    scanf("%d", &n);
    for(int i = 0; i < n; i++) scanf("%d", &a[i]);
    
	quick_sort(a, 0, n - 1);
    
	for(int i = 0; i < n; i++) printf("%d ", a[i]);
    
	return 0;
}

C++代码实现 acwing模板 (稳定)

#include 
using namespace std;

const int N = 1000010;
int a[N];
 
void quick_sort(int a[],int left,int right)
{
    if(left >= right) return;
    int tmp = a[(left + right) / 2], q = left - 1, e = right + 1;
    while(q < e)
    {
        do q++;while(a[q] < tmp);
        do e--;while(a[e] > tmp);
        if(q < e) swap(a[q], a[e]);
    }
    quick_sort(a, left, e);
    quick_sort(a, e + 1, right);
}

int main()
{
    int n;
    scanf("%d", &n);
    for(int i = 0; i < n; i++) scanf("%d", &a[i]);
    
	quick_sort(a, 0, n - 1);
    
	for(int i = 0; i < n; i++) printf("%d ", a[i]);
    
	return 0;
}

acwing模板 python实现

def quick_sort(li, left, right):
    if left >= right:
        return
    tmp = li[(left + right) // 2]
    q = left - 1
    e = right + 1
    while q < e:
        q += 1
        while li[q] < tmp:
            q += 1
        e -= 1
        while li[e] > tmp:
            e -= 1

        if q < e:
            li[q], li[e] = li[e], li[q]

    quick_sort(li, left, e)
    quick_sort(li, e + 1, right)


li = [i for i in range(100)]
random.shuffle(li)
quick_sort(li, 0, len(li) - 1)
print(li)

你可能感兴趣的:(【信奥赛之路,2】--,算法基础,算法,青少年编程,python,c++)