快排的优化

文章详细介绍了快速排序算法中使用霍尔划分思想的两种改进方法:一种是让右指针先走,遇到小于key的元素交换并移动;另一种是前后指针法,后指针先走,根据元素大小调整并交换。这两种方法优化了分区过程,提高排序效率。
摘要由CSDN通过智能技术生成

快排

霍尔划分

思想:将最左边设为key值,int key = left; 设有两个指针,left 和 right ,

right从右往左找如果小于arr[key]的停下来,left从左往右找如果大于arr[key]停下来。注意必须是右边先走。

代码

int partion(int * arr , int left , int right)
{
    int key = left;
    while(left<right)
    {
        while(left<rightt && arr[right]>=arr[key])
        {
            right--;//找到小于arr[key]的时候停下来
        }
        while(left<right && arr[left]<=arr[key])
        {
            left++//找到大于arr
        }
        //找到了,两个才可以交换
        Swap(&arr[left],&arr[right]);
    }
    Swap(&arr[key],&arr[left]);//此时的left所指的下标必定小于key所指的
    return left;
}


// 接着划分区间

void quickSort(int* arr , int left , int right)
{
    if(left<=right) return;
    int key = partion(arr,left , right);
   	quickSort(arr , left , key-1);
    quickSort(arr , key+1 , right);
    
}

问题:为什么让 right 先走呢?

假设right先走 :

情况1, right遇到left停下来,停下的原因遇到比arr[key]小的

情况2,letf遇到right 停下来,由于是right先走,而right停下来的原因是遇到小于key的,此时left 来遇到 right , 即left==right

挖坑法

还是右边先走,遇到小于arr[key]的直接在key对应的位置赋值,然后左边再走,遇到比key大的,直接赋值给arr[key],

int partion(int * arr , int left , int right)
{
        int hole  = left;
    	int key = arr[left]
    while(left<right)
    {
        while(left<rightt && arr[right]>=key)
        {
            right--;//找到小于arr[key]的时候停下来
        }
       
        arr[hole] = arr[right];
      hole = right;
        while(left<right && arr[left]<=key)
        {
            left++//找到大于arr
        }
        
        
        arr[hole] = arr[left];
        hole = left;
    }
   arr[left] = key;
    return left;
}
// 接着划分区间

void quickSort(int* arr , int left , int right)
{
    if(left<=right) return;
    int key = partion(arr,left , right);
   	quickSort(arr , left , key-1);
    quickSort(arr , key+1 , right);
    
}

前后指针法

思想:定一个前后指针,取左边为key,后指针先走,遇到大于的就往后走,遇到小的就停下来,此时前指针开始走,遇到小的继续走,遇到大的停下来.两个的值开始交换,然后 后指针继续往前走.接着重复这样的过程,最后出来的时候,要swap(prev,key)

int partion(int * arr , int left , int right)
{
      int key  = left;
    int prev = left;//前指针
    int cur = left+1;//后指针
    while(cur<right)
    {
        if(arr[cur]>=arr[left])
        {
            cur++;
        }else{
            //先加加prev;第一个是key值,必须保持不变,key要和最后的prev交换
            Swap(&arr[++prev],&arr[cur]);
            cur++;
        }
      
	}
     Swap(&arr[prev],&arr[key]);
    return prev;
}
// 接着划分区间

void quickSort(int* arr , int left , int right)
{
    if(left<=right) return;
    int key = partion(arr,left , right);
   	quickSort(arr , left , key-1);
    quickSort(arr , key+1 , right);
    
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值