【从零学习经典算法系列】分治策略实例——二分查找

1、二分查找算法简介

二分查找算法是一种在有序数组中查找某一特定元素的搜索算法。搜素过程从数组的中间元素开始,如果中间元素正好是要查找的元素,则搜索过程结束;如果某一特定元素大于或者小于中间元素,则在数组大于或小于中间元素的那一半中查找,而且跟开始一样从中间元素开始比较。如果在某一步骤数组
为空,则代表找不到。这种搜索算法每一次比较都使搜索范围缩小一半。折半搜索每次把搜索区域减少一半,时间复杂度为Ο(logn)。

二分查找的优点是比较次数少,查找速度快,平均性能好;其缺点是要求待查表为有序表,且插入删除困难。因此,二分查找方法适用于不经常变动而查找频繁的有序列表。

2、二分查找算法要求

(1)必须采用顺序存储结构

(2)必须按关键字大小有序排列。

3、二分查找算法流程图

图1 二分查找算法流程图

4、c语言实现

#include <stdio.h>

int binary_search_recursion(const int array[], int low, int high, int key)
{
	int mid = low + (high - low)/2;
	if(low > high)
		return -1;
	else{
		if(array[mid] == key)
			return mid;
		else if(array[mid] > key)
			return binary_search_recursion(array, low, mid-1, key);
		else
			return binary_search_recursion(array, mid+1, high, key);
	}
}

int binary_search_loop(const int array[], int len, int key)
{
	int low = 0;
	int high = len - 1;
	int mid;
	while(low <= high){
		mid = (low+high) / 2;
		if(array[mid] == key)
			return mid;
		else if(array[mid] > key)
			high = mid - 1;
		else
			low = mid + 1;
	}
	return -1;
}

int main()
{
	const int num_array[] = {2,4,6,8,10,12,14,16,18,20};
	int key;
	int key_pos;
	int array_size = sizeof(num_array)/sizeof(int);
	for(int i=0;i<array_size;i++){
		printf("%d  ",num_array[i]);
		if(i % 5 == 0)
			printf("\n");
	}
	printf("\n");

	while(1){
		printf("Put in the number you want to find:\n");
		scanf("%d",&key);
		//key_pos = binary_search_recursion(num_array, 0, array_size, key);
		key_pos = binary_search_loop(num_array, array_size, key);
		printf("The position of key is %d\n", key_pos);
	}

}

图2 程序结果

5、造成边界错误的原因

二分查找算法的边界一般分为两种情况,一种为左闭右开区间,如[low,high),一种是左闭右闭区间,如[low,high]。这里需要注意的是循环体外的初始化条件,与循环体内的迭代步骤,都必须遵守一致的区间规则,也就是说,如果循环体初始化时,是以左闭右开区间为边界的,那么循环体内部的迭代也应该如此。

转载请注明作者与文章出处:http://blog.csdn.net/jasonding1354/article/details/38176171

【从零学习经典算法系列】分治策略实例——二分查找,布布扣,bubuko.com

时间: 2024-10-27 07:47:18

【从零学习经典算法系列】分治策略实例——二分查找的相关文章

【从零学习经典算法系列】分治策略实例——快速排序(QuickSort)

在前面的博文(http://blog.csdn.net/jasonding1354/article/details/37736555)中介绍了作为分治策略的经典实例,即归并排序,并给出了递归形式和循环形式的c代码实例.但是归并排序有两个特点,一是在归并(即分治策略中的合并步骤)上花费的功夫较多,二是排序过程中需要使用额外的存储空间(异地排序算法<out of place sort>). 为了节省存储空间,出现了快速排序算法(原地排序in-place sort).快速排序是由东尼·霍尔所发展的一

【经典算法】分治策略

一.什么是分治 有很多算法是递归的:为了解决一个给定的问题,算法要一次或多次递归调用其自身来解决的子问题.这些算法通常采用分治策略:将原问题划分为n个规模较小而结构与原问题相似的子问题:递归地解决这些子问题,然后再合并其结果,就得到原问题的解. 二.分治算法的三个步骤 分治模式在每一层递归上都有三个步骤: 分解(Divide)步骤将问题划分为一些子问题,子问题的形式与原问题一样,只是规模更小. 解决(Conquer)步骤递归地求解出子问题.如果子问题规模足够小,则停止递归,直接求解. 合并(Co

白话经典算法系列之七 堆与堆排序

堆排序与高速排序,归并排序一样都是时间复杂度为O(N*logN)的几种常见排序方法.学习堆排序前,先解说下什么是数据结构中的二叉堆. 二叉堆的定义 二叉堆是全然二叉树或者是近似全然二叉树. 二叉堆满足二个特性: 1.父结点的键值总是大于或等于(小于或等于)不论什么一个子节点的键值. 2.每一个结点的左子树和右子树都是一个二叉堆(都是最大堆或最小堆). 当父结点的键值总是大于或等于不论什么一个子节点的键值时为最大堆.当父结点的键值总是小于或等于不论什么一个子节点的键值时为最小堆.下图展示一个最小堆

经典算法宝典——分治思想(四)(1)

分治法(Divide and Conquer)的设计思想是,将一个难以直接解决的大问题,分割成一些规模较小的几个相似问题,以便各个击破,分而治之. 说明: 分治策略的应用很广,具体表现形式各异,比如:折半查找.合并排序.快速排序.二叉树遍历(先遍历左子树再遍历右子树).二叉排序树的查找等算法. 一.分治算法框架 1.算法设计思想 分治法求解问题的过程是,将整个问题分解成若干个小问题后分而治之.如果分解得到的子问题相对来说还太大,则可反复使用分治策略将这些子问题分成更小的同类型子问题,直至产生出方

白话经典算法系列之七 堆与堆排序(转)

堆排序与快速排序,归并排序一样都是时间复杂度为O(N*logN)的几种常见排序方法.学习堆排序前,先讲解下什么是数据结构中的二叉堆. 二叉堆的定义 二叉堆是完全二叉树或者是近似完全二叉树. 二叉堆满足二个特性: 1.父结点的键值总是大于或等于(小于或等于)任何一个子节点的键值. 2.每个结点的左子树和右子树都是一个二叉堆(都是最大堆或最小堆). 当父结点的键值总是大于或等于任何一个子节点的键值时为最大堆.当父结点的键值总是小于或等于任何一个子节点的键值时为最小堆.下图展示一个最小堆: 由于其它几

【转】白话经典算法系列之七 堆与堆排序

堆排序与快速排序,归并排序一样都是时间复杂度为O(N*logN)的几种常见排序方法.学习堆排序前,先讲解下什么是数据结构中的二叉堆. 二叉堆的定义 二叉堆是完全二叉树或者是近似完全二叉树. 二叉堆满足二个特性: 1.父结点的键值总是大于或等于(小于或等于)任何一个子节点的键值. 2.每个结点的左子树和右子树都是一个二叉堆(都是最大堆或最小堆). 当父结点的键值总是大于或等于任何一个子节点的键值时为最大堆.当父结点的键值总是小于或等于任何一个子节点的键值时为最小堆.下图展示一个最小堆: 由于其它几

白话经典算法系列之九 从归并排序到数列的逆序数对(微软笔试题)

首先来看看原题 微软2010年笔试题 在一个排列中,如果一对数的前后位置与大小顺序相反,即前面的数大于后面的数,那么它们就称为一个逆序数对.一个排列中逆序的总数就称为这个排列的逆序数.如{2,4,3,1}中,2和1,4和3,4和1,3和1是逆序数对,因此整个数组的逆序数对个数为4,现在给定一数组,要求统计出该数组的逆序数对个数. 计算数列的逆序数对个数最简单的方便就最从前向后依次统计每个数字与它后面的数字是否能组成逆序数对.代码如下: #include <stdio.h> int main()

【白话经典算法系列之十七】 数组中只出现一次的数 其他三次

本文地址:http://blog.csdn.net/morewindows/article/details/12684497转载请标明出处,谢谢. 欢迎关注微博:http://weibo.com/MoreWindows 首先看看题目要求: 数组A中,除了某一个数字x之外,其他数字都出现了三次,而x出现了一次.请给出最快的方法找到x. 这个题目非常有意思,在本人博客中有<位操作基础篇之位操作全面总结>这篇文章介绍了使用位操作的异或来解决——数组中其他数字出现二次,而x出现一次,找出x.有<

三白话经典算法系列 Shell排序实现

山是包插入的精髓排序排序.这种方法,也被称为窄增量排序,因为DL.Shell至1959提出命名. 该方法的基本思想是:先将整个待排元素序列切割成若干个子序列(由相隔某个"增量"的元素组成的)分别进行直接插入排序,然后依次缩减增量再进行排序,待整个序列中的元素基本有序(增量足够小)时,再对全体元素进行一次直接插入排序. 由于直接插入排序在元素基本有序的情况下(接近最好情况),效率是非常高的,因此希尔排序在时间效率上比前两种方法有较大提高. 以n=10的一个数组49, 38, 65, 97