这周学习了一维数组,内容可分为下列几个部分
1.数组定义:变量类型 数组名[数组长度]
2.经典算法:(1)选择排序法
(2)冒泡排序法
(3)数组移位
(4)哈希数组统计点赞,查找重复值
(5)二分查找法
(1)选择排序法(升序或降序)
思路:将一组无序数按从大到小(从小到大)的顺序排列
代码实现:
#include<stdio.h> #define MAXN 20 int main(){ int n; scanf("%d",&n); int i,a[MAXN]; for(i=0;i<n;i++){ scanf("%d",&a[i]); } int k,index; for(k=0;k<n-1;k++){ index=k; for(i=k+1;i<n;i++){//每一个数与后面的所有数比较 if(a[i]<a[index]){ index=i; } } int temp=a[index];//中间交换 t=a,a=b,b=t a[index]=a[k]; a[k]=temp; } for(i=0;i<n;i++){ printf("%d ",a[i]); } return 0; }
(2)冒泡排序
思路:相邻两数之间交换(升序降序)
过程图解示例(取自B站)
升序示例:每一趟比较两个相邻数的大下,如果前一个数位大于后一个数则交换位置
经过上一步数组中最大的数已经沉到了最低端,下一趟的比较就可以减少一次(5 12 6 2 23)
......以此类推 (2 5 6 12 23)
代码实现:
#include<stdio.h> #define MAXN 20 int main(){ int n; scanf("%d",&n); int i,a[MAXN]; for(i=0;i<n;i++){ scanf("%d",&a[i]); } int j; for(i=0;i<n-1;i++){ for(j=0;j<n-1-i;j++){//每进行一趟下一次要比较的次数就减少一次 if(a[j]>a[j+1]){ int temp=a[j]; a[j]=a[j+1]; a[j+1]=temp; } } } for(i=0;i<n;i++){ printf("%d ",a[i]); } return 0; }
(3)数组移位:
#include<stdio.h> #define MAXN 20 void shift(int n,int a[],int m); int main(){ int n; scanf("%d",&n); int i,a[MAXN]; for(i=0;i<n;i++){ scanf("%d",&a[i]); } int m; scanf("%d",&m);//移动次数 shift(n,a,m); for(i=0;i<n;i++){ printf("%d ",a[i]); } return 0; } void shift(int n,int a[],int m){ int i; int k,temp; for(k=0;k<m;k++){ temp=a[0]; //因为循环开始的第一步将a[1]赋给a[0],a[0]的值被更改,需要对a[0]做特殊处理 for(i=0;i<n;i++){ a[i]=a[i+1]; } a[n-1]=temp; } }
(4)数组统计点赞:(以pta上的题为例)
代码实现:
#include<stdio.h> #define MAXN 20 int main(){ int n; scanf("%d",&n); int i; int date; int b[10]={0};// for(i=0;i<n;i++){ scanf("%d",&date);//将投票情况作为下标统计计数 b[date]++; } for(i=1;i<=8;i++){ printf("%d %d\n",i,b[i]); } return 0; }
类似于哈希数组的做法:
要点:新构建的数组要先初始化
优点:不用一个一个去计算相加,减少了复杂性
缺点:对于输入的数较大时无法确定新构建的数组的范围,且在pta上容易出现段错误
(5)二分查找法:
(限于有序数组,对于无序数组要先进行排序)
代码实现:
#include<stdio.h> #define MAXN 20 int search(int n,int a[],int x); int main(){ int n,x; scanf("%d %d",&n,&x); int a[MAXN],i; for(i=0;i<n;i++){ scanf("%d",&a[i]); } int result=search(n,a,x); if(result==-1){ printf("not found"); } else printf("%d",result); return 0; } int search(int n,int a[],int x){ int left=0; int right=n-1; int result=-1; while(left<=right){ int mid=(left+right)/2; if(a[mid]==x){ result=mid; break; } else if(a[mid]<x){ left=mid+1; } else{ right=mid-1; } } return result; }
要点:找出跳出循环的条件
以上代码测试用例较少,可能会出现错误,欢迎指正
总结:对数组的经典算法理解透彻,就可以举一反三,一道题的做法可以变形运用到另一题上,但pta上的题总是会扣掉一两分,代码还要更严谨一些。