折半查找某数X在数组中出现的次数(2019北邮考研真题)

题目:采用折半查找的思想,统计所给X在数组A中出现的次数,例如,122235。2出现次数为3。

分析:采用分治(折半查找)的思想,若中间值为X,则统计数量+1,并递归查找左子表与右子表。若中间值小于X,则X可能在右子表,查找右子 表。若中间值大于X,则X可能在左子表,查找左子表。

函数代码:

//统计X在数组A中出现的次数函数
int Count(int A[],int start,int end,int X)
{
	int low,high,mid;int countmid=0,countleft=0,countright=0;
	low=start;
	high=end;
    if(low>high)return 0;//递归出口
    //折半查找思想 
	mid=(low+high)/2;
	 if(A[mid]==X)//比较中间
	 {
		 countmid++;
		 countleft=Count(A,low,mid-1,X);//折半查找左子表
		 countright=Count(A,mid+1,high,X);//折半查找右子表
	 }
	 else if(A[mid]<X)//X只能出现在A[mid]右侧,仅需查找右子表
		countright=Count(A,mid+1,high,X);//折半查找右子表
	 else            //仅需查找左子表
		countleft=Count(A,low,mid-1,X);//折半查找左子表
	return countmid+countleft+countright;
}

全部代码:

/*
    题目:采用折半查找的思想,统计所给X在数组A中出现的次数,例如,122235。2出现次数为3。
    Project: binary_count(数据结构-折半统计) 
    Date:    2018/12/26
    Author:  Frank Yu
	基础函数:
	CreatList(int A[],int &n) 参数:数组A,数组长度n 功能:创建数组函数 初始化前n个数据 时间复杂度:O(n)
	InitList(int A[]) 参数:数组A 功能:初始化 时间复杂度:O(1)
	Count(int A[],int start,int end,int X) 参数:数组A,开始下标start,结束下标end,要统计数X 时间复杂度:O(n) 
	PrintList(int A[],int &n) 参数:数组A 功能:遍历数组A,并输出 时间复杂度:O(n) 
	Create(int A[],int &n) 参数:数组A,数组长度n 功能:创建数组A 时间复杂度:O(n)
	Binary_Count(int A[],int &n) 参数:数组A,数组长度n 功能:调用输入X,调用Count(int A[],int start,int end,int X)
	                            ,显示X在数组A中出现的次数 
	 
	分析:采用分治的思想,若中间值为X,则统计数量+1,并递归查找左子表与右子表。若中间值小于X,则X可能在右子表,查找右子表。
              若中间值大于X,则X可能在左子表,查找左子表。
*/
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<iostream>
#define MaxSize 100
#define Status int
using namespace std;
int n=0;
int A[MaxSize];
//***************************基本操作函数*******************************//
//初始化数组函数,构造一个空的数组 
Status InitList(int A[])
{
	memset(A,0,sizeof(A));//初始化数据为0
	return 0;
}
//创建数组函数 初始化前n个数据
bool CreatList(int A[],int &n)
{
	if(n<0||n>MaxSize)false;//n非法
	for(int i=0;i<n;i++)
	{
		scanf("%d",&A[i]);
	}
	return true;
}
//统计X在数组A中出现的次数函数
int Count(int A[],int start,int end,int X)
{
	int low,high,mid;int countmid=0,countleft=0,countright=0;
	low=start;
	high=end;
    if(low>high)return 0;//递归出口
    //折半查找思想 
	mid=(low+high)/2;
	 if(A[mid]==X)//比较中间
	 {
		 countmid++;
		 countleft=Count(A,low,mid-1,X);//折半查找左子表
		 countright=Count(A,mid+1,high,X);//折半查找右子表
	 }
	 else if(A[mid]<X)//X只能出现在A[mid]右侧,仅需查找右子表
		countright=Count(A,mid+1,high,X);//折半查找右子表
	 else            //仅需查找左子表
		countleft=Count(A,low,mid-1,X);//折半查找左子表
	return countmid+countleft+countright;
}
//********************************功能函数*****************************************//
//输出功能函数 按位置从小到大输出数组所有元素
void PrintList(int A[],int &n)
{
	printf("当前数组所有元素:");
	for(int i=0;i<n;i++)
	{
		printf("%d ",A[i]);
	}
	printf("\n");
}
//创建数组函数
void Create(int A[],int &n)
{
	bool flag;
	printf("请输入要创建的数组长度(>1):");
	scanf("%d",&n);
	printf("请输入%d个数(空格隔开):",n);
	flag=CreatList(A,n);
	if(flag){
		printf("创建成功!\n");
		PrintList(A,n);
	}
	else printf("输入长度非法!\n");

}
//折半统计功能函数 调用Count(int A[],int start,int end,int X)
void Binary_Count(int A[],int &n)
{
	int X;int count;
	if(0==n)printf("数组为空\n");
	else
	{
		printf("请输入要查找的值:\n");
		scanf("%d",&X);
		count=Count(A,0,n-1,X);
		printf("%d在数组中出现%d次。\n",X,count);
	}
}
//菜单
void menu()
{
   printf("********1.创建    2.统计*********\n");
   printf("********3.退出          *********\n");
}
int main()
{
 int choice;
 InitList(A);
 while(1)
 {
  menu();
  printf("请输入菜单序号:\n");
  scanf("%d",&choice);
  if(3==choice) break;
  switch(choice)
  {
  case 1:Create(A,n);break;
  case 2:Binary_Count(A,n);break;
  default:printf("输入错误!!!\n");
  }
 }
 return 0;
}

结果截图:

结果截图

更多数据结构实现:数据结构严蔚敏版的实现(含全部代码)

有问题请下方评论,转载请注明出处,并附有原文链接,谢谢!如有侵权,请及时联系。

评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

lady_killer9

感谢您的打赏,我会加倍努力!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值