日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

八、二分查找(Binary Search)

發(fā)布時間:2025/3/19 编程问答 14 豆豆
生活随笔 收集整理的這篇文章主要介紹了 八、二分查找(Binary Search) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

一、概述

二分查找(Binary Search,也稱折半查找)——針對有序數(shù)據(jù)集合的查找算法

1、基本思想

類似分治思想,每次都通過跟區(qū)間的中間元素進行對比,將代查找的區(qū)間縮小為之前的一半,直到找到要查找的元素,或者區(qū)間被縮小為0(不存在該元素)。

2、時間復雜度分析——O(logn)

不妨假設數(shù)據(jù)量為n,每次查找后數(shù)據(jù)量均為原來的1/2,最壞的情況下,直到查找區(qū)間被縮小為空,才停止。設經(jīng)過k次區(qū)間縮小操作區(qū)間縮小到1,可得 k=log2n 時間復雜度為O(k),也就是O(logn)。

O(1) 常量級時間復雜度的算法可能還沒有O(logn)的算法執(zhí)行效率高。因為:大O標記法表示時間復雜度時,會省略掉常數(shù)、系數(shù)和低階,O(1)可能表示一個非常大的常量值,eg: O(10000)。

二、簡單實現(xiàn)

二分查找最簡單的情況:有序數(shù)組中不存在重復元素

1、遞歸方法實現(xiàn)

#include<iostream> using namespace std;int BinarySearchRecursive(int *array, int low, int high, int key) {if(low > high)return -1;// int mid = (low + high) / 2; 若low和high比較大,兩者之和就可能溢出int mid = low + (high - low) / 2; // 若性能有要求,可將除以2操作轉化為位運算,以提升效率// int mid = low + ((high - low)>>1)if(array[mid] == key)return mid;else if(array[mid] < key)return BinarySearchRecursive(array, mid+1, high, key);elsereturn BinarySearchRecursive(array, low, mid-1, key); }int main() {int array[10];for(int i = 0; i < 10; i++)array[i] = i;cout<< "Recursive:"<<endl;cout<<"postion:"<<BinarySearchRecursive(array,0,9,4)<<endl;return 0; }

2、非遞歸方法

int BinarySearch(int *array, int aSzie, int key) {if(array == NULL || aSize == 0)return -1;int low = 0;int high = aSize - 1;int mid = 0;while(low <= high){mid = low + (high - low) / 2;if(array[mid] == key)return mid;else if(array[mid] < key)low = mid + 1;elsehigh = mid - 1;}return -1; }

3、應用場景的局限性

適用于:插入、刪除操作都不頻繁,一次排序多次查找且數(shù)據(jù)量較大的場景。

  • 二分查找依賴的是順序表數(shù)據(jù)結構,也就是數(shù)組(可以按照下標隨機訪問元素)

  • 二分查找的數(shù)據(jù)是有序的:排序算法時間復雜度最低為O(nlogn),若動態(tài)變化的數(shù)據(jù)集合,不再適用。

  • 適合數(shù)據(jù)量較大的場景,而非特別大。因為數(shù)組為了支持隨機訪問的特性,要求內存空間連續(xù)。

特例:若數(shù)據(jù)之間的比較操作特別耗時,不管數(shù)據(jù)量大小,都推薦使用二分查找。同on個過盡可能較少比較次數(shù)來提升性能。

三、應用實例

1、實例

假設我們有 1000 萬個整數(shù)數(shù)據(jù),每個數(shù)據(jù)占 8 個字節(jié),如何設計數(shù)據(jù)結構和算法,快速判斷某個整數(shù)是否出現(xiàn)在這 1000 萬數(shù)據(jù)中? 我們希望這個功能不要占用太多的內存空間,最多不要超過 100MB,你會怎么做呢?

2、分析

由于每個數(shù)據(jù)占 8 個字節(jié),內存占用差不多為80M < 100M,符合內存限制。
==》先從小到大排序,然后利用二分查找算法找數(shù)據(jù)。

注意:散列表、二叉樹這些支持快速查找的動態(tài)數(shù)據(jù)結構。但是,在該情況卻不行的。雖然在大部分情況下,用二分查找可以解決的問題,用散列表、二叉樹都可以解決。但是都會需要比較多的額外的內存空間。所以,如果用散列表或者二叉樹來存儲這
1000 萬的數(shù)據(jù),用 100MB 的內存肯定是存不下的。而二分查找底層依賴的是數(shù)組,除了數(shù)據(jù)本身之外,不需要額外存儲其他信息,是最省內存空間的存儲方式,所以剛好能在限定的內存大小下解決這個問題。

四、二分查找的進級(變形問題)

前提:數(shù)據(jù)都是從小到大排列的,且數(shù)據(jù)中存在重復的數(shù)據(jù)。

1、常見的變形問題

  • 查找第一個值等于給定值的元素
  • 查找最后一個值等于給定值的元素
  • 查找第一個大于等于給定值的元素
  • 查找最后一個小于等于給定值的元素

2、查找第一個值等于給定值的元素

(1)方法一

int bsearch1(int *array, int aSize, int key) {int low = 0;int high = aSize - 1;while (low <= high) {int mid = low + ((high - low)/2);if(array[mid] > key)high = mid - 1;else if(array[mid] < key)low = mid + 1;else// 當array[mid]=key時,// 需要確認一下這個 array[mid] 是不是第一個值等于給定值的元素{// 若mid等于0,說明該元素為第一個元素;// array[mid]的前一個元素array[mid-1]不等于key,說明該元素為第一個元素;if((mid == 0)||(array[mid-1]!=key))return mid;// 否則更新區(qū)間elsehigh = mid - 1;}}return -1; }

(2)方法二

int bsearch2(int *array, int aSize, int key) {int low = 0;int high = aSize - 1;while (low <= high){int mid = low + ((high - low) / 2);if(array[mid] >= key){high = mid - 1;}else{low = mid + 1;}}if(array[low] == key) return low;else return -1; }

3、查找最后一個值等于給定值的元素

int bSearch(int *array,int aSize,int key) {int low = 0;int high = aSize - 1;while(low <= high){int mid = low + ((high - low) / 2);if (array[mid] >= key)high = mid - 1;else if (array[mid < key]) {low = mid + 1;}else{if((mid == aSize - 1)||(array[mid+1] != key))return mid;elselow = mid + 1;}}return -1; }

4、查找第一個大于等于給定值的元素

int bSearch(int *array,int aSize,int key) {int low = 0;int high = aSize - 1;while(low <= high){int mid = low + ((high - low) / 2);if (array[mid] >= key){if((mid == 0)||(array[mid-1] < key))return mid;elsehigh = mid - 1;}else{low = mid + 1;}}return -1; }

5、查找最后一個小于等于給定值的元素

int bSearch(int *array,int aSize,int key) {int low = 0;int high = aSize - 1;while(low <= high){int mid = low + ((high - low) / 2);if (array[mid] > key){high = mid - 1;}else{if((mid == aSize - 1)||(array[mid+1] > key))return mid;elselow = mid + 1;}}return -1; }

總結

以上是生活随笔為你收集整理的八、二分查找(Binary Search)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內容還不錯,歡迎將生活随笔推薦給好友。