這周學習了一維數組,內容可分為下列幾個部分
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上的題總是會扣掉一兩分,代碼還要更嚴謹一些。
