数据结构:折半查找

二分查找  折半查找(Binary Search)

折半查找算法的基本前提:

1)采用物理线性结构存储;

2)数据必须有序。

 

思想:

首先,假设表中元素是按升序排列,将表中间位置记录的关键字与查找关键字比较,如果两者相等,则查找成功;否则利用中间位置记录将表分成前、后两个子表,如果中间位置记录的关键字大于查找关键字,则进一步查找前一子表,否则进一步查找后一子表。重复以上过程,直到找到满足条件的记录,使查找成功,或直到子表不存在为止,此时查找不成功。

折半查找法也称为二分查找法,它充分利用了元素间的次序关系,采用分治策略,可在最坏的情况下用O(log2n)完成搜索任务。它的基本思想是,将n个元素分成个数大致相同的两半,取a[n/2]与欲查找的x作比较,如果x=a[n/2]则找到x,算法终止。如 果x<a[n/2],则我们只要在数组a的左半部继续搜索x(这里假设数组元素呈升序排列)。如果x>a[n/2],则我们只要在数组a的右 半部继续搜索x。

 

时间复杂度

时间复杂度无非就是while循环的次数!

总共有n个元素,渐渐跟下去就是n,n/2,n/4,....n/2^k(接下来操作元素的剩余个数),其中k就是循环的次数

由于你n/2^k取整后>=1

即令n/2^k=1

可得k=log2n,(是以2为底,n的对数)

所以时间复杂度可以表示O(h)=O(log2n)

log(2_10) log以2为底10的对数=3表示:在有10个数据组成的数组中查找一个数据,最多只需要找3次

             

本次算法学到的知识:

rand()产生随机数 可以通过变换产生任意数值的随机数

最简单的升序排序

中心代码:

           

//找到了输出下标,没找到输出特定符号NOT_FOUND
int BinarySearch(int *array, int cnt, int num){  
	int h = 0;          //head
	int t = cnt - 1;    //tail
	int mid;
//	int mid = (h+t)/2;   
//小错误:将mid写在这个位置,num每次都和一个固定的值进行比较,将会进入死循环

	while(h <= t){
		mid = (h+t)/2;
		if(num > array[mid]){
			h = mid + 1;
		}else if(num < array[mid]){
			t = mid - 1;	
		}else{
			return mid;
		}
	}

	return  NOT_FOUND;   //#define NOT_FOUND  -1
}

完整代码如下:

//折半查找完整代码
//(1)产生n个随机数 (整型正整数,且数据无规律)
//(2)将这n个数据进行升序排序
//(3)待查数据为num,利用BinarySearch进行查找


#include<stdio.h>   
#include<malloc.h>
#include<stdlib.h>
#include<time.h>   

#define NOT_FOUND  -1


int *initArray(int cnt);
void showArray(int *array, int cnt);
void sortAscending(int *array, int cnt);
int BinarySearch(int *array, int cnt, int num);  //找到了输出下标,没找到输出特定符号NOT_FOUND
void resultOfBinarySearch(int index);


void resultOfBinarySearch(int index){
	if(index == -1){
		printf("没有找到该数值\n");
	}else{
		printf("您要查找的数在下标为%d的位置\n", index);
	}
}


//找到了输出下标,没找到输出特定符号NOT_FOUND
int BinarySearch(int *array, int cnt, int num){  
	int h = 0;          //head
	int t = cnt - 1;    //tail
	int mid;
//	int mid = (h+t)/2;

	while(h <= t){
		mid = (h+t)/2;
		if(num > array[mid]){
			h = mid + 1;
		}else if(num < array[mid]){
			t = mid - 1;	
		}else{
			return mid;
		}
	}

	return  NOT_FOUND;   //#define NOT_FOUND  -1
}


void sortAscending(int *array, int cnt){
	int i;
	int j;
	int tmp;

	for(i = 0; i < cnt; i++){
		for(j = i + 1; j < cnt; j++){
			if(array[i] > array[j]){
				tmp = array[i];
				array[i] = array[j];
				array[j] = tmp;
			}
		}
	}
}


void showArray(int *array, int cnt){
	int i;

	for(i = 0; i < cnt; i++){
		printf("%d ", array[i]);
	}
	printf("\n");
}


int *initArray(int cnt){
	int *p;
	int i;

	p = (int *)malloc(sizeof(int) * cnt);

	srand(time(NULL));
	for(i = 0; i < cnt; i++){
		*(p+i) = rand()%900 + 100;   //产生一个三位数的随机数,即100-999			
	}

	return(p);
}


void main(void){
	int *array;  //为什么不是数组?因为要动态申请空间
	int elementCount;
	int number;
	int index;
	
	printf("\n请输入数组元素个数:");
	scanf("%d", &elementCount);

	array = initArray(elementCount);
	printf("产生的%d个三位数的随机数为:", elementCount);
	showArray(array, elementCount);

	sortAscending(array, elementCount);
	printf("这%d个数按升序排序后的结果为:", elementCount);
	showArray(array, elementCount);

	printf("\n请输入要查找的数:");
	scanf("%d", &number);
	index = BinarySearch(array, elementCount, number);
	resultOfBinarySearch(index);

    free(array);   //千万不要忘记free
}

猜你喜欢

转载自blog.csdn.net/weixin_42072280/article/details/83097711