茫茫人海,如何查找?

Posted Big sai

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了茫茫人海,如何查找?相关的知识,希望对你有一定的参考价值。

大家好,我是bigsai。今天,我们来聊编程中重要的问题:查找。

先来看这样一个场景:张无忌带着芷若、阿离、敏敏和小昭,在一家客栈住下,4个女孩分别在4个不同的房间。张无忌想去找敏敏,但不知道敏敏住在哪个房间,该如何去找呢?

思路一: 逐个查找

最直接的思路就是,一个个地问。于是,张无忌敲开了第一个房间,被骂个狗血喷头:

张无忌知道,问错房间了,那就接着试吧,敲开第二个房间的门,被骂得惨不忍睹:

张无忌垂头丧气,但痴心不改,继续问,继续敲开第三个房间的门,这回就对了:

我们回头反思一下,这种盲目逐个查找,是非常低效的,是要被喷的。逐个查找的C++程序如下:

#include <iostream>
using namespace std;


bool findElement(int a[], int n, int x)
{
  for (int i = 0; i < n; i++)
  {
    if (a[i] == x)
    {
      return true;
    }
  }
  
  return false;
}


int main()
{
  int a[] = {60, 7, 15, 12, 20, 30, 3};
  int n = sizeof(a) / sizeof(a[0]);
  cout << findElement(a, n, 30) << endl;
  return 0;
}

经测试,程序OK.

思路二: 二分查找

大家应该都去图书馆借过书,里面的图书都是按照顺序来排列的,这样就非常好查找了。为了方便示意,我用数字查找来举例。

假设有数字:3, 7, 12, 15, 20, 30, 60,张无忌要找30这个数字,该怎么找呢?

张无忌从中间开始找,发现中间的数字是15,而30比15大,所以30必然在15右边:

接下来,张无忌从右边剩下来的数字中查找,还是从中间开始找起,发现刚好找到了30,目标达成:

这里我们反思一下,二分查找的前提是数字要有序。二分查找之所以高效,是因为每次询问后,就能排除一半的数据。

那么,利用二分查找的思路,张无尽该如何找到敏敏呢?显然,需要对这四个人进行排序,我们以首字母排序来定:

于是乎,排序之后,张无忌用二分查找的思路,很快就找到了敏敏的房间,可高兴坏了。找数字的C++二分查找程序如下:

#include <iostream>
using namespace std;


int binarySearch(int a[], int n, int x)
{
  int low = 0;
  int high = n - 1;
  int mid;
  while(low <= high)
  {
    mid = (low + high)/2;  
    if(x == a[mid])
    {
      return mid;
    }


    if(x < a[mid])
    {
      high = mid - 1;
    }
    else
    {
      low = mid + 1;
    }
  }
 
  return -1;
}
 
int main()
{
  int a[] = {3, 7, 12, 15, 20, 30, 60}; // 要求有序
  int n = sizeof(a) / sizeof(a[0]);
  cout << binarySearch(a, n, 30) << endl;  // 输出下标
  return 0;
}

经测试,程序OK.

思路三: 哈希查找

张无忌越来越没有耐心了,毕竟他知道,无论是逐个查找还是二分查找,总会有问错的时候,容易被骂是个大渣男。

所以,张无忌在寻找一种更好的方法,为什么不直接给每个房间定一个房间标号呢?这样就可以直接去敏敏的房间啊。

于是乎,居住安排和查找思路如下:

这里的本质思路就是:建立人与房间号的对应关系。这种表的结构,就叫哈希表,对应的查找就是哈希查找,效率非常高。说白了,把具体人放在该放的房间,直接通过房间号找人。

想一想,在生活中是不是也一样?有时候,焦头烂额找东西,却找不到,那是因为没有把东西放到该放的地方。当你在喊:老婆,我毛巾放哪里了?你老婆可以说:放在该放的地方。

C++中的unordered_map、Java中的hashmap、Golang中的map都是哈希表的典型应用,都需要熟练掌握。下面,我们以C++为例,来看哈希查找:

#include<iostream>
#include<unordered_map>
#include <algorithm>
using namespace std;


int main() 
{
  unordered_map<int, bool> mp;
  mp[30] = true;
  mp[7] = true;
  mp[15] = true;
  mp[12] = true;
  mp[60] = true;
  mp[3] = true;
  mp[20] = true;


  cout << (mp.find(30) != mp.end()) << endl;
  return 0;
}

经测试,程序OK.

查找,是最基础的算法。本文聊了三种典型的查找思路,我们也会一步一个脚印,争取每篇文章讲清讲透一件事,也希望大家阅读后有所收获,心情愉快。

本文作者道哥,CSDN前30名,曾混迹于BAT大厂。公众号讲解计算机基础、网络、数据结构、算法、C++、Java等多方面的编程知识。欢迎点击名片关注道哥,感谢点赞和在看支持哦。

以上是关于茫茫人海,如何查找?的主要内容,如果未能解决你的问题,请参考以下文章

20154312 曾林 Exp4恶意软件分析

小程序如何使用订阅消息(PHP代码+小程序js代码)

高清手机壁纸 | IOS,android 壁纸

css3进阶less实现星空动画

异常还不知道是什么?一文教会你异常是什么,如何优雅处理!

调用DoSomething方法执行一些逻辑代码