折半查找/二分查找(C语言)递归/非递归查找

概述

二分查找也称折半查找(Binary Search),它是一种效率较高的查找方法。但是,折半查找要求线性表必须采用顺序存储结构,而且表中元素按关键字有序排列。

算法要求

  1. 必须采用顺序存储结构。
  2. 必须按关键字大小有序排列。下面的例子是从小到大排序。

算法图解

举例,我们要查找数字21:

首先根据算法要求找了一组数据,使用low、high、mid指针分别表示数据开始结束和中间位置。算法开始时指针分别在自己的位置。

在这里插入图片描述
递归开始,将21与mid指针的数字比较,结果大于21,因此high指针指向mid位置并且减一,然后重新计算mid指针的位置。

在这里插入图片描述
同样再次与mid指向的数字进行比较,21大于19,low指针指向mid的位置加一,重新计算mid,发现low指针和mid指针指向同一个位置,因此就找到数字21了。

在这里插入图片描述

算法分析

1、递归

1.创建并初始化数据

#define MAXSIZE 100
#define KeyType int
#define ERROR    0


typedef struct{
    
    
	KeyType key;
}ElemType;

typedef struct{
    
    
	ElemType *R;
	int length;
}SSTable;

int CreateSTable(SSTable &ST){
    
    
	ST.length=0;
	ST.R=new ElemType[MAXSIZE];
	if(!ST.R)	exit(ERROR);
	int n;
	cout<<"请输入要输入数字的个数:"<<endl;
	cin>>n;
	for(int i=1;i<=n;i++){
    
    
		cin>>ST.R[i].key;
		ST.length++;
	}
		return 1;
}
          ST.R 存放的是排好序的数据。如:11  12  13  14  15  16  17  18  19 20
          ST.length 存放数据的长度。 如:10

2.递归查找要查找的数字

int Search_Bin(SSTable ST,KeyType key,int low ,int high){
    
    //递归算法 
	if(low>high) return -1;
	int mid=low+(high-low)/2;
	if(key<ST.R[mid].key){
    
    
		return Search_Bin(ST,key,low,mid-1);
	}
	else if(key>ST.R[mid].key) return Search_Bin(ST,key,mid+1,high);
	else{
    
    
		cout<<"该数字在第:"<<mid<<"个位置";
	}
} 
  mid保证了记录的位置始终是中间附近的位置
  key记录了要查找的数字
  low记录下标最小的位置,初始默认为1
  high记录下标最大的位置

如果要查找的数字key小于中间位置mid的数字,那么递归进入mid左边部分;
如果要查找的数字key大于中间位置mid的数字,那么递归进入mid右边部分;
如果要查找的数字key不大于也不小于中间位置mid的数字,那么mid所在的数字就是要查找的数字;

递归停止条件是low大于high,说明查找完毕;查到或者没有查找。

在递归时,low和high在不停变化,如果进入左边递归时那么high等于mid-1(就是说此时最大的下标high等于中间位置mid减一的位置);如果进入右边递归时那么low等于mid+1(就是说此时最小的下标low等于中间位置mid加一的位置);

目的在于不断缩小数据的规模,直到找到或者找完所有数据为止。

2、非递归

1.同样的初始化数据

#define MAXSIZE 100
#define KeyType int
#define ERROR    0


typedef struct{
    
    
	KeyType key;
}ElemType;

typedef struct{
    
    
	ElemType *R;
	int length;
}SSTable;

int CreateSTable(SSTable &ST){
    
    
	ST.length=0;
	ST.R=new ElemType[MAXSIZE];
	if(!ST.R)	exit(ERROR);
	int n;
	cout<<"enter the number :"<<endl;
	cin>>n;
	for(int i=1;i<=n;i++){
    
    
		cin>>ST.R[i].key;
		ST.length++;
	}
		return 1;
}

2.非递归查找要查找的数字

int Search_Bin(SSTable ST,KeyType key){
    
    //非递归算法 
	int low=1,high=ST.length,mid;
	while(low<=high){
    
    
		mid=(low+high)/2;
		if(key==ST.R[mid].key) {
    
    
			cout<<"add is "<<mid;
			return 1;
		}
		else if(key<ST.R[mid].key)  high = mid-1;
		else low=mid+1;
	}
	return 0;
}

非递归使用while循环,停止条件同样是是low大于high。
在循环中首先计算中间元素的下标,然后将要比较的数字和中间位置的数字进行比较;如果等于,则找到;如果小于,那么进入中间位置的左边(即把最大的下标high变成中间下标减一的位置)再次进行循环;如果大于,那么进入中间位置的右边进行查找;

目的在于不断缩小数据的规模,直到找到或者找完所有数据为止。

二分查找案例

1、递归案例

#include<iostream>
#include<stdlib.h>
using namespace std;

#define MAXSIZE 100
#define KeyType int
#define ERROR    0


typedef struct{
    
    
	KeyType key;
}ElemType;

typedef struct{
    
    
	ElemType *R;
	int length;
}SSTable;

int CreateSTable(SSTable &ST){
    
    
	ST.length=0;
	ST.R=new ElemType[MAXSIZE];
	if(!ST.R)	exit(ERROR);
	int n;
	cout<<"请输入要输入数字的个数:"<<endl;
	cin>>n;
	for(int i=1;i<=n;i++){
    
    
		cin>>ST.R[i].key;
		ST.length++;
	}
		return 1;
}

void print(SSTable ST){
    
    
	for(int i=1 ; i<=ST.length ; i++)
		cout<<ST.R[i].key<<" ";
}

int Search_Bin(SSTable ST,KeyType key,int low ,int high){
    
    //递归算法 
	if(low>high) return -1;
	int mid=low+(high-low)/2;
	if(key<ST.R[mid].key){
    
    
		return Search_Bin(ST,key,low,mid-1);
	}
	else if(key>ST.R[mid].key) return Search_Bin(ST,key,mid+1,high);
	else{
    
    
		cout<<"该数字在第:"<<mid<<"个位置";
	}
} 


int main(){
    
    
	SSTable ST;
	CreateSTable(ST);
	print(ST);
	int n;
	cout<<endl<<"输入要查找的数字 :";
	cin>>n;
	Search_Bin(ST,n,1,ST.length);
}

2、非递归案例

#include<iostream>
#include<stdlib.h>
using namespace std;

#define MAXSIZE 100
#define KeyType int
#define ERROR    0


typedef struct{
    
    
	KeyType key;
}ElemType;

typedef struct{
    
    
	ElemType *R;
	int length;
}SSTable;

int CreateSTable(SSTable &ST){
    
    
	ST.length=0;
	ST.R=new ElemType[MAXSIZE];
	if(!ST.R)	exit(ERROR);
	int n;
	cout<<"enter the number :"<<endl;
	cin>>n;
	for(int i=1;i<=n;i++){
    
    
		cin>>ST.R[i].key;
		ST.length++;
	}
		return 1;
}

void print(SSTable ST){
    
    
	for(int i=1 ; i<=ST.length ; i++)
		cout<<ST.R[i].key<<" ";
}

int Search_Bin(SSTable ST,KeyType key){
    
    //非递归算法 
	int low=1,high=ST.length,mid;
	while(low<=high){
    
    
		mid=(low+high)/2;
		if(key==ST.R[mid].key) {
    
    
			cout<<"add is "<<mid;
			return 1;
		}
		else if(key<ST.R[mid].key)  high = mid-1;
		else low=mid+1;
	}
	return 0;
}


int main(){
    
    
	SSTable ST;
	CreateSTable(ST);
	print(ST);
	int n;
	cout<<endl<<"enter your number :";
	cin>>n;
	Search_Bin(ST,n);
}

おすすめ

転載: blog.csdn.net/Lazy_Goat/article/details/120027985