Sorting and Searching in C++
Sorting और searching क्यों ज़रूरी हैं
Sorting (data को क्रम में लगाना) और searching (कोई item खोजना) data पर सबसे आम operations हैं — rank list, merit list, roll number खोजना, library में book है या नहीं देखना। C++ <algorithm> में इनके तेज़, tested versions देती है, और exams में classic algorithms हाथ से लिखने को भी कहा जाता है। यह lesson दोनों सिखाता है।
std::sort
#include <iostream>
#include <vector>
#include <algorithm>
#include <functional>
int main() {
std::vector<int> marks = {66, 91, 78, 55, 84, 91};
std::sort(marks.begin(), marks.end()); // बढ़ता क्रम
for (int m : marks) std::cout << m << " ";
std::cout << "\n";
std::sort(marks.begin(), marks.end(), std::greater<int>()); // घटता क्रम
for (int m : marks) std::cout << m << " ";
std::cout << "\n";
int arr[] = {5, 2, 9, 1};
std::sort(arr, arr + 4); // साधारण arrays भी
std::cout << arr[0] << " " << arr[3] << "\n";
return 0;
}std::sort O(n log n) में चलता है और इसे random-access iterators (vector, deque, arrays) चाहिए। std::list के लिए list.sort() लें।
Comparator से objects sort करना
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
struct Student { std::string name; int marks; };
int main() {
std::vector<Student> cls = {{"Ravi", 78}, {"Aman", 91}, {"Sara", 78}, {"Priya", 91}};
// सबसे ज़्यादा marks पहले; बराबर हों तो नाम के alphabetical क्रम में
std::sort(cls.begin(), cls.end(), [](const Student& a, const Student& b) {
if (a.marks != b.marks) return a.marks > b.marks;
return a.name < b.name;
});
int rank = 1;
for (const auto& s : cls) std::cout << rank++ << ". " << s.name << " " << s.marks << "\n";
return 0;
}Comparator तब true लौटाए जब a को b से पहले आना चाहिए, और वह strict ordering हो — बराबर elements के लिए कभी true न लौटाए (> की जगह >= से sort crash भी कर सकता है)।
Sorting के और functions
| Function | कब इस्तेमाल करें |
|---|---|
std::stable_sort | बराबर elements का मूल क्रम बना रहे (जैसे marks से sort पर बराबरी में roll-number क्रम रहे) |
std::partial_sort(b, b + k, e) | सिर्फ ऊपर के k sorted चाहिए (top 3 rankers) |
std::nth_element | k-th सबसे छोटा / median चाहिए, पूरा क्रम नहीं |
std::is_sorted | Range पहले से sorted है या नहीं |
std::reverse | Range उल्टी करना |
find / find_if से linear search
किसी भी data पर चलता है, sorted हो या नहीं — O(n)।
std::vector<int> rolls = {12, 7, 25, 3, 18};
auto it = std::find(rolls.begin(), rolls.end(), 25);
if (it != rolls.end())
std::cout << "found at index " << (it - rolls.begin()) << "\n"; // 2
auto big = std::find_if(rolls.begin(), rolls.end(), [](int r) { return r > 15; });
std::cout << "first roll > 15: " << *big << "\n"; // 25Sorted data पर binary search
Binary search बीच के element को देखती है और हर कदम पर आधी range छोड़ देती है — O(log n)। Data उसी क्रम में sorted होना ज़रूरी है।
#include <iostream>
#include <vector>
#include <algorithm>
int main() {
std::vector<int> marks = {35, 48, 55, 66, 66, 66, 78, 91};
std::cout << std::boolalpha
<< "66 present? " << std::binary_search(marks.begin(), marks.end(), 66) << "\n"
<< "70 present? " << std::binary_search(marks.begin(), marks.end(), 70) << "\n";
auto lo = std::lower_bound(marks.begin(), marks.end(), 66); // पहला >= 66
auto hi = std::upper_bound(marks.begin(), marks.end(), 66); // पहला > 66
std::cout << "66 appears " << (hi - lo) << " times, starting at index "
<< (lo - marks.begin()) << "\n";
auto pos = std::lower_bound(marks.begin(), marks.end(), 70);
std::cout << "70 would be inserted at index " << (pos - marks.begin()) << "\n";
return 0;
}Classic algorithms खुद लिखना
Bubble sort — O(n²)
void bubbleSort(std::vector<int>& a) {
for (size_t i = 0; i + 1 < a.size(); i++) {
bool swapped = false;
for (size_t j = 0; j + 1 < a.size() - i; j++) {
if (a[j] > a[j + 1]) {
std::swap(a[j], a[j + 1]);
swapped = true;
}
}
if (!swapped) break; // पहले से sorted: जल्दी रुको
}
}Binary search — O(log n)
int binarySearch(const std::vector<int>& a, int key) {
int low = 0, high = static_cast<int>(a.size()) - 1;
while (low <= high) {
int mid = low + (high - low) / 2; // (low + high) के overflow से बचाव
if (a[mid] == key) return mid;
if (a[mid] < key) low = mid + 1;
else high = mid - 1;
}
return -1; // नहीं मिला
}और हाथ से लिखे sorts के लिए देखें bubble sort, selection और insertion sort और merge sort।
Complexity एक नज़र में
| Algorithm | Best | Average | Worst | Stable? |
|---|---|---|---|---|
| Bubble sort | O(n) | O(n²) | O(n²) | हाँ |
| Selection sort | O(n²) | O(n²) | O(n²) | नहीं |
| Insertion sort | O(n) | O(n²) | O(n²) | हाँ |
Merge sort / stable_sort | O(n log n) | O(n log n) | O(n log n) | हाँ |
std::sort (introsort) | O(n log n) | O(n log n) | O(n log n) | नहीं |
| Linear search | O(1) | O(n) | O(n) | — |
| Binary search | O(1) | O(log n) | O(log n) | — |
आम गलतियाँ
- Unsorted data पर
binary_searchयाlower_boundचलाना — नतीजा बेमतलब। - Sort comparator में
<=या>=— strict weak ordering टूटती है और crash हो सकता है। std::sort(v.begin(), v.end() - 1)लिखकर आख़िरी element छोड़ देना।- बहुत बड़े indices पर
mid = (low + high) / 2— overflow हो सकता है;low + (high - low) / 2लें। listपरstd::sortलगाना।
8 students के नाम और marks पढ़ें। Merit list print करें (marks घटते क्रम में, बराबरी पर नाम से)। फिर एक mark पूछें और marks की sorted copy पर lower_bound/upper_bound से बताएँ कि कितने students के ठीक उतने marks हैं और कितनों के ज़्यादा।
सारांश
std::sortO(n log n) में sort करता है; custom क्रम के लिएstd::greaterया lambda दें।- बराबरी में मूल क्रम रखना हो तो
stable_sort; top-k के लिएpartial_sort। find/find_if= किसी भी data पर linear search।binary_search,lower_bound,upper_bound= sorted data पर O(log n)।- Exams के लिए bubble sort और binary search हाथ से लिखना आना चाहिए।
संबंधित: STL algorithms, lambda, vector, C: binary search।
अक्सर पूछे जाने वाले प्रश्न (FAQ)
C++ में vector को घटते क्रम में कैसे sort करें?
std::sort को comparator दें: std::sort(v.begin(), v.end(), std::greater<int>()); या lambda [](int a, int b) { return a > b; }। एक और तरीका std::sort(v.rbegin(), v.rend()); है, जो उल्टी range को बढ़ते क्रम में sort करता है।std::sort कौन-सा sorting algorithm इस्तेमाल करता है?
std::stable_sort लें।Linear search और binary search में क्या अंतर है?
lower_bound और upper_bound में क्या अंतर है?
lower_bound(x) पहले ऐसे element का iterator लौटाता है जो x से छोटा नहीं है (≥ x), और upper_bound(x) x से बड़े पहले element का। दोनों के बीच की दूरी x के बराबर elements की संख्या होती है।