java c++ python php 实现 二分查找。如果没查找到,显示离待查找值最近的值

本文介绍了二分查找算法的多种实现方式,包括Java、C++、Python和PHP四种语言的具体实现,展示了递归和循环两种不同的方法,并提供了查找未命中时的处理方案。

   java 实现:

    // java 实现 二分查找,如果没查找到,显示离代查找值最近的值
    // main
    public static void main(String[] a) {
        int[] array = {1, 3, 5, 7, 9, 11};
        int findValue = 6;
        int re = search(array, findValue);
        System.out.println(re);  // 打印: 没查找到 6。离代查找值最近的值是 :  5  和  7

        int re2 = searchRecursive( array, findValue, 0, array.length - 1 );
        System.out.println(re2);
    }

    // java 二分查找 --- while 实现
    public static int search( int[] array, int findValue ){
        // 查找次数
        int count = 0;

        // 代查找值 比 中值 大还是小
        int lgOrlt = -1;

        // 如果数组为空,直接返回 -1,即查找失败
        if (array == null) {
            return -1;
        }

        // 起始位置
        int start = 0;

        // 结束位置
        int end = array.length - 1;

        // 中间位置
        int middleIndex = -1;

        // 中值
        int middleValue = 0;

        while ( start <= end ) {
            count ++;

            middleIndex = ( start + end ) / 2;

            middleValue = array[ middleIndex ];

            if ( findValue == middleValue ) {
                // 找到了
                lgOrlt = 0;

                // 等于中值,直接返回
                return middleIndex;
            } else if ( findValue < middleValue ) {
                // 小于中值时,在中值前面找
                lgOrlt = 1;

                end = middleIndex - 1;
            } else {
                // 大于中值时,在中值后面找
                lgOrlt = 2;

                start = middleIndex + 1;
            }
        }

        System.out.print( "没查找到 " + findValue + "。离代查找值最近的值是 :  " );

        if ( lgOrlt == 1 ){
            // 小于中值时,在中值前面找
            if ( middleIndex > 0 ) {
                System.out.print( array[ middleIndex - 1 ] );
                System.out.print( "  和  " );
                System.out.print( middleValue );
                System.out.println();
            } else {
                System.out.println( array[ 0 ] );
            }
        } else if ( lgOrlt == 2 ) {
            // 大于中值时,在中值后面找
            if ( middleIndex < array.length - 1 ){  // 注意这里要写 middleIndex < array.length - 1,不要写 middleIndex < end,因为 end 是动态变化的
                System.out.print( middleValue );
                System.out.print( "  和  " );
                System.out.print( array[ middleIndex + 1 ] );
                System.out.println();
            } else {
                System.out.println( array[ array.length - 1 ] );
            }
        }

        // 返回 -1,即 没查找到
        return -1;
    }

    // java 二分查找 递归实现
    // 查找次数
    private static int count = 0;

    // 代查找值 比 中值 大还是小
    private static int lgOrlt = -1;

    // 中间位置
    private static int middleIndex = -1;

    // 中值
    private static int middleValue = 0;

    // 二分查找 --- 递归 实现
    public static int searchRecursive( int[] array, int findValue,
                                           int start, int end ){
        // 如果数组为空,直接返回 -1,即没查找到
        if (array == null) {
            return -1;
        }

        count++;

        if ( start <= end ){
            middleIndex = ( start + end ) / 2;

            middleValue = array[ middleIndex ];

            if ( findValue == middleValue ){
                lgOrlt = 0;

                // 等于中值,直接返回
                return middleIndex;
            } else if ( findValue < middleValue ){
                // 小于中值时,在中值前面找
                lgOrlt = 1;

                return searchRecursive( array, findValue, start, middleIndex - 1 );
            } else {
                // 大于中值时,在中值后面找
                lgOrlt = 2;

                return searchRecursive( array, findValue, middleIndex + 1, end );
            }
        } else {
            System.out.print( "没查找到 " + findValue + "。离代查找值最近的值是 :  " );

            if ( lgOrlt == 1 ){
                // 小于中值时,在中值前面找
                if ( middleIndex > 0 ) {
                    System.out.print( array[ middleIndex - 1 ] );
                    System.out.print( "  和  " );
                    System.out.print( middleValue );
                    System.out.println();
                } else {
                    System.out.println( array[ 0 ] );
                }
            } else if ( lgOrlt == 2 ) {
                // 大于中值时,在中值后面找
                if ( middleIndex < array.length - 1 ){
                    System.out.print( middleValue );
                    System.out.print( "  和  " );
                    System.out.print( array[ middleIndex + 1 ] );
                    System.out.println();
                } else {
                    System.out.println( array[ array.length - 1 ] );
                }
            }

            // 返回 -1,即没查找到
            return -1;
        }
    }

 

cpp 实现:

#include <string>
using namespace std;

    void print( string st ) {
        cout << ">>>" << st << endl;
    }
    
    void print( int a ) {
        cout << ">>>" << a << endl;
    }
    
    void println() {
        cout << endl;
    }
    
    // 把整型数字转换成字符串
    string intToStr( int a ) {
        char str[100];
        char str1[100];

        memset( str, 0, 100 );
        memset( str1, 0, 100 );

        int c = 0;
        int i;

        while( 1 ) {
            str[c] = ( a % 10 ) + '0'; // 模10得到最低位,+‘0’变成字符
            c++;
            a = a / 10;  // 除以10去掉已求出的最后低位,再循环计算

            if ( a == 0 ) {
                break;
            }
        }

        for( i = 0, c = c-1; c >= 0; i++, c-- ) {
            str1[i] = str[c];
        }

        //print( str1 );
        return str1;
    }

    // cpp 二分查找 --- while 实现
    int search( int arrayLength, int array[], int findValue ) {
        // 如果数组为空,直接返回 -1,即查找失败
        if ( arrayLength == 0 ) {    //cpp 判断数组为空
            return -1;
        }
        
        // 起始位置
        int start = 0;

        // 结束位置
        int end = arrayLength - 1;

        // 中间位置
        int middleIndex = -1;

        // 中值
        int middleValue = 0;

        // 查找次数
        int count = 0;

        // 代查找值 比 中值 大还是小
        int lgOrlt = -1;

        while ( start <= end ) {
            count ++;

            middleIndex = ( start + end ) / 2;
            middleValue = array[ middleIndex ];
            
            //string st1 = " middleValue = " + intToStr( middleValue )
                  // + " middleindex = " + intToStr( middleIndex );
            //print( st1 );

            if ( findValue == middleValue ) {
                // 找到了
                lgOrlt = 0;
                
                // 等于中值,直接返回
                return middleIndex;
            } else if ( findValue < middleValue ) {
                // 小于中值时,在中值前面找
                lgOrlt = 1;
                end = middleIndex - 1;
                //println( "小于中值时,在中值前面找 " );
            } else {
                // 大于中值时,在中值后面找
                lgOrlt = 2;
                start = middleIndex + 1;
                //print( "大于中值时,在中值后面找 " );
            }
        }
        
        //print( "查找次数  " + intToStr( count ) );
        //print( "lgOrlt " + intToStr( lgOrlt ) );
        //print( "middleIndex " + intToStr( middleIndex ) );
        
        string st =  "没查找到" + intToStr( findValue ) +  "  离代查找值最近的值是 :  ";
        
        if ( lgOrlt == 1 ) {
            // 小于中值时,在中值前面找
            if ( middleIndex > 0 ) {
                string temp = intToStr( array[ middleIndex - 1 ] ) + "  和  " + intToStr( middleValue );
                st += temp;
                print( st );
                println();
            } else {
                print( array[ 0 ] );
            }
        } else if ( lgOrlt == 2 ) {
            // 大于中值时,在中值后面找
            if ( middleIndex < arrayLength - 1 ) {
                string temp = intToStr( middleValue ) + "  和  " + intToStr( array[ middleIndex + 1 ] );
                st += temp;
                print( st );
                println();
            } else {
                print( array[ arrayLength - 1 ] );
            }
        }

        // 返回 -1,即 没查找到
        return -1;
    }


    // cpp 二分查找 递归实现
    // 查找次数
    int count = 0;

    // 代查找值 比 中值 大还是小
    int lgOrlt = -1;

    // 中间位置
    int middleIndex = -1;

    // 中值
    int middleValue = 0;

    // 二分查找 --- 递归 实现
    int searchRecursive( int array[], int findValue, int start, int end ) {
        // 如果数组为空,直接返回 -1,即没查找到
        if ( sizeof( array ) == 0 ) {
            return -1;
        }

        count++;

        if ( start <= end ) {
            middleIndex = ( start + end ) / 2;

            middleValue = array[ middleIndex ];

            if ( findValue == middleValue ) {
                lgOrlt = 0;

                // 等于中值,直接返回
                return middleIndex;
            } else if ( findValue < middleValue ) {
                // 小于中值时,在中值前面找
                lgOrlt = 1;

                return searchRecursive( array, findValue, start, middleIndex - 1 );
            } else {
                // 大于中值时,在中值后面找
                lgOrlt = 2;

                return searchRecursive( array, findValue, middleIndex + 1, end );
            }
        } else {
            string st =  "没查找到";
            st += intToStr( findValue );
            st +=  " 离代查找值最近的值是 :  ";
            //print( "查找次数  " + count );
            //print( "lgOrlt " + lgOrlt );
            //print( "middleIndex " + middleIndex );

            if ( lgOrlt == 1 ) {
                // 小于中值时,在中值前面找
                if ( middleIndex > 0 ) {
                   st += intToStr( array[ middleIndex - 1 ] );
                   st += "  和  ";
                   st += intToStr( middleValue );
                   print( st );

                   println();
                } else {
                   print( array[ 0 ] );
                }
            } else if ( lgOrlt == 2 ) {
                // 大于中值时,在中值后面找
                if ( middleIndex < sizeof( array ) - 1 ) {
                    print( middleValue );
                    print( "  和  " );
                    print( array[ middleIndex + 1 ] );

                    println();
                } else {
                    print( array[ sizeof( array ) - 1 ] );
                }
            }

            // 返回 -1,即没查找到
            return -1;
        }
    }

    
    // main
    void main() {
        int array[] = { 1, 3, 5, 7, 9, 11 };
        int findValue = 11;
        int arrLength = sizeof( array ) / sizeof( array[0] );
        // cpp 数组作为函数参数时,需要传递进去一个数组长度 arrLength,因为 cpp 不会在方法里辨别出数组的长度
        int re = search( arrLength, array, findValue );
        print( re );
        
        int re2 = searchRecursive( array, findValue, 0, arrLength - 1 );
        print( re2 );        
    }
    
    // --- cpp 语法注意事项 ---
    // int array[] --- cpp 数组是这样声明的
    // cpp 数组作为函数参数时,需要传递进去一个数组长度 arrLength,因为 cpp 不会在方法里辨别出数组的长度
    // 把整型数字转换成字符串,用 itoa,或者使用自己定制的函数
    // cpp 类似 js,被调用的函数,需要在调用它的位置前面,进行声明
    // 在函数外部调用 print( sizeof( array ) ); 打印的是数组所占的全部字节数,所以,可以在函数外部使用 sizeof( array ) / sizeof( array[0] ) 来计算数组的长度
    // 如果函数有一个参数是数组,在函数内部调用 print( sizeof( array ) ); 打印的是数组第一个元素所占的字节数
    // 要在 cpp 程序里使用 string,需要在文件头部这样引用 #include <string>
    

python 实现:

# py 二分法查找,递归实现。   还没实现没查找到时,显示离代查找值最近的值
def search_data(data,data_find):    #
    # 中间值的索引号的定义:数组长度/2
    mid = int( len(data) / 2 )
    
    # 判断从1开始的数字数组内查找
    if data[mid] >= 1:
        # 如果我们要找的值(data_find)比中间值(data[mid])小
        if data[mid] > data_find:
            print("要找的数比中间值[%s]小" % data[mid])
            
            # 在中间值(data[mid])的左侧继续查找,在此函数中继续循环
            search_data(data[:mid], data_find)
            
        # 如果我们要找的值(data_find)比中间值(data[mid])大
        elif data[mid] < data_find:
            print("要找的数比中间值[%s]大" % data[mid])
            
            # 在中间值(data[mid])的右侧继续查找,在此函数中继续循环
            search_data(data[mid:], data_find)
            
        else:
            # 就是它
            print("这就是要找的值[%s]" % data[mid])
    else:
        print("没找到")
#
 
if __name__ == '__main__':    #
    # 创建一个1到60万的连续数组
    data = list( range(600000) )
    
    # 调用函数找到等于 95936 的值
    search_data( data, 95936 )
#

php 实现:

<?php
// binSearch.php

/*
    递归 实现二分法查找
    $search 函数 $array 为数组,$toSearch 为要找的值
    $low 是数组第一个元素的索引
    $high 数组最后一个元素的索引 
*/
function searchRecursive( $array, $toSearch, $low = 0, $high = 0 ) {
    // 判断数组元素的数量
    if ( count( $array ) != 0 and $high == 0 ) {    // 判断是否为第一次调用
        // 数组的元素个数
        $high = count( $array );
    }
    
    if ( $low <= $high ) {      // 如果还存在剩余的数组元素
        $mid = intval( ( $low + $high ) / 2 );      // 取 $low 与 $high 的中间值
        
        //return $array[ $mid ];
        if ( $array[ $mid ] == $toSearch ) {
            return $mid;    //如果找到则返回
        } elseif ( $toSearch < $array[ $mid ] ) {
            //如果上面没有找到,则继续查找
            return searchRecursive( $array, $toSearch, $low, $mid - 1 );
        } else {
            return searchRecursive( $array, $toSearch, $mid + 1, $high );
        }
    }
    
    return "没查找到输入的值";
}

/*
	while 循环实现二分法查找
*/
function searchInWhile( $array, $toSearch ) {	
	// 第一个元素的索引
	$low = 0;   
	
	// 数组最后一个元素的索引
	$high = count( $array ) - 1;
	
	while ( $low <= $high ) {
	    // 取得数组的中间键值
	    $mid = intval( ( $low + $high ) / 2 );
	    
	    if ( $array[ $mid ] == $toSearch ) {
	        //如果取出中间的下标值跟你要搜索的值相等的话,直接去除值得下标就行
	        return $mid; 
	        
	        break;
	    } elseif ( $array[ $mid ] > $toSearch ) {
	        $high = $mid - 1;
	    } else {
	        $high = $mid + 1;
	    }
	}
}


// 
$array = array( 3, 4, 5, 7, 8, 9, 10 );
$toSearch = 9;

echo "要查找的值在数组内的索引 = ".searchRecursive( $array, $toSearch );

echo "\n";

$arr = array( 2, 4, 5, 6, 7, 8, 9, 10 );
$search = 6;

echo "要查找的值在数组内的索引 = ".searchInWhile( $arr, $search );

?>

 

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值