本文主要介绍一个Java使用二分法进行搜索和排序的例子。二进制插入排序和二分搜索法是基本算法,有需要的朋友可以参考一下。
实现二分法搜索
二分搜索法需要数组中的有序序列。
二分搜索法优于线性搜索:数组中的元素越多,效率越高。
二分搜索法的效率表示O(log2N) N在2的M次幂的范围内,最大搜索次数为M,log2N表示2的M次幂等于N,所以省略常数,缩写为O(logN)。
如果有一个200个元素的有序数组,那么二进制搜索的最大数量是:
2 7=128, 2 8=256.可以看出7次方小于200,加上8次方,那么最大搜索次数等于8。
//循环,二分搜索法
static int binary search(int[]array,int data) {
int start=0;
int end=array . length-1;
int mid=-1;
while (start=end) {
System.out.println('查找次数');
mid=(开始结束)1;
if(数组[中间]数据){
start=mid 1;
} else if (array[mid] data) {
end=mid-1;
}否则{
返回mid
}
system . out . println(' start=' start ',end=' end ',mid=' mid);
}
return-1;
}
//递归二分搜索法初始start=0,end=array.length-1
static int binary search 4 recursion(int[]array,int data,int start,int end) {
int mid=-1;
System.out.println('查找次数');
如果(开始结束){
返回mid
}
mid=(开始结束)1;
if(数组[中间]数据){
返回binarysearch 4递归(array,data,mid 1,end);
} else if (array[mid] data) {
返回binarySearch4Recursion(array,data,start,mid-1);
}否则{
返回mid
}
}
二分法插入排序
有一个序列a[0],a[1].a[n];a[i-1]的正面已经订购。当插入a[i]时,通过二分法搜索插入a[i]的位置
效率:O (n 2),对于初始基本有序序列,效率不如直接插入排序;对于随机无序的序列,效率要高于直接插入排序。
/*
*二进制(半)插入排序
*有一个序列a[0],a[1].a[n];a[i-1]的正面已经订购。当插入a[i]时,通过二分法搜索插入a[i]的位置
*/
公共类BinaryInsertSort {
公共静态void main(String[] args) {
int len=10
int[]ary=new int[len];
Random Random=new Random();
for(int j=0;j lenj ) {
ary[j]=random . nextint(1000);
}
binaryInsert(ary);
/*
*复杂度分析:在最好的情况下,也就是说,如果它们都是有序的,就不需要向右移动。此时的时间复杂度为:O(n lg n)。最坏的情况下,全部逆序,复杂度为o (n 2)。
*最坏情况的复杂度不能提升到O(n|logn)。
*/
//打印数组
print array(ary);
}
/**
*插入排序
* @param ary
*/
私有静态void binaryInsert(int[] ary) {
int setvalue count=0;
//从数组的第二个元素开始排序,因为第一个元素本身必须已经排序。
for(int j=1;j数组长度;J) {//复杂度n
//保存当前值
int key=ary[j];
//使用二分搜索法定位插入位置
//int index=binarySearchAsc(ary,ary[j],0,j-1);//复杂度:O(logn)
//int index=binarySearchDesc(ary,ary[j],0,j-1);//复杂度:O(logn)
int index=binarySearchDesc2(ary,ary[j],0,j-1);//复杂度:O(logn)
print array(ary);
System.out.println(其中要插入的第‘j’个索引上的元素为:‘index’);
//将目标插入该位置,同时将目标位置右侧的元素向右移动。
for(int I=j;I指数;I-){//复杂度,最坏情况:(n-1) (n-2).n/2=O(n ^ 2)
ary[I]=ary[I-1];//i-1==index
setValueCount
}
ary[index]=key;
setValueCount
}
system . out . println(' \ nSetvalueCount====' SetvalueCount);
}
/**
*二分搜索法升序递归
*
* @param ary
*给定要检查的有序数组
* @param target
*找到目标。
* @param来自
*当前搜索范围的起点
* @param to
*当前搜索的返回目的地
* @return返回目标在数组中按顺序应该出现的位置。
*/
private static int binarySearchAsc(int[]ary,int target,int from,int to) {
int range=to-from;
//如果范围大于0,即有两个以上的元素,则继续拆分。
if(范围0) {
//选择中间位
int mid=(to from)/2;
//如果不满足临界位,则继续二分搜索法。
if (ary[mid] target) {
/*
* mid目标,升序规则,目标较小,交换位置要靠前,即目标位于mid位置,
*根据搜索思路,从from到mid-1被认为是有序的,所以to=mid-1。
*/
返回binarySearchAsc(ary,target,from,mid-1);
}否则{
/*
* mid目标,升序规则,目标较大,位置不交换,搜索比较的起始位置应为mid 1。
*/
返回binarySearchAsc(ary,target,mid 1,to);
}
}否则{
If (ary[from] target) {//例如,5,4,要插入的是4
从.返回;
}否则{
从1返回;
}
}
}
/**
*二分搜索法递减,递归
*/
private static int binarySearchDesc(int[]ary,int target,int from,int to) {
int range=to-from;
if(范围0) {
int mid=(from to)1;
if (ary[mid] target) {
返回binarySearchDesc(ary,target,mid 1,to);
}否则{
返回binarySearchDesc(ary,target,from,mid-1);
}
}否则{
If (ary[from] target) {//例如,5,4,要插入的是4
从1返回;
}否则{
从.返回;
}
}
}
/**
*二分搜索法递减,非递归
*/
private static int binarysearchdesc 2(int[]ary,int target,int from,int to) {
//while(从到){
for(;从到;) {
int mid=(from to)1;
if (ary[mid] target) {
from=mid 1;
}否则{
to=中1;
}
}
//from==to;
If (ary[from] target) {//例如,5,4,要插入的是4
从1返回;
}否则{
从.返回;
}
}
私有静态void printArray(int[] ary) {
for (int i : ary) {
system . out . print(I ' ');
}
}
}
打印
98 562 442 531 210 216 931 706 333 132第一个索引上的元素要插入的位置是:1
98 562 442 531 210 216 931 706 333 132第二个索引上的元素要插入的位置是:2
98 562 442 531 210 216 931 706 333 132第三个索引的元素插入位置是:2
98 562 531 442 210 216 931 706 333 132在第四个索引上插入元素的位置是:4
98 562 531 442 210 216 931 706 333 132在第五个索引上插入元素的位置是:4
98 562 531 442 216 210 931 706 333 132在第6个索引处插入元素的位置是:0
91 918 562 531 442 216 210 706 333 132第7个索引上的元素要插入的位置是:2
91 918 706 562 531 442 216 210 333 132第8个索引上的元素要插入的位置是:6
91 918 706 562 531 442 333 216 210 132第9个索引上的元素要插入的位置是:9
设定值计数====24
931 918 706 562 531 442 333 216 210 132
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。