【C语言】选择排序、冒泡排序、二分查找、插入排序的详解

1、排序:(在c语言中很重要)

排序,字面意思就是按照一定的顺序排列,一般分为两种:
1、从小到大;(升序)
2、从大到小;(降序)

c语言中主要介绍四个排序:
1、选择排序;
2、冒泡排序;
3、插入排序;
4、快速排序;

1、选择排序:(先统一写升序排列)

1、依靠算法,算法主要是数学逻辑;所以我们要了解算法思想,掌握c语言如何实现、选择和应用;
2、选择排序基本思想:给合适位置选择合适的数;
思考过程:首先先假设一个最小值,设为min,假设min = a[0],从最开始进行比较,假定数组的长度为len,所以数组对应的下标的最大值为len - 1,从a[0]往后依次比较,因为a【0】作为已经作为比较数,所以他一共可以跟数组的数比较len - 1次,依次比较过程中,如果接下来的数比他小,就进行交换(需要定义一个中间值进行存储),依次比较到数组最后一个数字,然后结束循环,此时a【0】中就会存下比较完过后的最小值,然后就开启下次循环,在下次循环过程中,因为a【0】的值已经确定是最小值,所以需要固定住,于是第二次循环从a【1】开始,并且循环的次数也会少一次;所以用两个循环,小的用来记录进行一次排序的操作,一次可以排出一个数,大的用来控制排序次数,即排好的数的个数;

1、1基本用法举例:
将下列数组按升序排列:

#include

int main(void)
{
	int a[] = {7,5,4,3,6,0,1,2}; // 定义一个数组
	int i,j,temp;
	int len = sizeof(a)/sizeof(a[0]);  //求出数组的长度

	for(i = 0; i a[j] ) //进行判断,一次循环中a[i]的值不动,一直跟变化的a[j]比。
			{
				temp = a[i];  //判断成立就交换位置
				a[i] = a[j];
				a[j] = temp;

			}
		}
	}

	for(j = 0; j < len ; j++) //从0  - len-1打印出来
	{
		printf("%d",a[j]);
	}

	return 0;

}

2、冒泡排序

1、基本过程:类小气泡,一次冒出一个数,相邻两个元素两两比较,小的放前,大的放后;
 

2、思想:首先,研究数学关系,假设长度为n的一个数组,第一次比较,从a【0】开始,即从第一个数开始,一共比较n-1次,最后一个值就是最大的了,然后结束循环,次数是n-1;第二次依然从a【0】,即第一个数开始,由于最后一个数已经固定,所以次数会再少一次,为n--1-1,然后结束循环;第三次依然从a【0】开始,由于后面两个数已经有顺序,固定了,所以循环顺序又少一次,即为n -1 -1 -1;……,由于排第一次的规律已经出现,所以只需要再套一个循环然后控制循环次数就好,外循环为len-1次。循环到a【len-1-1】。

3、基本流程图解:
【C语言】选择排序、冒泡排序、二分查找、插入排序的详解_第1张图片

2.1基本用法举例:
定义一个数组,用冒泡法实现升序排列:

#include

int main(void)
{
	int a[] = {8,7,6,5,4,3,2,1}; //定义数组
	int i,j,temp;
	int len  = sizeof(a) / sizeof(a[0]); //求出数组长度

	for(i = 0; i < len - 1 ;i++)  // 控制循环次数 
	{
		for(j = 0; j< len - i - 1 ; j++ )
		{
			if(a[j] > a[j+1]) // 前面的数比后面的数大,所以交换
			{
				temp = a[j+1];
				a[j+1] = a[j];
				a[j] = temp;

			}
		}
	}
	for(j=0;j

3、插入排序:

1、例子:军训,行列,一个人,不排序,加入一个人,排序;
2、思想:在有序序列中,找到合适的位置插入;
过程:为了方便理解,以两个数组为例,首先准备两个数组,分别为a【i】,a【j】;从a中取出a【0】 = b【0】;第一个数不用判断,直接令a【0】=b【0】,放进去就行,此时i=j;第二个数a【1】,预备存进b【1】,但是需要跟b数组中的b【0】比大小,如果比b【0】大,直接存,如果比b【0】还小,需要存进b【0】的位置,所以先取出a【1】,存进一个中间量t中,先不放进b数组中,t = a【1】,判断完后,若t b【j-1】,要放的数比前一个数大了,不需要比较了,循环结束。所以用while语句,while(j>0 && t< b【j -1】),这个时候循环继续,循环内语句应该为:b【j】=b【j-1】;--j(每次需要往前比,--j是使循环趋于结束的条件,也是循环动起来的条件,因为每次都需要往前比,j的数在减小)意思就是如果要放进的数据比前一个数据小,就把前一个数据挪到前面去,不用担心覆盖问题,因为j = i,并且t = a【i】,数据是已经存在t中,b【j】的位置相当于空的,随便放数据。挪空位就行;
进阶:在a数组上直接操作:原地插入,与非原地插入代码差距不大,就是把b改成a,再将输出改为a【j】输出;

3.1基本应用举例:
定义一个数组,用插入排序方法实现升序排列: 

#include

int main()
{
	int a[] = {3,6,5,7,8};
	int len = sizeof(a)/sizeof(a[0]);
	int b[len];
	int t,i,j;
	i = len ;


	for(i=1;i 0 && t < a[j-1])  //排序一次的循环的条件
			{
				a[j] = a[j-1];     // 循环体语句
				--j;		//使循环趋于结束的操作,也是使循环动起来的操作
			}
		a[j] = t; //比较完后,a[i]给a[j]
	}

	for(j = 0;j

4、二分查找:(折半查找)

1、大前提:数据需要有序;
2、思想:找到中间位置的数,在数组里面用下标表示,拿这个数和要找的数进行比较;记下mid为中间值,begin和end为起始位置和结束位置,定义mid = (begin + end)/2

4.1基本用法举例:
打印出6在数组中所在的位置:

#include

int main(void)
{
	int a[8] = {1,2,3,4,5,6,7,8};

	int begin,end,mid;
	int b = 6;

		begin = 0;
		end = 7;

	while(begin<=end)
	{
		mid =(begin+end)/2;

	if(a[mid] >b )
	{
		end = mid - 1;
	}else if(a[mid] begin)
	{
			printf("a[%d]",mid);
	}else
		printf("error\n");

		return 0;
}

你可能感兴趣的:(c语言,开发语言)