排序与查找
排序——选择,冒泡
查找——顺序,二分查找法
1.选择排序
从第一个数开始,每次与后面的数比较找出最大值,将这个最大值放在当前位置,当前位置的数的值放在最大值所在位置,依次循环直到循环到最后一个数。
例题:输入一个正整数n(1<n<=9),在输入n个正数,用选择法将它们从小到大排序后输出。
#include<stdio.h> #define MAXN 10 int main() { int i,index,k,n,temp; int a[MAXN]; scanf("%d",&n); for(i=0;i<n;i++){ scanf("%d",&a[i]); } //对n个数排序 for(k=0;k<n-1;k++){ index=k; //index用于存放最小值所在下标 for(i=k+1;i<n;i++){ //寻找最小值下标 if(a[i]<a[index]) index=i; } temp=a[index]; //最小值与a[k] 的元素交换,把最小值换到当前位置,把当前位置的数放在最小值数原本的位置上 a[index]=a[k]; a[i]=temp; } //输出排序后的数组 for(i=1;i<n;i++){ printf("%d",a[i]); } printf("\n"); return 0; }
2.冒泡排序
进行多次循环,每次将相邻两个数比较,在升序排列是,将大的数放到后面。 就像气泡,较大的数下沉,较小的数冒起来。
例题:
#include <stdio.h> int main(void) { int a[1001]; int n,i,j,t; scanf("%d",&n);//n为要排序的数的个数 //输入要排序的数 for(i=0;i<n;++i) scanf("%d",a+i); //接下来进行排序 for(i=0;i<n-1;++i)//n个数,总共需要进行n-1次 { //n-1个数排完,第一个数一定已经归位 //每次会将最大(升序)或最小(降序)放到最后面 for(j=0;j<n-i-1;++j) { if(a[j]>a[j+1])//每次冒泡,进行交换 { t=a[j]; a[j]=a[j+1]; a[j+1]=t; } } for(j=0;j<n;++j) printf("%-5d ",a[j]); printf("\n\n"); } return 0; }
优化:在排序过程中,执行完最后的排序后,虽然数据已全部排序完备,但程序无法判断是否完成排序,为了解决这一不足,可设置一个标志位flag,将其初始值设置为非0,表示被排序的表是一个无序的表,每一次排序开始前设置flag值为0,在进行数据交换时,修改flag为非0。在新一轮排序开始时,检查此标志,若此标志为1,表示上一次没有做过交换数据,表明有序;若排序的过程中,序列已变为有序,则不会进行冒泡,否则进行排序。
代码如下:
for(i=0;i<n-1;++i)//n个数,总共需要进行n-1次 { //n-1个数排完,第一个数一定已经归位 //每次会将最大(升序)或最小(降序)放到最后面 int f=1;//这里设置一个开关变量 for(j=0;j<n-i-1;++j) { if(a[j]>a[j+1]) { t=a[j]; a[j]=a[j+1]; a[j+1]=t; f=0; } } if(1==f)//f为1说明没进行过冒泡,说明序列有序 break;//若序列有序,则跳出排序即可 }
1.顺序查找
顺序查找法是指从头到尾逐个查找。
例题代码:
#include<stdio.h> int main() { int n,x,flag,i; int a[10]; scanf("%d%d",&n,&x); for( i=0;i<n;i++){ scanf("%d",&a[i]); } //查找 flag=0; //设置flag做标志 for(i=0;i<n;i++){ if(a[i]==x){ printf("Idex is %d\n",i); //找到x,则输出下标 flag=1; //置flag为1,表示找到x } } if(flag==0){ printf("No Found"); //flag为0,说明没有找到x } return 0; }
2.二分查找
作为二分查找对象的表必须是顺序存储的有序表。查找过程是首先取整个有序表 A[0] ~ A[n - 1] 的中点元素 A[mid] (mid = (0 + n -1) / 2) 的关键字同给定值 K 比较,相等则查找成功,若 K 较小,则对剩余的左半部分进行同样操作,若 K 较大,则对其剩余的右半部分进行同样的操作。
有两种:非递归与递归
代码一:非递归函数部分
int Binary_search(int low,int high,int n) { int mid; while(low<=high){ mid=(low+high)/2; if(n==a[mid]){ break; }else if(n<a[mid]){ high=mid-1; }else if(n>a[mid]){ low=mid+1; } } if(low<=high) return mid; //返回查找数所在下标 else return -1; //没找到
代码二:递归函数部分
int Binary_search_recursive(int *s,int length,int key,int L,int H) { int M=(L+H)/2; if(L>H) return -1; //没找到 if(key<s[M]) { return (Binary_search_recursive(s,length,key,L,M-1)); } else if(key>s[M]) { return (Binary_search_recursive(s,length,key,M+1,H)); } else return (M); //M即查找数 }
优点:循环次数更少,程序运行效率更高。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· DeepSeek 开源周回顾「GitHub 热点速览」
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了