1.说一下什么是二分法?使用二分法时需要注意什么?如何用代码实现?
二分法查找(Binary Search)也称折半查找,是指当每次查询时,将数据分为前后两部分,再用中值和待搜索的值进行比较,如果搜索的值大于中值,则使用同样的方式(二分法)向后搜索,反之则向前搜索,直到搜索结束为止。
二分法使用的时候需要注意:二分法只适用于有序的数据,也就是说,数据必须是从小到大,或是从大到小排序的。时间复杂度是O(logn)
执行源码:
@Service
public class TestService {
/**
* 二分查找
* @param nums
* @param start
* @param end
* @param findValue
* @return
*/
public static Integer twoHalf (Integer[] nums,Integer start,Integer end,Integer findValue){
Integer middle=(start+end)/2;
Integer tempValue=nums[middle];
if(start.compareTo(end)<=0){
if(tempValue.equals(findValue)){
return middle;
}else if(findValue.compareTo(tempValue)>0){
return twoHalf(nums,middle+1,end,findValue);
}else{
return twoHalf(nums,start,middle-1,findValue);
}
}
return -1;
}
public static void main(String[] args){
Integer[] nums={1,3,5,9,17,19,34,56};
Integer findvalue=19;
Integer start=0;
Integer end=nums.length-1;
Integer a=null;
a=TestService.twoHalf(nums,start,end,findvalue);
System.out.println("查找到元素的位置"+a);
}
}
执行结果:
2.快速排序
快速排序原理:
快速排序使用分治的思想,从待排序序列中选取一个记录的关键字为key,通过一趟排序将待排序列分割成两部分,其中一部分记录的关键字不大于key,另一部分记录的关键字不小于key,之后分别对这两部分记录继续进行排序,以达到整个序列有序的目的。
快速排序算法的基本步骤为(从小到大):
选择关键字:从待排序序列中,按照某种方式选出一个元素作为 key 作为关键字(也叫基准)。
置 key 分割序列:通过某种方式将关键字置于一个特殊的位置,把序列分成两个子序列。此时,在关键字 key 左侧的元素小于或等于 key,右侧的元素大于 key(这个过程称为一趟快速排序)。
对分割后的子序列按上述原则进行分割,直到所有子序列为空或者只有一个元素。此时,整个快速排序完成。
时间复杂度:
当待排序序列完全顺序或者完全逆序的时候,此中情况下排序的时间复杂度仍为O(N^2),但是,随机化快速排序对于绝大多数排序序列达到 O(nlogn)的期望时间复杂度。
快速排序代码:
/**
* 快速排序
* created by alpha on 2021-08-19
*/
public class QuickSortService {
public static void quickSort(Integer[] nums,Integer start,Integer end){
//起始被比较值
Integer index=nums[start];
//异常校验
if(nums==null||nums.length==0){
return;
}
if(start>=end){
return;
}
//记录本轮比较的开始位置与结束位置
Integer left=start;
Integer right=end;
//直到开始位置与结束位置重合,则本轮比较结束
while(!left.equals(right)) {
//比index大的元素,右指针直接移动
while (left < right && nums[right] > index) {
right--;
}
//比index小的元素,左指针直接移动
while (left < right && nums[left] < index) {
left++;
}
//如果出现index右边元素比index小,或者index左边的元素比index大,则当前左位置元素与右位置元素交换
Integer temp = nums[left];
nums[left] = nums[right];
nums[right] = temp;
//元素交换后,继续移动左位置与右位置比较元素,直到左位置与右位置重合
}
//记录当前重合元素的位置
Integer xy=left;
//以重合位置为切分点,左边数组与右边数组继续重新排序
quickSort(nums,start,xy-1);
quickSort(nums,xy+1,end);
}
public static void main(String[] args){
Integer[] nums={6,1,5,4,2,3,8,10};
quickSort(nums,0,nums.length-1);
for(int i=0;i<nums.length;i++){
System.out.println( nums[i]+",");
}
}
}
执行结果: