查找算法

基础查询

有一个人名的数组,请编写一个程序,判断用户输入的人是否在程序当中

人名:好好,学学,天天,上上,雷雷,奥奥

string student[6] = {"haohao","xuexue","tiantian","shangshang","leilei","aoao"};

思路分析:

1.获得用户的输入

2.遍历数组,进行比较

3.如果比较成立,则输出结果

代码实现

#include <iostream>
#include <string>

using namespace std;

int main(int argc, char const *argv[])
{
    string student[6] = {"haohao","xuexue","tiantian","shangshang","leilei","aoao"};
    string name = "";
    int i;

    cin >> name;

    for (i = 0;i <6;i++){
        if (student[i] == name){
            cout << student[i] << endl;
            break;
        }
    }

    if (i > 5) cout << "not found" << endl;

    return 0;
}

当我们的数据量非常多的时候,如果我们采用同样的算法,那么在最坏的情况下,需要遍历所有的数据

假设我们有1000000个数据,刚好好查找的数据在最后一个,那么我们将比较1000000次才能得出正确答案,这样的算法效率是非常不高的

二分算法

二分查找算法是一个           的算法,可以非常快速的定位数据的位置

log_2(N)

1.对于输入的数据N

2.找到数组中间位置的数据M,如果N < M,则说明数据在M前面的位置,重新计算中间数据M,重复第二步

3.如果N > M,则说明数据在M后面的位置,重新在后面一半中计算中间数据M,重复第二步

请编写一个程序,利用二分算法,找到20在数组当中的位置

算法需求

动画演示

#include <iostream>

using namespace std;

int main(){
    int a[11] = {12,20,36,45,56,67,71,79,84,90,95};
    int L = 0,R = 10,M;
    int data;
    bool flag = false;

    cin >> data;

    while (L < R){
        M = (L + R)/2;
        if (data == a[M]){
            cout << "found:" << M << endl;
            flag = true;
            break;
        }else if (data < a[M]){
            R = M - 1;
        }else{
            L = M + 1;
        }
    }

    if (!flag){
        cout << "not found" << endl;
    }


}

算法实现

注意:使用二分算法的前提是必须要有序,无序的序列是没有办法使用二分算法的

#include <iostream>

using namespace std;

int func(int a[],int data,int L,int R){

    if (L > R){
        return -1;
    }

    int M = (L+R)/2;
    if (data == a[M]){
        return M;
    }else if (data < a[M]){
        return func(a,data,L,M-1);
    }else{
        return func(a,data,M+1,R);
    }
}


int main(){
    int a[11] = {12,20,36,45,56,67,71,79,84,90,95};
    int data;
    cin >> data;
    int result = func(a,data,0,10);

    if (result == -1){
        cout << "not found" << endl;
    }else{
        cout << "found:" << result << endl;
    }

}

二分算法递归实现

综合练习

有个排序后的字符串数组,其中散布着一些空字符串,编写一个方法,找出给定字符串(肯定不是空字符串)的索引。

"a","","ac","","ad","b","","ba"
#include <iostream>
#include <cstring>

using namespace std;

int main(){
    string str1[8] = {"a","","ac","","ad","b","","ba"};
    string result;
    cin >> result;
    
    int begin = 0;
    int end = 7;
    int mid;

    while (begin <= end){
        mid = begin + ((end - begin) >> 1);
        while (str1[mid] == ""){
            mid ++;
        }
        if (str1[mid] == result){
            cout << str1[mid];
            break;
        }

        if (str1[mid][0] > result[0] )
            begin = mid+1;
        else
            end = mid-1;
    }

}

算法实现

编写程序,找出最长连续递增的子序列

例如:(1,9,2,5,7,3,4,6,8,0)中最长的递增子序列为(3,4,6,8)

#include <iostream>

using namespace std;

int main(){
   int a[10] = {1,9,2,5,7,3,4,6,8,0};
   
   int begin = 0;
   int end = 0,maxlength = 0,length = 1;

   while (begin <= 9){
       while (a[end] < a[end + 1] ){
           length ++;
           end ++;
       }
       begin ++;
       end = begin;
       if (length > maxlength)
           maxlength = length;
       length = 1;
   }

   cout << maxlength << endl;
}

算法实现

Made with Slides.com