一维数组学习总结

这周学习了一维数组,内容可分为下列几个部分

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上的题总是会扣掉一两分,代码还要更严谨一些。

posted @ 2021-10-31 11:42  zhuhaizhuang  阅读(366)  评论(0编辑  收藏  举报