排序之快速排序

本文详细介绍了快速排序算法的不同实现方式,包括使用中位数作为基准数的优化方法、啊哈算法中的快速排序实现以及另一种常见的快排实现。文章还讨论了快排的非稳定性及其解决方法。

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

//快排为非稳定排序,因为两个相等的元素,在选择某数为基准数的情况下,可能会互换位置,具体去想原理;
//当利用C语言快排函数时,可利用结构体的优先元素排序解决不稳定的问题
//快排基于分治思想
//快排例程很多,自我感觉最全面可靠的是黑皮书教材上的,老美就是厉害,这一点确实得佩服人家,国内的计算机教材真心不敢恭维
//几个快排例程:
//一:教材(赞一个)
int Median3(int array[],int left,int right){//left,middle,right三个位置的数据按大小顺序排好,并且把基准数array[middle](三者中位数)与array[right-1]交换
	int middle=(left+right)/2;
	if(array[left]>array[middle])
		swap(array[left],array[middle]);
	if(array[middle]>array[right])
		swap(array[middle],array[right]);
	if(array[left]>array[right])
		swap(array[left],array[right]);
	swap(array[middle],array[right-1]);
	return array[right-1];
}
void Qsort(int array[],int left,int right){
	int pivot,i,j;
	if(left>=right)//由代码判断,left>right应该出现不了吧(待定)
		return;
	pivot=Median3(array,left,right);//取基准数
	i=left;
	j=right-1;
	if(j-i<=1)//j-i=0或1,说明当前排序序列一共俩/仨元素,那么经过Median3(),已排好序
		return;
	while(1){
		while(array[++i]<pivot);
		while(array[--j]>pivot);
		if(i>j)
			swap(array[i],array[j]);
		else
			break;
	}
	swap(array[i],array[right-1]);
	Qsort(array,left,i-1);
	Qsort(array,i+1,right);
}
void QuickSort(int array[],int n){//与主程序接口
	Qsort(array,0,n-1);
}


//二:啊哈算法
void QuickSort(int array[],int left,int right)
{
    int base=array[left];//取最左边的数为基准数,最后小于等于基准数的在基准数左,大于等于基准数的在右
    int i=left;//哨兵,从左向右走;
    int j=right;//哨兵,从右往左走;
    if(left>=right)//递归出口,当left==right,为一个元素;left>right,说明上次i=j时,i,j均在当次快排的端点
        return;
    base=array[left];
    while(i!=j){//哨兵相遇时,跳出while
        while(array[j]>=base&&i<j)//j哨兵先走;理由在下方
            j--;
        while(array[i]<=base&&i<j)//i哨兵再走
            i++;
        if(i<j){//当哨兵不相遇,交换元素
           int temp;
           temp=array[i];
           array[i]=array[j];
           array[j]=temp;
        }
    }
    //当哨兵相遇,将基准数归位
    array[left]=array[i];
    array[i]=base;
    QuickSort(array,left,i-1);//递归处理
    QuickSort(array,i+1,right);//递归处理

}
//j先走理由:
//如:数组为 5 3 4 6 7 8 10 11 12
//若先走i,第一次会交换5(temp)和6,明显不符合


//三:其他书籍
void Sort(int array[],int left,int right)  
{  
    int temp=array[left];  
    int i,j;  
    i=left;  
    j=right;  
    if(i>=j)  
        return;  
    while(i<j){//此处不可以用while(i!=j),,因为i可能直接到最后right的后面
        while(array[i]<=temp&&i<=j)//先动i
            i++;  
        while(array[j]>=temp&&i<=j)  
            j--;  
        if(i<j){  
            int t=array[i];  
            array[i]=array[j];  
            array[j]=t;  
        }  
  
    }  
    array[left]=array[i-1];  
    array[i-1]=temp;  
    Sort(array,left,i-2);  
    Sort(array,i,right);  
} 
//为何与array[i-1]交换? 与先动i有关系  
//最后有两种情况:  
//一,i直接到right后,此时array[right]<=temp 
//二,经过几次交换,或者i直接到j,i和j相遇,j再退一步到i前面,此时array[i-1]小于等于temp,array[i]>temp 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值