1. 程式人生 > 其它 >題解——冒泡+二分查詢

題解——冒泡+二分查詢

技術標籤:C++資料結構與演算法教程資料結構演算法c++

題解——冒泡+二分查詢

文章目錄


題目連結: 傳送門

題面

描述

有一組資料放在陣列R[ ]中,R[ ]={9,8,7,6,0,-1,10,-5,-32,66},請呼叫氣泡排序函式(自己定義函式),先將陣列進行排序,然後呼叫二分查詢演算法(自己定義函式)查詢某數,分別給出比較次數,每個比較次數佔一行,比較次數為-1時表示沒找到。

輸入

第1行輸入排序標誌,為1時,對原陣列先採用升序排序

,為2時,對原陣列採用降序排序

第2行開始輸入待查詢的數。輸入非整數^Z時,結束輸入。

輸出

採用二分查詢法查詢某數時的比較次數,每個比較次數佔一行,比較次數為-1時表示沒找到。

樣例輸入

1
-1
25
6

樣例輸出

3
-1
1

提示

直接在程式裡定義R[ ]={9,8,7,6,0,-1,10,-5,-32,66}

ps. 這裡有點狠!讓你直接在程式裡定義,結果原題混入一箇中文逗號!
看不見我


題解

這個題對大家來說陌生的地方可能主要在於輸入要求:

輸入非整數或^Z時,結束輸入。

^Z其實是ctrl+Z的意思,這是一個檔案結束符,當你在鍵盤上敲ctrl+Z的時候,相當於輸入了“檔案結束符”,你的程式必須能讀取“檔案結束符”,並使輸入停止。

我們一步一步來:

首先按題意,定義陣列r

#include <iostream>
using namespace std;
int r[]={9,8,7,6,0,-1,10,-5,-32,66};

ps. 為了方便使用,我們直接把它定義為全域性變數

氣泡排序

升序

void cin_up(){
    int t;
    for(int i=0;i<10;i++)
        for(int j=0;j<9;j++)
            if(r[j]>r[j+1]) //升序
                t=r[j],r[j]=r[j+1],r[j+1]=t;
}

降序

void cin_down(){
    int t;
    for(int i=0;i<10;i++)
        for(int j=0;j<9;j++)
            if(r[j]<r[j+1]) //降序
                t=r[j],r[j]=r[j+1],r[j+1]=t;
}

二分查詢

首先需要注意的一點是,二分演算法可能需要根據序列的增減性不同而作出相應調整,如:

  • 若待查詢序列為升序,如0 1 2 3 4 5 6,要找5,第一次mid=(0+6)/2=3r[mid]=3<5,此時應該進行的操作是l=mid+1

  • 若待查詢序列為降序,如6 5 4 3 2 1 0,還是要找5,第一次r[mid]=3<5,此時進行的操作就不是l=mid+1了,而是r=mid-1

因此,我們乾脆就寫兩個二分查詢函式,根據升序/降序的不同選擇性地呼叫它們即可。

二分查詢——升序

int binFind_up(int key){
    int L=0,R=9,mid,num=0;
    while (L<=R){
        num++;
        mid=(L+R)/2;
        if(r[mid]==key)return num;
        else if(r[mid]<key)
            L=mid+1;
        else
            R=mid-1;
    }
    return -1;
}

二分查詢——降序

int binFind_down(int key){
    int L=0,R=9,mid,num=0;
    while (L<=R){
        num++;
        mid=(L+R)/2;
        if(r[mid]==key)return num;
        else if(r[mid]>key)
            L=mid+1;
        else
            R=mid-1;
    }
    return -1;
}

輸入

AC做法

int main(){
    int n; // 排序標誌n
    cin>>n;
    if(n==1)
        cin_up(); // 採用升序排序
    else if(n==2)
        cin_down(); // 採用降序排序
    int x;
    while (cin>>x){ // 符合要求的資料輸入方法
        if(n==1)cout<<binFind_up(x)<<endl;
        else cout<<binFind_down(x)<<endl;
    }
    return 0;
}

原理

為什麼可以把cin直接放在while的條件裡呢?這就要從cin函式的返回值說起。函式cin也是有返回值的。當:

  • 遇到檔案結束符ctrl+Z 的時候,返回0
  • 遇到無效輸入的時候,返回0,比如待輸入的數是整數,但你輸入了非整數
  • 有效輸入返回1

因此,我們可以直接定義int型的待輸入變數x,然後直接將cin>>x放在while的判斷條件內,就可以“歪打正著”地實現題目要求的功能。