二分查找算法

介绍:

在计算机科学中,折半搜索,也称二分查找算法二分搜索,是一种在有序数组中查找某一特定元素的搜索算法。 搜素过程从数组的中间元素开始,如果中间元素正好是要查找的元素,则搜素过程结束;如果某一特定元素大于或者小于中间元素,则在数组大于或小于中间元素的 那一半中查找,而且跟开始一样从中间元素开始比较。如果在某一步骤数组为空,则代表找不到。这种搜索算法每一次比较都使搜索范围缩小一半。

时间复杂度

折半搜索每次把搜索区域减少一半,时间复杂度为O(logN)。(N代表集合中元素的个数)

空间复杂度

O(1),虽以递归形式定义,但是尾递归,可改写为循环。

测试结果:

数组里有500000个随机数, 执行500次后花费的毫秒数
最大毫秒数为21
最小毫秒数为1
平均毫秒数为2

代码示例:

<!doctype html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>二分查找算法</title>
</head>
<body>
<script>
var count = 10000,
	num = testCount = 500,
    i,
    exeCount,
	exeTimeArr = [],

	binarySearch = function(n, a, lastIndex, type){
		
		if(a.length === 0) return -1;

		lastIndex = lastIndex || 0;

		var middle = Math.floor(a.length / 2),
			thisIndex = middle;

		if(type == 'right'){

			thisIndex = lastIndex + middle + 1;

		}else if(type == 'left'){
			thisIndex = lastIndex - ( a.length - middle);
				
		}

		if(a[middle] === n){
			
			return thisIndex;

		}else{
			
			if(n > a[middle]){
				return binarySearch( n, a.slice(middle + 1), thisIndex, 'right' );
			}else{
				return binarySearch( n, a.slice(0, middle), thisIndex, 'left' );
			}
		}
	};

var body = document.getElementsByTagName('body')[0];
var log = function(s){

	var p = document.createElement('p');
	var ps = document.getElementsByTagName('p');

	p.innerHTML = s;

	ps.length ?
		body.insertBefore(p, ps[0]) :
		body.appendChild(p);

	//document.write(s + '<br />'); 破坏文档结构
	//firefox下使用console.log并开启firebug会影响执行
}

function exeTest( callback ){

	function test(){
		var cost,
			startTime,
			arr = [],
			index,
			num = Math.round(Math.random() * count);

		testCount--;

		// 构建随机数组
		for(i=0;i<count;i++){
			arr.push( Math.round(Math.random() * count) ); // 0 - count
		}

		arr.sort(function(a, b){
			return a - b;
		});

		startTime = + new Date();

		// 算法执行
		index = binarySearch( num, arr );
		exeTimeArr.push(cost = new Date() - startTime); //花费的毫秒数

		log('本次测试花费 '+ cost +' 毫秒, 还剩 '+ testCount +' 次测试, 该数的index为 ' + index);

		if(testCount == 0 && typeof callback == 'function'){

			callback();

		}else{

			// 预防浏览器挂起
			setTimeout(test, 0);
		}
	}

	test();
}

function callback(){
	var sum = 0;
    var result = '数组里有'+ count +'个随机数, 执行'+ num +'次后花费的毫秒数' + '<br />' +
					  '最大毫秒数为' + Math.max.apply(null, exeTimeArr) + '<br />' +
					  '最小毫秒数为' + Math.min.apply(null, exeTimeArr) + '<br />';

	exeTimeArr.forEach(function(value) {
		sum += value;
	})

	result += '平均毫秒数为' + Math.round( sum / num ) ;

	log(result);
}

// 开始测试
exeTest(callback);

</script>
</body>
</html>





你可能感兴趣的:(二分查找算法)