排序和查找

排序和查找

1. 排序算法介紹

  • 排序也稱排序算法,排序是將一組數據,依指定的順序進行排列的過程
  • 排序的分類
    • 內部排序:指將須要處理的全部數據都加載到內部存儲器(內存)中進行排序
    • 外部排序:數據量過大,沒法所有加載到內存中,須要藉助外部存儲器進行排序

2. 冒泡排序

2.1 基本介紹

  • 冒泡排序的基本思想是:經過對待排序序列從前向後(從下標較小的元素開始),依次比較相鄰元素的值,若發現逆序則交換,使值較大的元素從前移向後部,就像水底的氣泡同樣逐漸向上冒。
  • 由於排序的過程當中,各元素不斷接近本身的位置,若是一趟比較下來沒有進行過交換,就說明序列有序,所以要在排序過程當中設置一個標誌flag判斷元素是否進行過交換,從而減小沒必要要的比較

2.2 案例

  • 將五個無序 的數:{3,9,-1,10,-2}使用冒泡排序法將其排成一個從小到大的有序數列

2.3 分析冒泡的過程+代碼

//冒泡排序的過程(從小到大)
原始數組{3,9,-1,10,-2}

第一輪
    1.3,9,-1,10,2
    2.3,-1,9,10,2
    3.3,-1,9,10,2
    4.3,-1,9,-2,10
    //第一大的數就移動到最後
第二輪
    1.-1,3,9,-2,10
    2.-1,3,9,-2,10
    3.-1,3,-2,9,10
第三輪
    1.-1,3,-2,9,10
    2.-1,-2,3,9,10
 第四輪
    -2,-1,3,9,10
#include<stdio.h>
//冒泡排序函數
void bubbleSort(int arr[],int arrLen){
    //由於每輪排序幾乎同樣,所以,可使用for循環處理
    int i,j;
    int t;//臨時變量
    for(i=0;i<arrLen-1;i++){
        for(j=0;j<arrLen-1-i;j++){
        //若是前面的數大於後面的數,就交換
        if(arr[j]>arr[j+1]){
            t=arr[j];
            arr[j]=arr[j+1];
            arr[j+1]=t;
        }
        }
    }
}
void main(){
    int arr[]={3,9,-1,10,-2,11};
    int arrLen=sizeof(arr)/sizeof(int);
    int j;
    bubbleSort(arr,arrLen);//數組默認是地址傳遞
    printf("排序後");
    for(j=0;j<arrLen;j++){
        printf("%d",arr[j]);
    }
    getchar();
}

3. 查找

3.1 介紹

在C中,經常使用的查找有兩種算法

  • 順序查找
  • 二分查找

3.2 案例演示

  • 有一個數列{23,1,34,89,101}
  • 猜數遊戲:從鍵盤任意輸入一個數,判斷數列中是否包含該數[順序查找]
  • 要求:若是找到了,就提示找到,並給出下標值,找不到提示沒有
#include<stdio.h>
int seqSearch(int arr[],int arrLen,int val){
    int i;
    for(i=0;i<arrLen;i++){
        if(arr[i]==val){
            return i;
        }
    }
    //若是在for循環中,沒有執行到return,說明沒有找到
    return -1;
}

void main(){
    int arr[]={23,1,34,89,101};
    int arrLen=sizeof(arr)/sizeof(int);
    int index=seqSearch(arr,arrLen,-101);
    if(index != -1){
        printf("找到 下標爲%d",index);
    }else{
        printf("沒有找到");
    }
    getchar();
}
  • 請對一個有序數組進行二分查找{1,8,10,89,100,123},輸入一個數看看該數組是否存在此數,而且求出下標,若是沒有就提示「沒有這個數」
  • 二分查找的前提是該數組是一個有序數組
#include<stdio.h>
//二分查找
int binarySearch(int arr[],int leftIndex,int rightIndex,int findVAL){
    //先找到數組中間這個數midVal
    int midIndex=(leftIndex+rightIndex)/2;
    int midVal=arr[midIndex];
    //若是leftIndex>rightIndex,說明這個數組都比較過,可是沒有找到
    if(leftIndex>rightIndex){
        return -1;
    }
    //若是midVal>findVal說明,應該在midVal的左邊查找
    if(midVal>findVal){
        binarySearch(arr,leftIndex,midIndex-1,findVal);
    }else if(midVal<findVal){
        //若是midVal<findVal說明,應該在midVal的右邊查找
        binarySearch(arr,midIndex+1,rightIndex,findVal);
    }else{
        return midIndex;
    }
}

void main(){
    //分析
    //好比要查找的數是findVal
    //1.先找到數組中間這個數midVal,和findVal比較
    //2.若是midVal>findVal說明,應該在midVal的左邊查找
    //3.若是midVal<findVal說明,應該在midVal的右邊查找
    //4.若是midVal==findVal,說明找到
    int arr[]={1,8,10,89,1000,1234};
    int arrLen=sizeof(arr)/sizeof(int);
    int index=binarySearch(arr,0,arrLen-1,-1000);
    if(index!=-1){
        printf("找到index=%d",index);
    }else{
        printf("沒有找到");
    }
    getchar();
}

4.多維數組和二維數組

多維數組主要介紹二維數組數組

5. 二維數組的應用場景

好比開發一個五子棋遊戲,棋盤就是須要二維數組來表示函數

6.二維數組的使用

6.1 快速入門

請用二維數組輸出以下圖形佈局

0 0 0 0 0 0code

0 0 1 0 0 0排序

0 2 0 3 0 0遊戲

0 0 0 0 0 0內存

6.2 使用方式1:先定義再初始化

語法:類型 數組名[大小 ] [大小]開發

好比:int a[2] [3]get

6.3 使用演示

二維數組在內存的存在形式,各個元素的地址是連續分佈的,即在前一個元素基礎上加+4

#include<stdio.h>
void main(){
    //a[4][6];表示一個4行6列的二維數組
    int a[4][6];//沒有初始化,則是分配的內存垃圾值
    
    int i,j;
    //所有初始化爲0
    for(i=0;i<4;i++){
        for(j=0;j<6;j++){
            a[i][j]=0;
        }
    }
    a[1][2]=1;
    a[2][1]=2;
    a[2][3]=3;
    //輸出二維數組
    for(i=0;i<4;i++){
        for(j=0;j<6;j++){
            printf("%d",a[i][j]);
        }
        printf("\n");
    }
    //看看二維數組的內存佈局
    printf("二維數組a的首地址=%p",a);
    printf("二維數組a[0]的地址=%p",a[0]);
    printf("二維數組a[0][0]的地址=%p",&a[0][0]);
    printf("二維數組a[0][1]的地址=%p",&a[0][1]);
    //將二維數組的各個元素的地址輸出
    printf("\n");
    for(i=0;i<4;i++){
        printf("a[%d]的地址=%p",i,a[i]);
        for(j=0;j<6;j++){
            printf("a[%d][%d]的地址=%p",i,j,&a[i][j]);
        }
        printf("\n");
    }
    getchar();
}

6.4 使用方式2:直接初始化

  • 定義 類型 數組名【大小】【大小】={{值1,值2....},{值1,值2....}};
  • 或者 類型 數組名 【大小】【大小】 ={值1,值2,值3,值4,值5,值6...};
    • 會自動匹配到各行各列

7.二維數組應用案例

7.1 案例1

  • 請使用靈活的方式遍歷以下數組
  • int map[3] [3]={{0,0,1},{1,1,1}{1,1,3}};

7.2 案例2

int arr[3] [2]={{4,6},{1,4},{-2,8}};

遍歷該二維數組,並獲得和

#include <stdio.h>
void main(){
    int map[3][3]={{0,0,1},{1,1,1},{1,1,3}};
    //遍歷
    //先獲得行
    //1.sizeof(map) 獲得這個map數組的大小9*4=36
    //2.sizeof(map[0])獲得map中,第一行有多大3*4=12
    int rows=sizeof(map)/sizeof(map[0]);
    //printf("rows=%d",rows);
    //獲得列
    int cols=sizeof(map[0])/sizeof(int);
    int i,j,sum=0;
    for(i=0;i<rows;i++){
        for(j=0;j<cols;j++){
            printf("%d",map[i][j]);
            sum+=map[i][j];
        }
        printf("\n");
    }
    printf("sum=%d",sum);
    getchar();
}

7.4 定義二維數組,用於保存三個班,每一個班五名同窗成績,並求出每一個班級平均分,以及全部班級平均分

#include<stdio.h>
void main(){
    //分析
    //1.建立一個scores[3][5]
    //2.遍歷,給複製
    //3.再次遍歷,統計總分和平均分
    //4.輸出
    double score[3][5];
    int rows=sizeof(score)/sizeof(score[0]),cols=sizeof(score[0])/sizeof(double),i,j;
    //classTotalScore 各個班級總成績 totalscore 全部學生成績
    double totalScore=0.0,classTotalScore=0.0;
    for(i=0;i<rows;i++){
        for(j=0;j<rows;j++){
            score[i][j]=0.0;
        }
    }
    //遍歷,給每一個學生輸入成績
    for(i=0;i<rows;i++){
        for(j=0;j<cols;j++){
            printf("請輸入第%d個班的第%d個學生的成績",i+1,j+1);
            scanf("%lf",&score[i][j]);
        }
    }
    getchar();
    //顯示下成績狀況
    for(i=0;i<rows;i++){
        for(j=0;j<cols;j++){
            printf("%.2f",score[i][j]);
        }
        printf("\n");
    }
    //統計各個班的總成績,和全部學生的成績
    for(i=0;i<rows;i++){
        classTotalScore=0.0;//每次清零
        for(j=0;j<cols;j++){
            classTotalScore+=score[i][j];//累計每一個班的總成績
        }
        printf("第%d個班的平均成績是%.2f",i+1.classTotalScore/cols);
        totalScore+=classTotalScore;//將該班的總分,累加到totalScore
    }
    printf("全部學生的總成績是%.2f 平均成績是%.2f",totalScore,totalScore/(rows*cols));
    getchar();
    getchar();
}

8.二維數字使用細節和注意事項

  • 能夠只對部分元素賦值,爲賦值的元素自動取零
int main(){
    int a[4][5]={{1},{2},{3},{1}};
    int i,j;
    for(i=0;i<4;i++){
        for(j=0;j<5;j++){
            printf("%d",a[i][j]);
        }
        printf("\n");
    }
    getchar();
}
  • 若是對所有元素賦值,那麼第一維的長度能夠不給出
int a[3][3]={1,2,3,4,5,6,7,8,9};
//能夠寫爲
int a[][3]={1,2,3,4,5,6,7,8,9};
  • 二維數組能夠看做是由一維數組嵌套而成的;若是一個數組的每一個元素又是一個數組,那麼它就是二維數組
    • 二維數組a[3] [4]可當作三個一維數組,他們數組名分別爲a[0],a[1],a[2]
    • 這三個一維數組都有4個元素,如一維數組a[0]的元素爲a[0] [0],a[0] [1],a[0] [2],a[0] [3]
相關文章
相關標籤/搜索