1.3二分搜索
算法1.1 LINEARSEARCH
先对线性搜索搜索进行描述,为二分排序进行铺垫
下面展示的是书中的伪代码:
算法1.1:LINEARSEARCH
输入:n个元素的数组A[1···n]和元素x
输出:如果x=A[j],1<=j<=n,则输出j,否则输出0
1.j <- 1
2.while(j<n) and (x!=A[j]) //逐一进行比较,将与x相等的值的下标进行传递
3. j=j+1
4.end while
5.if x =A[j] then return j else return 0
关于线性搜索的实现不做展示,原理就是简单的逐一比较
算法1.2.1 BINARYSEARCH
直接贴出伪代码:
算法1.2 BINARYSEARCH
输入:n个元素的升序数组A[1···n]和元素x
输出:如果x=A[j],1<=j<=n,则输出j,否则输出0
1.low <- 1;high <- n;j <- 0
2.while(low <= high) and (j=0)
3. mid <- (low+high)/2 //计算中间值下标
4. if x=A[mid] then j <- mid //待寻数是否为中间值,若是则直接返回中间值下标
5. else if x <A[mid] then high <- mid-1 //如果x小于中间值,则在1与mid中寻找
6. else low <- mid+1 //如果x大于中间值,则在mid与high中寻找
7.end while
8.return j //返回寻找到的数的下标
下面展示的是Java的实现:
package com.sheye;
/**
* @author Sheye
* @date 2019-10-23 17:46
*/
public class BinarySearch {
static int binarySearch(int[] A,int low,int high,int x){
int j=0;
while(low <= high && j==0){
int mid = (low+high)/2; //计算中间值下标
if(x==A[mid]){ //待寻数是否为中间值
j=mid; //若是则直接返回中间值下标
}
else if (x<A[mid]){ //如果x小于中间值,则在1与mid中寻找
high=mid-1;
}else { //如果x大于中间值,则在mid与high中寻找
low=mid+1;
}
}
return j; //返回寻找到的数的下标
}
public static void main(String[] args) {
int[] A = {1,2,3,4,5,6,7,8,9,10};
int x = 7;
System.out.println(binarySearch(A,0,A.length-1,x));
}
}
贴上运行结果
6
算法1.2.2 BINARYSEARCH
因为二分搜索的前提是一个升序的数组,在此加上自底向上合并排序总结出一个完整版
贴出自底向上合并排序算法链接: https://blog.youkuaiyun.com/u014120081/article/details/101103027.
下面展示的是Java的实现:
package com.sheye;
/**
* @author Sheye
* @date 2019-10-23 17:46
*/
public class BinarySearch {
private static int[] A = {7,24,78,56,4,24,10,26,1,2,88,99};
private static int[] B = new int[A.length];
static void merge(int[] A,int p,int q,int r){
int k=p;
int s=p;
int t=q+1;
while ((s<=q)&&(t<=r)){
if (A[s]<=A[t]){
B[k]=A[s];
s=s+1;
}else {
B[k]=A[t];
t=t+1;
}
k=k+1;
}
if (s==q+1){
System.arraycopy(A,t,B,k,(r-t)+1); //B[r-k]=A[r-t];
}else {
System.arraycopy(A,s,B,k,(q-s)+1); //B[r-k]=A[q-s];
}
System.arraycopy(B,p,A,p,(r-p)+1); //A[r-p]=B[r-p];
}
static void buttomUpSort(){
int n =A.length; //a数组的长度
int t =1;
while(t<n){
int s=t; //合并序列的大小
t=2*s; //每次循环,序列大小*2
int i=0;
while((i+t)<=n){ //判断合并序列的大小小于等于a数组时进行循环排序
//减1是因为伪代码中是从1开始数起,而数组是从0开始
merge(A,i+1-1,i+s-1,i+t-1); //排序
i=i+t; //合并后合并序列的大小
}
if ((i+s)<n){ //两个要排序的序列边界
merge(A,i+1-1,i+s-1,n-1);
}
}
}
static void binarySearch(int[] A,int low,int high,int x){
int j=0;
while(low <= high && j==0){
int mid = (low+high)/2; //计算中间值下标
if(x==A[mid]){ //待寻数是否为中间值
j=mid; //若是则直接返回中间值下标
}
else if (x<A[mid]){ //如果x小于中间值,则在1与mid中寻找
high=mid-1;
}else { //如果x大于中间值,则在mid与high中寻找
low=mid+1;
}
}
System.out.println(j); //返回寻找到的数的下标
}
public static void main(String[] args) {
int x = 7;
buttomUpSort();
System.out.print("排序后结果为:");
for (int i=0;i<A.length;i++){
System.out.print(" "+B[i]);
}
System.out.println();
System.out.print("待寻数"+x+"在数组中的下标为:");
binarySearch(B,0,A.length-1,x);
}
}
贴上运行结果:
排序后结果为: 1 2 4 7 10 24 24 26 56 78 88 99
待寻数7在数组中下标为:3
因为二分搜索比较简单,没啥说的,溜了