C语言:二分查找(折半查找),冒泡排序

目录

一、二分查找

二分查找的需注意的细节:

二、冒泡排序

 冒泡排序需注意的细节:


本篇博客详细讲解常用的几个方法,分别是二分查找和冒泡排序法

一、二分查找

二分查找,意思就是每次都分为两部分,将查找的数字和中间数字相比,判断大小后确定所查找数字在其中的一部分,接着在这部分数字中继续比较分为两部分查找,以此类推。

二分查找的运用比一个一个挨个找所需要的数字效率更高,但是需要注意的是:使用二分查找所满足的条件是必须是排序好的数组(本篇博客讲解的是顺序数组的二分查找法),否则无法运用二分查找。

下面是二分查找的代码部分:

int main()
{
	int arr[] = { 1,2,3,4,5,6,7,8,9,10 };
	int n = 8;
	int sz = sizeof(arr) / sizeof(arr[0]);
	int left = 0;
	int right = sz - 1;
	while (left <= right)
	{
		int mid = left + (right - left) / 2;
		if (arr[mid] < n)
		{
			left = mid + 1;
		}
		else if (arr[mid] > n)
		{
			right = mid - 1;
		}
		else
		{
			printf("找到所查找的数字,该数字下标是%d\n", mid);
			break;
		}
	}
	if (left > right)
	{
		printf("未找到该数字!\n");
	}
	return 0;
}

运行结果为下图:

C语言:二分查找(折半查找),冒泡排序_第1张图片

二分查找的需注意的细节:

1、int n = 8;

这里的n就是所查找的数字

2、int sz = sizeof(arr) / sizeof(arr[0]);

sz算的是数组中有几个元素

这里的sizeof(arr)就是算出整个数组的大小,sizeof(arr[0])算的是数组首元素的大小,用整个数组的大小除以数组首元素的大小,即算出数组中有几个元素

3、int left = 0;int right = sz - 1;

令数组首元素的下标是left,数组最后一个元素的下标为right,以便于后续的比较

4、int mid = left + (right - left) / 2;

mid就是所需比较的数字下标,至于为什么不int mid = (left + right)/2,是因为如果left和right数值很大,有可能  left+right  会造成溢出的情况,所以使用int mid = left + (right - left) / 2;

5、if (left > right) printf("未找到该数字!\n");

while循环中left<=right,若直到最后都没有找到数字,那么left就会mid+1超过right,所以若判断left>right成立,则说明没有找到所查找数字,打印出“未找到该数字”


二、冒泡排序

冒泡排序,其实就是从数组的第一个元素开始,与其相邻的元素进行比较,如果不满足顺序就调换,接着与下一个元素相比较,以此类推......

冒泡排序是为了使数组中元素形成升序排序,从而完成更多需求

下面是冒泡排序的代码:

void bubble_sort(int* arr, int sz)
{
	int i = 0;
	for (i = 0; i < sz - 1; i++)
	{
		int flag = 1;
		int j = 0;
		for (j = 0; j < sz - 1 - i; j++)
		{
			if (arr[j] > arr[j + 1])
			{
				flag = 0;
				int tmp = arr[j];
				arr[j] = arr[j + 1];
				arr[j + 1] = tmp;
			}
		}
		if (flag == 1)
		{
			break;
		}
	}
}

int main()
{
	int arr[] = { 9,8,7,6,5,4,3,2,1,0 };
	int sz = sizeof(arr) / sizeof(arr[0]);

	bubble_sort(arr, sz);

	int i = 0;
	for (i = 0; i < sz; i++)
	{
		printf("%d ", arr[i]);
	}
	return 0;
}

运行结果如下图:

C语言:二分查找(折半查找),冒泡排序_第2张图片

 冒泡排序需注意的细节:

1、int sz = sizeof(arr) / sizeof(arr[0]);

main函数中的这行代码和二分查找一样,都是计算数组中的元素个数

2、bubble_sort(arr, sz);

创建一个bubble_sort函数进行冒泡排序的具体操作,并传入数组首元素的地址arr,以及数组元素个数sz

3、void bubble_sort(int* arr, int sz)

int* arr是为了接受main函数中传入的arr,即数组首元素的地址,用整型指针int*接收

int sz就是接收main函数中所传入的数组元素个数

4、for (i = 0; i < sz - 1; i++)

首先对于第一个for循环,是针对总共需要循环几趟

至于为什么是循环sz-1次,因为比如说3个元素,第一趟是第一个元素和另外两个元素相比较,第二趟是第二元素和第三个元素比较,第三个元素已经不需要比较了,所以3个元素只需要循环2趟,以此类推,sz个元素需要循环sz-1趟

5、for (j = 0; j < sz - 1 - i; j++)

对于第二个for循环,是针对于每趟循环所需要的次数

为什么是循环sz - 1 - i次呢,因为因为本来是每个元素都比较sz-1次,但是这样会导致重复比较,第一个元素和后面的所有元素比较后,后面元素比较时就不需要再和第一个元素比较了,因此每趟循环次数除了sz-1这个正常的顺序外,再减去i即前面已经比较过的元素个数,就是每趟所需要比较的次数sz-1-i

6、

C语言:二分查找(折半查找),冒泡排序_第3张图片

这几行代码很好理解,若不满足顺序排序,令flag = 0;接着创建临时变量tmp,完成下标j和下标为j+1元素的调换 

7、if (flag == 1) break;

这里的flag变量是为提升效率,主要是为了防止一个数组中元素本来就是顺序排序,但是却还是进行两次循环,费时费力,那么具体是怎么提升的呢?

在第一个for循环中定义了int flag = 1;在进行第二个for循环的第一次循环后,若flag仍然是1,就说明整个数组元素本身就符合顺序排序,因此,break跳出第一个for循环,整个循环结束,从而提高效率

若发生调换就说明该数组中元素并不是顺序排序,那么就将flag变为0,下方的if语句直接忽略即可,进行正常的冒泡排序即可。


本篇博客到此结束啦,如果对相关内容比较感兴趣的小伙伴,可以关注我的其他博客呦♪(^∇^*) 

你可能感兴趣的:(C语言,c语言,排序算法,算法)