交换排序-快速排序

本文详细解析了快速排序算法的单路和双路版本,包括快速排序的基本思想、与冒泡排序的区别,以及不同情况下的时间复杂度分析。提供了C/C++代码实例,并讨论了如何通过划分操作优化算法效率,特别关注了最坏情况下的避免策略。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

快排分为单路快排和多路快排
定义:在待排序列中L[1…n]中,任取一个元素pivot作为基准(一般取第一个元素),通过一趟排序将待排序表 划分 为独立的两部分,使得在L[K]左右两边的元素,L[1…K-1]中所有的元素都小于pivot,L[k+1…n]中的所有元素大于等于pivot,则pivot放在了其最终位置L[k]上,此过程为一趟快速排序。

(即array[low]<pivot<array[high])

快排是对冒泡的改进,基本思想分治,代码用到递归
关键在于划分操作。和冒泡排序一样,每次确定一个元素的最终位置。

和冒泡排序的不同是,快排是(不稳定算法)

空间复杂度与递归调用的栈的深度有关
平均为O(logn)
最坏为O(n)
平均、最优:时间复杂度为O(nlogn)
最坏才和冒泡一样为O(n2)
时间复杂度
快排的运行时间与划分是否对称有关,
若初始序列基本有序或逆序,那么为O(n2)
若初始序列分布都差不多,那么为O(nlogn)

一般快排的实现有两种,单路快排和双路快排,下面是C语言实现的单路快排

C语言实现版本


//其中L[0]不放元素
#include<stdio.h>
void QuickSort(int *a,int low,int high);
int Partition(int *a,int low,int high); 
int main(){
	int a[8]={8,7,6,5,4,3,2,1};
	int i;
	QuickSort(a,0,7);
	for(i=0;i<8;++i){
		printf("%d ",a[i]);
	}
	return 0;
} 
void QuickSort(int *a,int low,int high){
	int pivotpos;
	if(low<high){
		pivotpos=Partition(a,low,high);
		QuickSort(a,low,pivotpos-1);
		QuickSort(a,pivotpos+1,high); 
	}
} 
int Partition(int *a,int low,int high){
	int pivot=a[low];
	while(low<high){
		while(low<high&&pivot<=a[high])
			--high;
		a[low]=a[high];	
		while(low<high&&pivot>=a[low])
			++low;
		a[high]=a[low];
	}
	a[low]=pivot;
	return low;
}

image.png

java单路快排

public class test {
    public static void main(String[] args) {
        int[] a = new int[]{1,3,5,7,2,4,6,8};
//        int[] a = new int[]{9,7,6,5,4,3,2,1};
        int n = a.length-1;
        quickSort(a,0,n);
        for (int i=0;i<n;i++){
            System.out.println(a[i]);
        }
    }
    public static void quickSort(int array[],int left,int right){
        if(left<right){
            int mid = quickSort2(array,left,right);
                quickSort(array,left,mid-1);
                quickSort(array,mid+1,right);
        }
    }
    public static int quickSort2(int[] array,int left,int right){
        //目的就是让左边的元素都是小于基准值,右边的元素都大于基准值
        int pivot = array[left];
        //先来右边,因为基准值在左边
        while(left<right){
            while(array[right]>=pivot&&left<right){
                right--;    //如果右边的元素大,那么就没问题,很守规矩,可以过
                //就是不用换,等于需要换吗,等于也不需要换
            }
            array[left]=array[right];
            while(array[left]<=pivot&&left<right){
                left++;
            }
            array[right] = array[left];
        }
        array[left] = pivot;
        return left;
    }
}

在这里插入图片描述

对算法最好的理解方式就是手动的模拟算法
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值