C语言程序设计:二分查找(折半查找)

C语言程序设计:二分查找(折半查找)

1.什么是二分查找

二班查找又称折半查找,他是一种高效率的查询方法。

2.二分查找的优点

高效,减少查询次数,查找的速度快,平均性能好(貌似 快速排序 也是),非递归实现(我觉得也是优点吧)。

3.二分查找的缺点

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

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

说人话就是 数据得是数组,且从大到小 或者 从小到大 等进行排好序。

4.二分查找原理

1

针对已经排列好的数组,假如我判断6是否在这个数组内,如果是返回ture,否则返回false。

我们在数组的最左边定义一个left,在最右边定义为right,中间的mid则为(left+right)/2

我们用mid的值与6做对比,发现mid的值为5,6比5大,则mid左边的所有数据都抛弃掉,同时,我们把left的值设为mid+1,right保持不变

NueXini2

则left则到了6这个位置,则mid可以是7或者8这个位置,不影响操作。假设mid在的7位置

我们这时在比较6与mid的值比较,发现mid的值为7,6比7小,则mid右边的所有数据都抛弃掉,同时right变为mid-1

NueXini3.png

此时,我们的mid位置为(left+right)/2=6,mid的第6位置的值为6,是我们要查找的6,则 return true。


但是,假如我们查找的数不在这个数组里面呢?

首先,我们定义一串这样的数组a,要查找的数为60

NueXini4

定义a起始位置为left,末尾位置为right,则mid=(0+9)/2=4(4或者5都可以),a[mid]=a[4]=45

60比a[mid]=45大,所以我们可以舍弃mid左边所有的数据,同时,left=mid+1即left=5,right不变

NueXini5

此时mid=(left+right)/2=(5+9)/2=7,a[mid]=a[7]=74

同理,60小于74,则right=mid-1=6,left不变

NueXini6

此时只剩下两个值,mid=(5+6)/2=5或6,mid等于哪个都没问题,a[mid]=a[6]=67,我们要找的值是60,那我们继续分析的话,则right=mid-1,那left=mid=right,假如我们要找的数是67,我们就找到了,返回true,可惜我们现在找的是60,在走下去,依旧得不到结果,这样做就没有意义了,所以要使它有意义就必须满足left<=right,这便是我们进行二分查找的循环条件~~!

5.源代码实现

#include<stdbool.h>
#include<stdio.h>

bool halfsort(int need_num, int num[], int num_length);

int main()
{
	int a[] = { 11,18,22,34,45,53,67,74,89,99 };
	int len = sizeof(a) / sizeof(a[0]);
	for (int i = 0; i < len; i++)
	{
		printf("正在检测[%d]:%d\n", a[i], halfsort(a[i], a, len));
	}
	
}

bool halfsort(int need_num, int num[], int num_length)
{
	bool ret = false;
	int left = 0;
	int right = num_length - 1;//计算出数组个数,数组中下标从0开始,需要-1
	while (left <= right)
	{
		//int mid = (left + right) / 2;
		int mid = left + (right - left) / 2;//防止溢出
		if (num[mid] == need_num) {
			ret = true;
			break;
		}
		else if ( need_num < num[mid]) {
			right = mid - 1;
		}
		else {
			left = mid + 1;
		}

	}
	return ret;
}

6.后话

分析原理的时候,可能说的有点乱,大概就是那样子,可以自己琢磨分析一下,enioy it~

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,这是一个学生信息管理系统的设计问题,需要用C语言实现。以下是我的回答: 1. 首先需要定义一个结构体来存储学生的信息,包括姓名、性别、学号和5门课程的期末考试成绩。可以按照以下方式定义结构体: ``` typedef struct { char name[20]; char gender[5]; int id; int scores[5]; float average; float total; } Student; ``` 其中,name和gender分别用char数组存储,id用int存储,scores用int数组存储5门课程的成绩,average和total分别用float存储平均成绩和总成绩。 2. 接下来需要生成50名学生的信息,包括姓名、性别、学号和5门课程的成绩。学号需要按照220101~220150的格式有序生成,姓名和性别可以在主程序中给定。可以利用rand()函数来生成成绩,代码如下: ``` srand((unsigned)time(NULL)); for (int i = 0; i < 50; i++) { Student stu; sprintf(stu.name, "Student%d", i + 1); strcpy(stu.gender, i % 2 == 0 ? "Male" : "Female"); stu.id = 220101 + i; for (int j = 0; j < 5; j++) { stu.scores[j] = rand() % 61 + 40; //成绩范围为40~100 stu.total += stu.scores[j]; } stu.average = stu.total / 5; students[i] = stu; } ``` 其中,students是一个Student类型的数组,用来存储所有学生的信息。 3. 实现根据学号查找学生的各个科目成绩,并输出该学生的姓名、学号、各科目成绩以及平均成绩。可以使用二分查找算法来实现,代码如下: ``` int binary_search(int id) { int left = 0, right = 49; while (left <= right) { int mid = (left + right) / 2; if (students[mid].id == id) { printf("Name: %s\n", students[mid].name); printf("ID: %d\n", students[mid].id); printf("Scores:"); for (int i = 0; i < 5; i++) { printf(" %d", students[mid].scores[i]); } printf("\n"); printf("Average: %.2f\n", students[mid].average); return 1; } else if (students[mid].id < id) { left = mid + 1; } else { right = mid - 1; } } printf("No student found with ID %d.\n", id); return 0; } ``` 4. 实现查找各个科目大于90分和小于60分的成绩,并输出相应的学生的姓名、学号和该科目成绩。可以使用线性查找算法来实现,代码如下: ``` void linear_search(int min, int max) { for (int i = 0; i < 50; i++) { for (int j = 0; j < 5; j++) { if (students[i].scores[j] >= min && students[i].scores[j] <= max) { printf("Name: %s\n", students[i].name); printf("ID: %d\n", students[i].id); printf("Score: %d\n", students[i].scores[j]); printf("\n"); break; } } } } ``` 其中,min和max分别表示要查找的成绩范围。 5. 实现根据总成绩对学生成绩进行从高到低排序,并依次输出姓名、学号、各科目成绩以及总成绩。可以使用冒泡排序算法来实现,代码如下: ``` void bubble_sort() { for (int i = 0; i < 49; i++) { for (int j = 0; j < 49 - i; j++) { if (students[j].total < students[j + 1].total) { Student temp = students[j]; students[j] = students[j + 1]; students[j + 1] = temp; } } } for (int i = 0; i < 50; i++) { printf("Name: %s\n", students[i].name); printf("ID: %d\n", students[i].id); printf("Scores:"); for (int j = 0; j < 5; j++) { printf(" %d", students[i].scores[j]); } printf("\n"); printf("Total: %.2f\n", students[i].total); printf("\n"); } } ``` 以上就是我的回答,其中查找功能1使用了二分查找算法,查找功能2使用了线性查找算法,排序功能使用了冒泡排序算法

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值