第3回 ソート、二分探索、データ構造
担当:laft
bit.ly/2W5p7mT
KMC-ID:laft
あくまで一例ですが、下を参考に
配列長nとする。
| index | 0 | 1 | 2 | 3 | 4 | 
| 値 | 8 | 2 | 7 | 3 | 4 | 
| index | 0 | 1 | 2 | 3 | 4 | 
| 値 | 8 | 2 | 7 | 3 | 4 | 
| index | 0 | 1 | 2 | 3 | 4 | 
| 値 | 8 | 2 | 7 | 3 | 4 | 
0番目>1番目なので入れ替え
| index | 0 | 1 | 2 | 3 | 4 | 
| 値 | 2 | 8 | 7 | 3 | 4 | 
| index | 0 | 1 | 2 | 3 | 4 | 
| 値 | 2 | 8 | 7 | 3 | 4 | 
| index | 0 | 1 | 2 | 3 | 4 | 
| 値 | 2 | 7 | 8 | 3 | 4 | 
| index | 0 | 1 | 2 | 3 | 4 | 
| 値 | 2 | 7 | 8 | 3 | 4 | 
| index | 0 | 1 | 2 | 3 | 4 | 
| 値 | 2 | 7 | 3 | 8 | 4 | 
| index | 0 | 1 | 2 | 3 | 4 | 
| 値 | 2 | 7 | 3 | 8 | 4 | 
| index | 0 | 1 | 2 | 3 | 4 | 
| 値 | 2 | 7 | 3 | 4 | 8 | 
3. これを最大n-1回繰り返す
| index | 0 | 1 | 2 | 3 | 4 | 
| 値 | 2 | 7 | 3 | 4 | 8 | 
3. これを最大n-1回繰り返す
| index | 0 | 1 | 2 | 3 | 4 | 
| 値 | 2 | 7 | 3 | 4 | 8 | 
3. これを最大n-1回繰り返す
| index | 0 | 1 | 2 | 3 | 4 | 
| 値 | 2 | 7 | 3 | 4 | 8 | 
3. これを最大n-1回繰り返す
| index | 0 | 1 | 2 | 3 | 4 | 
| 値 | 2 | 3 | 7 | 4 | 8 | 
3. これを最大n-1回繰り返す
| index | 0 | 1 | 2 | 3 | 4 | 
| 値 | 2 | 3 | 4 | 7 | 8 | 
3. これを最大n-1回繰り返す
| index | 0 | 1 | 2 | 3 | 4 | 
| 値 | 2 | 3 | 4 | 7 | 8 | 
3. これを最大n-1回繰り返す
| index | 0 | 1 | 2 | 3 | 4 | 
| 値 | 2 | 3 | 4 | 7 | 8 | 
今回は3回目でソート済みとなった。
swap(a,b); :aとbの中身を入れ替えるSTL
//バブルソート
void bubble_sort(vector<int> &vec){
  //n-1周全てを左から比較する。
  for(int i=0;i<(int)vec.size()-1;++i){
    //右端にできたソート済部分を除いて左から順に見る
    for(int j=0;j<(int)vec.size()-i-1;++j){
      //左>右なら
      if(vec.at(j)>vec.at(j+1))  {
        //右<左となるように入れ替える。
        swap(vec.at(j),vec.at(j+1));
      }
    }
  }  
}| index | 0 | 1 | 2 | 3 | 4 | 5 | 
| 値 | 6 | 2 | 9 | 5 | 1 | 4 | 
| index | 0 | 1 | 2 | 
| 値 | 6 | 2 | 9 | 
| index | 0 | 1 | 2 | 
| 値 | 5 | 1 | 4 | 
| index | 0 | 1 | 2 | 3 | 4 | 5 | 
| 値 | 6 | 2 | 9 | 5 | 1 | 4 | 
| index | 0 | 1 | 2 | 
| 値 | 6 | 2 | 9 | 
| index | 0 | 1 | 2 | 
| 値 | 5 | 1 | 4 | 
| index | 0 | 1 | 2 | 3 | 4 | 5 | 
| 値 | 6 | 2 | 9 | 5 | 1 | 4 | 
| index | 0 | 1 | 2 | 
| 値 | 2 | 6 | 9 | 
| index | 0 | 1 | 2 | 
| 値 | 1 | 4 | 5 | 
| index | 0 | 1 | 2 | 3 | 4 | 5 | 
| 値 | 6 | 2 | 9 | 5 | 1 | 4 | 
| index | 0 | 1 | 2 | 
| 値 | 2 | 6 | 9 | 
| index | 0 | 1 | 2 | 
| 値 | 1 | 4 | 5 | 
| index | 0 | 1 | 2 | 3 | 
| 値 | 2 | 6 | 9 | 
| index | 0 | 1 | 2 | 3 | 
| 値 | 1 | 4 | 5 | 
| index | 0 | 1 | 2 | 3 | 
| 値 | 2 | 6 | 9 | 
| index | 0 | 1 | 2 | 3 | 
| 値 | 1 | 4 | 5 | 
| index | 0 | 1 | 2 | 3 | 4 | 5 | 
| 値 | 
マージ後の配列
| index | 0 | 1 | 2 | 3 | 
| 値 | 2 | 6 | 9 | 
| index | 0 | 1 | 2 | 3 | 
| 値 | 1 | 4 | 5 | 
| index | 0 | 1 | 2 | 3 | 4 | 5 | 
| 値 | 
マージ後の配列
1の方が小さいので1を入れる。
| index | 0 | 1 | 2 | 3 | 
| 値 | 2 | 6 | 9 | 
| index | 0 | 1 | 2 | 3 | 
| 値 | 1 | 4 | 5 | 
| index | 0 | 1 | 2 | 3 | 4 | 5 | 
| 値 | 1 | 
マージ後の配列
1の方が小さいので1を入れる。
| index | 0 | 1 | 2 | 3 | 
| 値 | 2 | 6 | 9 | 
| index | 0 | 1 | 2 | 3 | 
| 値 | 1 | 4 | 5 | 
| index | 0 | 1 | 2 | 3 | 4 | 5 | 
| 値 | 1 | 
マージ後の配列
| index | 0 | 1 | 2 | 3 | 
| 値 | 2 | 6 | 9 | 
| index | 0 | 1 | 2 | 3 | 
| 値 | 1 | 4 | 5 | 
| index | 0 | 1 | 2 | 3 | 4 | 5 | 
| 値 | 1 | 2 | 
マージ後の配列
| index | 0 | 1 | 2 | 3 | 
| 値 | 2 | 6 | 9 | 
| index | 0 | 1 | 2 | 3 | 
| 値 | 1 | 4 | 5 | 
| index | 0 | 1 | 2 | 3 | 4 | 5 | 
| 値 | 1 | 2 | 4 | 
マージ後の配列
| index | 0 | 1 | 2 | 3 | 
| 値 | 2 | 6 | 9 | 
| index | 0 | 1 | 2 | 3 | 
| 値 | 1 | 4 | 5 | 
| index | 0 | 1 | 2 | 3 | 4 | 5 | 
| 値 | 1 | 2 | 4 | 5 | 
マージ後の配列
| index | 0 | 1 | 2 | 3 | 
| 値 | 2 | 6 | 9 | 
| index | 0 | 1 | 2 | 3 | 
| 値 | 1 | 4 | 5 | 
| index | 0 | 1 | 2 | 3 | 4 | 5 | 
| 値 | 1 | 2 | 4 | 5 | 6 | 
マージ後の配列
| index | 0 | 1 | 2 | 3 | 
| 値 | 2 | 6 | 9 | 
| index | 0 | 1 | 2 | 3 | 
| 値 | 1 | 4 | 5 | 
| index | 0 | 1 | 2 | 3 | 4 | 5 | 
| 値 | 1 | 2 | 4 | 5 | 6 | 9 | 
マージ後の配列
| index | 0 | 1 | 2 | 3 | 4 | 5 | 
| 値 | 1 | 2 | 4 | 5 | 6 | 9 | 
マージ後の配列
| index | 0 | 1 | 2 | 3 | 4 | 
| 値 | 3 | 5 | 2 | 4 | 1 | 
| index | 0 | 1 | 2 | 3 | 4 | 
| 値 | 3 | 5 | 2 | 4 | 1 | 
3より小さい配列
3より大きい配列
| index | 0 | 1 | 2 | 3 | 4 | 
| 値 | 3 | 5 | 2 | 4 | 1 | 
| 2 | 1 | 
| 5 | 4 | 
3より小さい配列
3より大きい配列
| index | 0 | 1 | 2 | 3 | 4 | 
| 値 | 3 | 5 | 2 | 4 | 1 | 
| 2 | 1 | 
| 5 | 4 | 
3より小さい配列
3より大きい配列
| index | 0 | 1 | 2 | 3 | 4 | 
| 値 | 3 | 5 | 2 | 4 | 1 | 
| 1 | 2 | 
| 4 | 5 | 
3より小さい配列
3より大きい配列
| 3 | 
| 1 | 2 | 
| 4 | 5 | 
3より小さい配列
3より大きい配列
基準値
| index | 0 | 1 | 2 | 3 | 4 | 
| 値 | 
| 3 | 
| 1 | 2 | 
| 4 | 5 | 
3より小さい配列
3より大きい配列
基準値
| index | 0 | 1 | 2 | 3 | 4 | 
| 値 | 1 | 2 | 3 | 4 | 5 | 
| index | 0 | 1 | 2 | 3 | 4 | 
| 値 | 1 | 2 | 3 | 4 | 5 | 
| 3 | 5 | 2 | 4 | 1 | 
| 2 | 1 | 
| 5 | 4 | 
| 3 | 
| 2 | 
| 1 | 
| 4 | 
| 5 | 
| 1 | 2 | 3 | 4 | 5 | 
| 1 | 2 | 
| 4 | 5 | 
| index | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 
| 値 | 2 | 3 | 4 | 7 | 8 | 10 | 11 | 
配列から2のあるindexを見つける。
| index | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 
| 値 | 2 | 3 | 4 | 7 | 8 | 10 | 11 | 
配列から2のあるindexを見つける。
真ん中の値と比較する
2<7
| index | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 
| 値 | 2 | 3 | 4 | 7 | 8 | 10 | 11 | 
配列から2のあるindexを見つける。
真ん中の値と比較する
2<7
この区間には2はない
探索範囲
| index | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 
| 値 | 2 | 3 | 4 | 7 | 8 | 10 | 11 | 
配列から2のあるindexを見つける。
探索範囲の真ん中の値と比較する
2<3
探索範囲
この区間には2はない
| index | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 
| 値 | 2 | 3 | 4 | 7 | 8 | 10 | 11 | 
配列から2のあるindexを見つける。
探索範囲の真ん中の値と比較する
2<3
探索範囲
この区間には2はない
| index | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 
| 値 | 2 | 3 | 4 | 7 | 8 | 10 | 11 | 
配列から2のあるindexを見つける。
探索範囲の真ん中の値と比較する
2=2
発見!!
この区間には2はない
// v 中に t を見つけたら そのindex 、なければ -1を返す
int binsearch(vector<int> v, int t) {
    int l = 0, r = v.size(); // 最初は全範囲 (半開区間)
    while (l < r) { // 範囲の長さが 0 でない限り繰り返す
        int m = l + (r - l) / 2; // 中間の点
        // 中間点で一致した = 見つかった
        if (v[m] == t) return m;
        // 見つからなかったら、値の大小に応じて範囲を狭める
        if (v[m] < t) l = m + 1;
        else          r = m;
    }
    // ここまできたら見つからなかった → v中にない
    return -1;
}#include<bits/stdc++.h>
using namespace std;
int main(){
  int n; cin >> n;  //配列長nの宣言・入力
  vector<int> v(n); //配列vの宣言
  for(int i=0;i<n;++i){
    cin >> v.at(i); //vの入力
  }
  sort(v.begin(),v.end()); //vの昇順ソート
  int q; cin >> q;  //クエリ数qの宣言・入力
  for(int i=0;i<q;++i){
    int x; cin >> x;//探索クエリxの宣言・入力
    if(binary_search(v.begin(),v.end(),x)==1){
      //二分探索して見つかったとき、"Yes"を出力。
      cout << "Yes" << endl;
    } else cout << "No" << endl; //なかったとき"No"を出力
  }
}全部STLにある!!!!
#include<bits/stdc++.h>
using namespace std;
int main(){
    pair<int,int> pr;    //pairを両方intで宣言
    pr.first = 5;        //1つ目に5を代入
    pr.second = 3;       //2つ目に3を代入
    if(pr < make_pair(5,4)){    //(5,4)より小さいとき
        //今回は実行される
        //2番目の値を出力
        cout << pr.second << endl; //3が出力される。
    }
}set<int> st = {5,1,3,2,4,6};
//beginから順番にイテレータを辿る。
//これによって、昇順ソートされたものと同等に出力できる。
//autoで初期化すれば、自動で型を決めてくれる。
for(auto itr = st.begin();itr!=st.end();++itr){
    cout << *itr << endl;  //*をつけて要素にアクセス。
    //1,2,3,4,5,6が改行で区切られて出力される。
}┏━━━━━━━━━━━┳━━┓
┃     c++  set       ┃検索┃
┗━━━━━━━━━━━┻━━┛