你真的會二分查詢嗎?

2021-09-02 16:42:23 字數 3701 閱讀 4292

二分查詢是一種在有序陣列中查詢某一特定元素的搜尋演算法。搜尋過程從陣列的中間元素開始,如果中間元素正好是要查詢的元素,則搜尋過程結束;如果某一特定元素大於或者小於中間元素,則在陣列大於或小於中間元素的那一半中查詢,而且跟開始一樣從中間元素開始比較。如果在某一步驟陣列為空,則代表找不到。這種搜尋演算法每一次比較都使搜尋範圍縮小一半。

時間複雜度為o(log n)

例如對於構成的有序序列對應的查詢樹:

最簡單的二分查詢演算法:

即找到返回下標,找不到返回-1,(座標範圍:[0~nums.size() - 1])

#include #include #include #include #include #include #include #include using namespace std;

int binarysearch(vector& nums, int target)

else if(nums[mid] < target)

else

}return -1;

}int main()

; cout << binarysearch(vec, 3);

return 0;

}

查詢第乙個與target相等的元素位置,找不到返回-1

int binarysearchleft(vector& nums, int target)

else

}if (left <= (int)nums.size() - 1 && nums[left] == target)

return -1;

}

查詢最後乙個與target相等的元素位置,找不到返回-1

int binarysearchright(vector& nums, int target)

else

}if (right >= 0 && nums[right] == target)

return -1;

}

查詢最後乙個小於key的元素

#include #include #include #include #include #include #include #include using namespace std;

int binarysearch(vector& nums, int target)

else if(nums[mid] < target)

}return right;

}int main()

; cout << binarysearch(vec, 7);

return 0;

}

查詢第乙個大於key的元素

#include #include #include #include #include #include #include #include using namespace std;

int binarysearch(vector& nums, int target)

else if(target < nums[mid])

}return left;

}int main()

; cout << binarysearch(vec, 5);

return 0;

}

如果返回nums.size()則說明不存在。

查詢第乙個等於或者小於key的元素

#include #include #include #include #include #include #include #include using namespace std;

int binarysearch(vector& nums, int target)

else

}if (nums[left] != target)

return left;

}int main()

; cout << binarysearch(vec, 5);

return 0;

}

查詢最後乙個等於或者大於key的元素

#include #include #include #include #include #include #include #include using namespace std;

int binarysearch(vector& nums, int target)

else

}if (nums[right] != target)

return right;

}int main()

; cout << binarysearch(vec, 5);

return 0;

}

stl中與二分查詢相關的函式有4個,分別是lower_bound, upper_bound, equal_range和binary_search,下面通過乙個簡單的例子說明各個函式的使用方法。

#include #include #include using namespace std;

int main()

; //已排序

vectorv(a, a + 6);

typedef vector::iterator it; //迭代器型別

it st = v.begin(), ed = v.end(); //起始迭代器

it p1 = lower_bound(st, ed, 2);//>=2的第乙個位置

printf("%d\n", p1 - st); // 1

it p2 = upper_bound(st, ed, 2);//>2的第乙個位置

printf("%d\n", p2 - st); // 4

pairp = equal_range(st, ed, 2); //==2的位置

printf("%d-%d\n", p.first - st, p.second - st); // 1-4

bool exist = binary_search(st, ed, 2); //2是否存在

printf("%d\n", exist); //1 (是)

}

其中每個函式實現的功能如下:

binary_search:查詢某個元素是否出現。

lower_bound:查詢第乙個大於或等於某個元素的位置。

upper_bound:查詢第乙個大於某個元素的位置。

equal_range:查詢某個元素出現的起止位置。注意,終止位置為最後一次出現的位置加一。

其中lower_bound和upper_bound的功能可能比較彆扭,可以這樣看:對於已排序的陣列1 2 2 2 3 4,元素2出現了3次,第一次出現的位置為1,最後一次的位置為3,lower_bound即為這個第一次出現的位置,而upper_bound本意是要標誌最後一次出現的位置,但stl中習慣使用左閉右開的區間,於是upper_bound返回的結果應該為最後一次出現的位置的下乙個位置。當查詢的元素一次都未出現時,二者返回的結果都是第乙個大於該元素的位置。

參考:

你真的會二分查詢嗎?

看到這個標題無論你是處於怎樣的心理進來看了,我覺得都是值得的。因為這個問題太簡單,任何乙個開始接觸 真正 演算法基本都是從二分查詢開始的。至於二分查詢都不知道是什麼的可以先去找別的資料看下,再來看這篇文章。既然很簡單,那麼我們開始一起寫乙個吧,要求是對num 不減序列在區間 0,7 進行查詢,當然我...

你真的會二分查詢嗎?

引用請註明出處 看到這個標題無論你是處於怎樣的心理進來看了,我覺得都是值得的。因為這個問題太簡單,任何乙個開始接觸 真正 演算法基本都是從二分查詢開始的。至於二分查詢都不知道是什麼的可以先去找別的資料看下,再來看這篇文章。既然很簡單,那麼我們開始一起寫乙個吧,要求是對num 不減序列在區間 0,7 ...

你真的會二分查詢嗎?

看到這個標題無論你是處於怎樣的心理進來看了,我覺得都是值得的。因為這個問題太簡單,任何乙個開始接觸 真正 演算法基本都是從二分查詢開始的。至於二分查詢都不知道是什麼的可以先去找別的資料看下,再來看這篇文章。既然很簡單,那麼我們開始一起寫乙個吧,要求是對num 不減序列在區間 0,7 進行查詢,當然我...