#include<stdio.h>//7.9 有15个数按大小的顺序存放在一个数组中,输入一个数,要求用拆半查找法找出该数是数组中第几个元素的值。(函数的方法)
#define N 15
int input(int a[N])
{
printf("\n……进入input()函数……\n");
int i,flag;
printf("请输入数组元素,后输入的要比前一个大:a[0]=");
scanf("%d",&a[0]);
fflush(stdin);
for(i=1;i<N;i++)
{
flag=1;
printf("a[%d]=",i);
scanf("%d",&a[i]);
fflush(stdin);
while(flag)
{
if(a[i]<a[i-1])
{
printf("您输入的数值小于前一个数,请重新输入a[%d]=",i);
scanf("%d",&a[i]);
fflush(stdin);
flag=1;
}
else
{
flag=0;
}
}
}
printf("……退出intput()函数……\n\n");
return 0;
}
int display(int a[N])
{
printf("\n……进入diaplay()函数……\n");
int i;
for(i=0;i<N;i++)
{
printf("a[%d]=%d ",i,a[i]);
}
printf("\n……退出display()函数……\n\n");
return 0;
}
int search(int num,int a[N])
{
printf("\n…………进入search()函数,开始查询…………\n");
display(a);
int i,mid,head=0,bottom=N,n,flag=1;
mid=(bottom-head)/2;
if((num<a[0])||(num>a[N-1]))
{
printf("您输入的数字不在数组的范围内。\n");
n=-1;
}
else
{
while(flag)
{
if(num==a[mid])
{
n=mid;
flag=0;
}
else
{
if(num>a[mid])
{
head=mid;
mid=(bottom+head)/2;
flag=1;
}
else
{
bottom=mid;
mid=(bottom-head)/2;
flag=1;
}
}
}
}
printf("\n…………查询结束,退出search()函数…………\n\n");
return n;
}
int main()
{
int a[N],num,n,flag=1;
char c;
input(a);
display(a);
while(flag)
{
printf("请输入您要查找的数:");
scanf("%d",&num);
fflush(stdin);
n=search(num,a);
if(n!=-1)
{
printf("您查找数在数组中:a[%d]=%d\n\n",n,a[n]);
}
printf("想继续查找吗?(Y/N)");
scanf("%c",&c);
if(c=='N'||c=='n')flag=0;
else flag=1;
}
return 0;
}
自己真的很笨,写了2个多小时。第1个严重的错误在 search() 函数中 if((num<a[0])||(num>a[N-1])) 的a[N-1]写成a[N]了,如此简单而又经典的错误。第2个错误在 if(num>a[mid]) 中的 mid=(bottom+head)/2; 写错,误写为bottom-head。真的是太不细心了。
为了方便理解 mid 的值是如何变化的,改进出了以下版本。
#include<stdio.h>//7.9 有15个数按大小的顺序存放在一个数组中,输入一个数,要求用拆半查找法找出该数是数组中第几个元素的值。(函数的方法)
#define N 14
int input(int a[N])
{
printf("\n……进入input()函数……\n");
int i,flag;
printf("请输入数组元素,后输入的要比前一个大:a[0]=");
scanf("%d",&a[0]);
fflush(stdin);
for(i=1;i<N;i++)
{
flag=1;
printf("a[%d]=",i);
scanf("%d",&a[i]);
fflush(stdin);
while(flag)
{
if(a[i]<a[i-1])
{
printf("您输入的数值小于前一个数,请重新输入a[%d]=",i);
scanf("%d",&a[i]);
fflush(stdin);
flag=1;
}
else
{
flag=0;
}
}
}
printf("……退出intput()函数……\n\n");
return 0;
}
int display(int a[N])
{
printf("\n……进入diaplay()函数……\n");
int i;
for(i=0;i<N;i++)
{
printf("a[%d]=%d ",i,a[i]);
}
printf("\n……退出display()函数……\n\n");
return 0;
}
int search(int num,int a[N])
{
printf("\n…………进入search()函数,开始查询…………\n");
display(a);
int i,mid,head=0,bottom=N,n,flag=1;
mid=(bottom-head)/2;
if((num<a[0])||(num>a[N-1]))
{
printf("您输入的数字不在数组的范围内。\n");
n=-1;
}
else
{
while(flag)
{
if(num==a[mid])
{
printf("num==a[mid]中if:mid=%d\n",mid);
n=mid;
flag=0;
}
else
{
if(num>a[mid])
{
printf("num>a[mid]中if:mid=%d\n",mid);
head=mid;
mid=(bottom+head)/2;
flag=1;
}
else
{
printf("num<a[mid]中if:mid=%d\n",mid);
bottom=mid;
mid=(bottom-head)/2;
flag=1;
}
}
}
}
printf("\n…………查询结束,退出search()函数…………\n\n");
return n;
}
int main()
{
int a[N],num,n,flag=1;
char c;
input(a);
display(a);
while(flag)
{
printf("请输入您要查找的数:");
scanf("%d",&num);
fflush(stdin);
n=search(num,a);
if(n!=-1)
{
printf("您查找数在数组中:a[%d]=%d\n\n",n,a[n]);
}
printf("想继续查找吗?(Y/N)");
scanf("%c",&c);
if(c=='N'||c=='n')flag=0;
else flag=1;
}
return 0;
}
第2天重写程序时发现,以上的2个程序都有问题,比如0,2,4,6,8,10……。如果查询3,程序会陷入死循环。
20160720-0841终于写改好了
#include<stdio.h>//7.9 有15个数按大小的顺序存放在一个数组中,输入一个数,要求用拆半查找法找出该数是数组中第几个元素的值。(函数的方法)
#define N 10
void input(int a[])
{
int i,flag;
printf("a[0]=",i);
scanf("%d",&a[0]);
fflush(stdin);
for(i=1;i<N;i++)
{
printf("a[%d]=",i);
scanf("%d",&a[i]);
fflush(stdin);
flag=1;
while(flag)
{
if(a[i]<=a[i-1])
{
printf("本次输入的小于上次输入,请重新输入a[%d]=",i);
scanf("%d",&a[i]);
fflush(stdin);
flag=1;
}
else
{
flag=0;
}
}
}
}
void display(int a[])
{
int i;
for(i=0;i<N;i++)
{
printf("a[%d]=%d ",i,a[i]);
}
printf("\n");
}
void search(int num,int a[])
{
int mid,head=0,bottom=N,flag=1,result,n;
mid=(bottom+head)/2;
if(num<a[0]||num>a[N-1])
{
printf("查询不到。您输入的数超出数组的范围。\n");
}
else
{
while(flag)
{
flag=1;
if(num==a[mid])
{
printf("mid=%d\n",mid);
result=1;
n=mid;
flag=0;
}
else
{
if(num>a[mid])
{
head=mid;
mid=(bottom+head)/2;
result=0;
printf("现在是>,head=%d,bottom=%d,mid=%d\n",head,bottom,mid);
if(mid==head){flag=0;}
}
else
{
bottom=mid;
mid=(bottom+head)/2;
result=0;
printf("现在是<,head=%d,bottom=%d,mid=%d\n",head,bottom,mid);
if(mid==bottom){flag=0;}
}
}
}
if(result==1)
{
printf("查询到。a[%d]=%d\n",n,a[n]);
}
else
{
printf("查询不到。\n");
}
}
printf("\n");
}
int main()
{
int a[N],num,flag=1;
char c;
input(a);
display(a);
while(flag)
{
display(a);
printf("请输入要查询的数:");
scanf("%d",&num);
fflush(stdin);
search(num,a);
printf("继续查找(Y/N)?");
scanf("%c",&c);
if(c=='N'||c=='n')
{
flag=0;
}
else
{
flag=1;
}
}
return 0;
}
这次主要耽误时间的原因是: search() 函数中的 while(flag) ,这个条件没有设定好。刚开始我只这样写的 while((mid!=head)||(mid!=bottom)) 程序陷入while死循环, (条件1) ||(条件2) 运算符的含义是逻辑与,(条件1)和(条件2)有一个为真,while就为真,就会继续运行。
今天我要不使用函数,试试看能不能完成。
今天是20160725,最近很忙,每天只有一个小时的时间能够进入状态。最近最有心得的一句话是来自于《程序员思维修炼》“程序员进入状态要20分钟”,我每天能进入状态的时间非常少,很宝贵。下边是不用函数完成的,写了2、3天吧,不用函数真难。
#include<stdio.h>//7.9 有15个数按大小的顺序存放在一个数组中,输入一个数,要求用拆半查找法找出该数是数组中第几个元素的值。
#define N 10
int main()
{
int a[N],i,flag,num,head=0,bottom=N,mid,flagChaZhao=1,ChaZhaoJieGuo=1;
char c;
printf("请输入a[0]=");
scanf("%d",&a[0]);
fflush(stdin);
flag=1;//输入部分
while(flag)
{
for(i=1;i<N;i++)
{
printf("a[%d]=",i);
scanf("%d",&a[i]);
fflush(stdin);
if(a[i]>a[i-1])
{
flag=0;
}
else
{
flag=1;
printf("您的输入有误,请重新输入a[%d]=",i);
scanf("%d",&a[i]);
fflush(stdin);
}
}
}
for(i=0;i<N;i++)//输出显示部分
{
printf("a[%d]=%d ",i,a[i]);
if((i+1)%5==0)printf("\n");
}
flag=1;//查找部分
while(flag)
{
printf("请输入您要查找的数num=");
scanf("%d",&num);
fflush(stdin);
printf("输入成功:num=%d\n",num);
if((num<a[0])||(num>a[N-1]))
{
printf("您找的数超出数组的范围。不再查找。\n");
ChaZhaoJieGuo=0;
}
else
{
printf("您找的数在数组的范围中。准备开始查找…………\n");
mid=(bottom+head)/2;
flagChaZhao=1;
while(flagChaZhao)
{
if(num==a[mid])
{
flagChaZhao=0;
ChaZhaoJieGuo=1;
num=mid;
}
else
{
if(num>a[mid])
{
flagChaZhao=1;
ChaZhaoJieGuo=0;
head=mid;
mid=(head+bottom)/2;
printf(">num=%d,mid=%d\n",num,mid);
}
else
{
flagChaZhao=1;
ChaZhaoJieGuo=0;
bottom=mid;
mid=(head+bottom)/2;
printf("<num=%d,mid=%d\n",num,mid);
}
if((mid==head)||(mid==bottom)) flagChaZhao=0;
}
}
if(ChaZhaoJieGuo)
printf("找到结果:a[%d]=%d\n",num,a[num]);
else
printf("找不到结果。\n");
}
printf("想继续查找吗?(Y/N)");//是否继续部分
scanf("%c",&c);
fflush(stdin);
if(c=='N'||c=='n')flag=0;
else flag=1;
head=0;bottom=N;mid=(bottom+head)/2;
}
return 0;
}
这次主要耽误时间的是倒数第3行 head=0;bottom=N;mid=(bottom+head)/2; 每次while开始前都要记得给head、bottom、mid赋值,不然它们会是上次程序运行的结果,上个版本使用函数由于是把要对比的数据每次都重新调入,刚好避免了这个问题。明天开始学习函数了,再见了,前7章。