百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 热门文章 > 正文

关于c语言中的二分查找,冒泡,快排,选择排序和归并

bigegpt 2024-08-16 14:19 2 浏览

二分查找

二分查找又称为折半查找,这种查找方法查找速度快,但是要求线性表必须采用顺序存储结构。
下面就以十个整数数组中查找关键数字,并且输出其所在数组的下标。(假设这个数组中关键字只出现过一次)完整代码如下:

#include<stdio.h>
int main(){
int mid,low=1,high=10;
int i,a[10],key;
printf("请输入要查找的数字:");
scanf("%d",&key);
printf("请输入10个整数:");
for(int i=1;i<=10;i++)
scanf("%d",&a[i]);
while(low<=high){
mid=low+(high-low)/2;
if(a[mid]>key)
high=mid;
if(a[mid]<key)
low=mid;
if(a[mid]==key){
printf("%d",mid);
break;
}
}
return 0;
}
//二分查找的实现,先确定每次数组的最高处下标和最低处下标,把关键数与两者中间值下标进行比较,确定新的low和high值
//二分查找算法结束的条件是,low大于high

注意二分查找中有一步是mid=(low+high)/2;这种运算方式如果是在非常的数组中使用,会导致设定的int型mid值溢出而导致程序运行失败,使用mid=low+(high-low)/2;就可尽可能避开这样的问题。文章举的例子非常特殊,真正使用还需要更多的考虑。

冒泡法排序

冒泡法排序名字的由来是因为越大的元素会经由交换慢慢“浮”到数列的顶端(升序或降序排列),就如同碳酸饮料中二氧化碳的气泡最终会上浮到顶端一样。

冒泡法的实现就是从简单的两个数字组合开始进行升序或者降序排序,然后不断加上数组的后一位数字,再对新产生的数组重新进行一次排序,依次类推。

#include<stdio.h>
int main()//冒泡法升序排序 
{
	int a[10]={3,46,8,22,6,43,1,23,9,12};
	int i,j,t;
	for(i=0;i<10;i++)
	for(j=0;j<9-i;j++)
	{
		if(a[j+1]<a[j])
		{
		t=a[j+1];
		a[j+1]=a[j];
		a[j]=t;
		}
	}
	for(i=0;i<=10;i++)
	printf("%d  ",a[i]); 
	return 0;
}

快速排序 <快排>

快速排序是冒泡法排序的改进。快速排序的第一趟排序是把数据分成独立分割的两部分,然后再分别对两部分的数据再进行快速排序。换个说法,快排就是先选择一个数组中的一个数字,然后创建左右两个指向从左右两边尽头开始,依次加一向中间靠拢,如果在左边找到一个需要交换到右边的数,在右边找到一个需要交换到左边的数,就进行数字的左右交换。当左右两边指向重合结束第一趟循环,再单独对左右两边的数进行以上操作,直到左指向指向右指向初始,右指向指向左指向的初始。

当然快速排序的具体实现还有其他大同小异的算法思想,有想法的可以补充在评论区。

 #include<stdio.h>
int a[10];//把数组作为全局变量 
void sort(int l,int r)
{
	int temp,mid,j,i;
	j=l;	i=r;
	mid=a[(j+i)/2];//选择中间的某个值是用来比较的关键数据 
	do{
		while(mid>a[j])		j++;//找到中间数值左边第一个比关键数字大的数 
		while(mid<a[i])		i--;//找到中间数值右边第一个比关键数字小的数 
		if(j<=i){       //如果数组下标还符合则把两数进行交换 
			temp=a[i];
			a[i]=a[j];
			a[j]=temp;
			j++;i--;//左右两边都向中间靠拢,直到两者数值重合 
		}
	}while(j<=i);//当左右两边的指向重合的时候结束循环 
	if(j<r) 	sort(j,r);//对关键数字的左边数列进行排序 
	if(i>l)		sort(l,i);//对关键数字的右边数列进行排序 
}
int main()
{
	int i;
	printf("请输入十个正整数:");
	for(i=1;i<=10;i++)
	scanf("%d",&a[i]);
	sort(1,10);
	for(i=1;i<=10;i++)
	printf("%d ",a[i]); 
	return 0;
}

选择排序

选择法排序有点类似于冒泡法排序,都是进行了n-1次排序。先初始最小值下标位置,通过选择数组内最小或者最大的数来进行交换,最终实现升序或降序排序。

#include<stdio.h>
int main()//选择法排序的升序排序
{
	int min,j,i,n;
	int t;
	int a[]={3,46,8,22,6,43,1,23,9,12}; 
	n=sizeof(a)/sizeof(a[0]);//计算数组的长度 
	for(i=0;i<n-1;i++)       //外循环 
	{
		min=i;              //初始最小的值下标
		for(j=i+1;j<n;j++)   //内循环实现选择一定数组中大的或者是小的数放在最左边i的位置上 
		{
			if(a[min]>a[j])
			min=j;
		}
		if(min!=i)//判断i和最小值的下标是否相同 ,不同则交换两个数 
		{
			t=a[min];
			a[min]=a[i];
			a[i]=t;
		}
	}
	for(i=0;i<10;i++)
	printf("%d ",a[i]);
	return 0;
}

归并法排序

归并法排序是分治思想的典范,首先将n个元素分为含n/2个元素的子序列,使用归并排序法实现子序列的递归排序,可以把整个原序列分为n个子序列,最后合并两个排好序的序列。

#include<stdio.h>
#include<stdlib.h>
void merge(int a[],int low,int mid,int high)
{
	int *tmp=(int*)malloc((high-low+1)*sizeof(int));
	int left_low=low;//左边序列的起始点 
	int left_high=mid;//左边序列的终点 
	int right_low=mid+1;//右边序列的起始点 
	int right_high=high;//右边序列的终点 
	int k,i;
	//两个部分的数据依次比较大小,“合” 
	for(k=0;left_low<=left_high &&right_low<=right_high;k++){
	if(a[left_low]<=a[right_low])
	{
	tmp[k]=a[left_low++];
    }
	else
	{
	tmp[k]=a[right_low++];
    }
    }
    //判断左右两侧数据是否有剩余,如果有,则直接复制粘贴在排列好的数组后面 
	if(left_low<=left_high)//左边序列有剩余 
	{
	for(i=left_low;i<=left_high;i++)
	tmp[k++]=a[i];
   }
	if(right_low<=right_high)//右边序列有剩余 
	{
		for(i=right_low;i<=right_high;i++)
		tmp[k++]=a[i];
	}
	for(i=0;i<high-low+1;i++)//把排序好的序列重新放回原数组中 
	a[low+i]=tmp[i];
	free(tmp);
	return ;
}
void mergesort(int a[],unsigned int first,unsigned int last)
{
	int mid;
	if(first<last)//把数据不断对半分,大致是“分”的思想 
	{
		mid=(first+last)/2;
		mergesort(a,first,mid);
		mergesort(a,mid+1,last);
		merge(a,first,mid,last);
	}
	return;
}
int main()
{
	int i;
	int a[10]={3,46,8,22,6,43,1,23,9,12}; 
	mergesort(a,0,9);
	for(i=0;i<10;i++)
	printf("%d ",a[i]);
	return 0;
 } 

相关推荐

了解Linux目录,那你就了解了一半的Linux系统

大到公司或者社群再小到个人要利用Linux来开发产品的人实在是多如牛毛,每个人都用自己的标准来配置文件或者设置目录,那么未来的Linux则就是一团乱麻,也对管理造成许多麻烦。后来,就有所谓的FHS(F...

Linux命令,这些操作要注意!(linux命令?)

刚玩Linux的人总觉得自己在演黑客电影,直到手滑输错命令把公司服务器删库,这才发现命令行根本不是随便乱用的,而是“生死簿”。今天直接上干货,告诉你哪些命令用好了封神!喜欢的一键三连,谢谢观众老爷!!...

Linux 命令速查手册:这 30 个高频指令,拯救 90% 的运维小白!

在Linux系统的世界里,命令行是强大的武器。对于运维小白而言,掌握一些高频使用的Linux命令,能极大提升工作效率,轻松应对各种系统管理任务。今天,就为大家奉上精心整理的30个Linu...

linux必学的60个命令(linux必学的20个命令)

以下是Linux必学的20个基础命令:1.cd:切换目录2.ls:列出文件和目录3.mkdir:创建目录4.rm:删除文件或目录5.cp:复制文件或目录6.mv:移动/重命名文件或目录7....

提高工作效率的--Linux常用命令,能够决解95%以上的问题

点击上方关注,第一时间接受干货转发,点赞,收藏,不如一次关注评论区第一条注意查看回复:Linux命令获取linux常用命令大全pdf+Linux命令行大全pdf为什么要学习Linux命令?1、因为Li...

15 个实用 Linux 命令(linux命令用法及举例)

Linux命令行是系统管理员、开发者和技术爱好者的强大工具。掌握实用命令不仅能提高效率,还能解锁Linux系统的无限潜力,本文将深入介绍15个实用Linux命令。ls-列出目录内容l...

Linux 常用命令集合(linux常用命令全集)

系统信息arch显示机器的处理器架构(1)uname-m显示机器的处理器架构(2)uname-r显示正在使用的内核版本dmidecode-q显示硬件系统部件-(SMBIOS/DM...

Linux的常用命令就是记不住,怎么办?

1.帮助命令1.1help命令#语法格式:命令--help#作用:查看某个命令的帮助信息#示例:#ls--help查看ls命令的帮助信息#netst...

Linux常用文件操作命令(linux常用文件操作命令有哪些)

ls命令在Linux维护工作中,经常使用ls这个命令,这是最基本的命令,来写几条常用的ls命令。先来查看一下使用的ls版本#ls--versionls(GNUcoreutils)8.4...

Linux 常用命令(linux常用命令)

日志排查类操作命令查看日志cat/var/log/messages、tail-fxxx.log搜索关键词grep"error"xxx.log多条件过滤`grep-E&#...

简单粗暴收藏版:Linux常用命令大汇总

号主:老杨丨11年资深网络工程师,更多网工提升干货,请关注公众号:网络工程师俱乐部下午好,我的网工朋友在Linux系统中,命令行界面(CLI)是管理员和开发人员最常用的工具之一。通过命令行,用户可...

「Linux」linux常用基本命令(linux常用基本命令和用法)

Linux中许多常用命令是必须掌握的,这里将我学linux入门时学的一些常用的基本命令分享给大家一下,希望可以帮助你们。总结送免费学习资料(包含视频、技术学习路线图谱、文档等)1、显示日期的指令:d...

Linux的常用命令就是记不住,怎么办?于是推出了这套教程

1.帮助命令1.1help命令#语法格式:命令--help#作用:查看某个命令的帮助信息#示例:#ls--help查看ls命令的帮助信息#netst...

Linux的30个常用命令汇总,运维大神必掌握技能!

以下是Linux系统中最常用的30个命令,精简版覆盖日常操作核心需求,适合快速掌握:一、文件/目录操作1.`ls`-列出目录内容`ls-l`(详细信息)|`ls-a`(显示隐藏文件)...

Linux/Unix 系统中非常常用的命令

Linux/Unix系统中非常常用的命令,它们是进行文件操作、文本处理、权限管理等任务的基础。下面是对这些命令的简要说明:**文件操作类:*****`ls`(list):**列出目录内容,显...