八大排序算法之-------快速排序及其优化 及其应用寻找第K小元素

快速排序是一种高效排序算法,通过一趟排序将数据分成两部分,但完全有序时效率降低。文中介绍了如何通过三取样中值法和随机选择主元进行优化,并探讨了快速排序在寻找第K小元素问题中的应用。

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

什么是快速排序?
顾名思义,快速派速是一种速度比较快,即时间复杂度较低的一种排序方法,其适用于数据混乱无章的情况,在数据完全有序的情况下,快速排序比较糟糕。
算法思想:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小;然后再次按照本方法对两部分再次排序,通过递归;最后数据全部有序。
C代码:

int partition(int a[] ,int low,int high)      //一次快速排序
 {
        int key=a[low];
        while(low<high)
		{

            while(low<high && a[high]>key) high--;
			if(low<high)  a[low]=a[high];
            while(low<high && a[low]<=key) low++;
            if(low<high)  a[high]=a[low];
        }
        a[low]=key;
        return low;
    }

void swap(int &a,int &b)            //交换函数
{
        int tmp=a;
        a=b;
        b=tmp;
}



 void QuickSort(int a[] ,int low,int high)       //简单快速排序
 {
        if(low>=high)
		{
            return;
        }
        int index=partition(a,low,high);
        QuickSort(a,low,index-1);
        QuickSort(a,index+1,high);
    }

上面的快速排序算法选取第一个元素为主元(即key),以此为依据将数据划分为两部分,但如果数据是完全有序的,那么此时时间复杂度为O(n^2),所以要采取优化。

C代码(优化一):采取三取样中值法,即在要排序的数组中,选取第一个数据 最后一个数据 以及中间的数据 取这三个数值的中位数作为主元(key),以此为依据来划分数据。此为三取样优化法。

void QuickSort(int a[] ,int low,int high)                   //三取样快速排序
{
        if(low>=high)
        {
            return;
        }
        int mid=(low+high)/2;
        if(a[mid]>a[high]) swap(a[mid],a[high]);     /*将最大值
        if(a[low]>a[high]) swap(a[low],a[high]);       放在high位置  * /          
        if(a[mid]>a[low]) swap(a[low],a[mid]);    //将中值放在 low位置
        int index=partition(a,low,high);
        QuickSort(a,low,index-1);
        QuickSort(a,index+1,high);
}

C代码(优化二): 采取随机数作为主元,即从数组中随机选取一个元素作为排序的主元。

void QuickSort(int a[] ,int low,int high)
{
        if(low>=high)
        {
            return;
        }
        int   rand= low + (int) rand()%(high -low+1 )
        swap(a[low],a[rand]);  
        int index=partition(a,low,high);
        QuickSort(a,low,index-1);
        QuickSort(a,index+1,high);
    }

快排应用:寻找第K小元素:

int     SelectKMin(int *p,int left,int right,int k)
{
	if(left == right && k == 1) 
	{
	      return p[left];
	}
	int index = partition(p,left,right);
	int pos = index - left + 1;     
	if(k <= pos) 
	{
	return SelectKMin(p,left,index,k);
	}
	else 
	{
	return SelectKMin(p,index+1,right,k - pos);
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值