Nico lomuto法求分界点

本文详细解析了分界点算法的原理与实现过程,通过选取数组中的一个元素作为基准值,将数组分为两部分,左边的元素都小于基准值,右边的元素都大于基准值。文章还介绍了如何通过迭代处理每个元素,最终确定分界点的位置,以及选择基准值的重要性。

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

  分界点,即该点左边的值都小于它,右边的值都大于它。

  在处理过程中随便挑选一个点,令为a,这个数不一定是数组中的元素,并且让数组x[]始终满足如下关系:

           

  L,R是数组x两端下标,j是小于a元素中最右边的脚码,第j+1个就大于等于a了,i是下一个待处理元素的脚码,因此x[j+1]到x[i-1]之间的元素都大于等于a。现在处理x[i],x[i]与a的关系无非两种:

  1.x[i]>=a:因为x[i]>=a,所以大于等于a的部分可以向右延伸覆盖住x[i],如下图所示:

      

  2.x[i]<a:此时,x[i]这个值得位置就不对,因为它小于a,应该在x[j+1]左边才是,那么怎么办呢?我们可以将x[j+1]与x[i]互换,并将i,j都往右移动一步,那么上述的关系还是不变。

  按照此法,当i一直到达R,x[R]处理完之后,工作也就结束了。那么x[j]就是一个分界点。但还有一个问题,a要如何选择呢?如果把a选的都大于或者都小于数组中的元素,那么上述做法是没有意义的。因此一般做法把a选为数组中的元素,最好能把数组分成差不多长的两半,最理想的就是选a为中位数,但求中位数也是一个难题(后续将介绍如何用上述方法求一个数组的中位数)。

  基于上述思想,我们很容易编出程序(选a为数组的第一个元素):

 1 void split(int input[],int first,int last,int *split_point){
 2     int current_split,unknown;
 3     int x;
 4     x=input[first];
 5     current_split=first;
 6     for(unknown=first+1;unknown<=last;unknown++){
 7         if(input[unknown]<=x){
 8             current_split++;
 9             swap(&input[current_split],&input[unknown]);
10         }
11     }
12     swap(&input[first],&input[current_split]);
13     *split_point=current_split;
14 
15  }
16  void swap(int *p,int *q){
17     int tmp;
18     tmp=*p;
19     *p=*q;
20     *q=tmp;
21  }

 

转载于:https://www.cnblogs.com/renb/p/10103970.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值