Skip to content

Commit 1645cf2

Browse files
feat: add new Median Search implementation (TheAlgorithms#1992)
* feat: add new median search algorithm with linked list * Removed filename Co-authored-by: David Leal <halfpacho@gmail.com> * Update search/median_search2.cpp Co-authored-by: David Leal <halfpacho@gmail.com> * Update search/median_search2.cpp Co-authored-by: David Leal <halfpacho@gmail.com> * Update search/median_search2.cpp Co-authored-by: David Leal <halfpacho@gmail.com> * Update search/median_search2.cpp Co-authored-by: David Leal <halfpacho@gmail.com> * fix: Requested changes made * Update search/median_search2.cpp Co-authored-by: David Leal <halfpacho@gmail.com> * Update search/median_search2.cpp Co-authored-by: David Leal <halfpacho@gmail.com> * Update search/median_search2.cpp Co-authored-by: David Leal <halfpacho@gmail.com> * Added algorithm and implementation explanations. Also added wikipedia link. * Update search/median_search2.cpp Co-authored-by: David Leal <halfpacho@gmail.com> * Added @brief and wikipedia link to algo * Update search/median_search2.cpp Co-authored-by: David Leal <halfpacho@gmail.com> * moved includes to top of file * fix: clang-tidy fixes applied * fix: clang-tidy fixes * updating DIRECTORY.md * clang-format and clang-tidy fixes for b24ca86 * Update search/median_search2.cpp Co-authored-by: David Leal <halfpacho@gmail.com> * clang-format and clang-tidy fixes for 247e061 * fix: fixed test case failing * clang-format and clang-tidy fixes for 4c1400d * fix: test cases now pass * clang-format and clang-tidy fixes for f302797 * Update search/median_search2.cpp Co-authored-by: David Leal <halfpacho@gmail.com> * Update search/median_search2.cpp Co-authored-by: David Leal <halfpacho@gmail.com> * clang-format and clang-tidy fixes for b8b5f5f * clang-format and clang-tidy fixes for d67d450 Co-authored-by: David Leal <halfpacho@gmail.com>
1 parent 0febbf0 commit 1645cf2

File tree

3 files changed

+159
-32
lines changed

3 files changed

+159
-32
lines changed

DIRECTORY.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -318,6 +318,7 @@
318318
* [Jump Search](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/search/jump_search.cpp)
319319
* [Linear Search](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/search/linear_search.cpp)
320320
* [Median Search](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/search/median_search.cpp)
321+
* [Median Search2](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/search/median_search2.cpp)
321322
* [Saddleback Search](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/search/saddleback_search.cpp)
322323
* [Sublist Search](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/search/sublist_search.cpp)
323324
* [Ternary Search](https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/search/ternary_search.cpp)

search/linear_search.cpp

Lines changed: 19 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@
77
* @author [Ritika Mukherjee](https://github.com/ritikaa17)
88
*/
99

10-
#include <iostream> /// for IO operations
11-
#include <cassert> /// for assert
10+
#include <cassert> /// for assert
11+
#include <iostream> /// for IO operations
1212

1313
/**
1414
* \brief [Algorithm implementation for linear search]
@@ -18,30 +18,26 @@
1818
* \returns index where the key-value occurs in the array
1919
* \returns -1 if key-value not found
2020
*/
21-
int LinearSearch(int *array, int size, int key)
22-
{
23-
for (int i = 0; i < size; ++i)
24-
{
25-
if (array[i] == key)
26-
{
21+
int LinearSearch(int *array, int size, int key) {
22+
for (int i = 0; i < size; ++i) {
23+
if (array[i] == key) {
2724
return i;
2825
}
2926
}
3027

31-
/* We reach here only in case element is not present in array, return an invalid entry in that case*/
28+
/* We reach here only in case element is not present in array, return an
29+
* invalid entry in that case*/
3230
return -1;
3331
}
3432

3533
/**
3634
* @brief Self-test implementations
3735
* @returns void
3836
*/
39-
static void tests()
40-
{
37+
static void tests() {
4138
int size = 4;
4239
int *array = new int[size];
43-
for (int i = 0; i < size; i++)
44-
{
40+
for (int i = 0; i < size; i++) {
4541
array[i] = i;
4642
}
4743

@@ -50,8 +46,7 @@ static void tests()
5046
assert(LinearSearch(array, size, 2) == 2);
5147

5248
size = 6;
53-
for (int i = 0; i < size; i++)
54-
{
49+
for (int i = 0; i < size; i++) {
5550
array[i] = i;
5651
}
5752

@@ -60,29 +55,27 @@ static void tests()
6055
assert(LinearSearch(array, size, 5) == 5);
6156

6257
std::cout << "All tests have successfully passed!\n";
63-
delete[] array; // free memory up
58+
delete[] array; // free memory up
6459
}
6560

6661
/**
6762
* @brief Main function
6863
* @returns 0 on exit
6964
*/
70-
int main()
71-
{
65+
int main() {
7266
int mode = 0;
7367

7468
std::cout << "Choose mode\n";
7569
std::cout << "Self-test mode (1), interactive mode (2): ";
7670

7771
std::cin >> mode;
7872

79-
if (mode == 2)
80-
{
73+
if (mode == 2) {
8174
int size = 0;
8275
std::cout << "\nEnter the size of the array [in range 1-30 ]: ";
8376
std::cin >> size;
8477

85-
while (size <= 0 || size > 30){
78+
while (size <= 0 || size > 30) {
8679
std::cout << "Size can only be 1-30. Please choose another value: ";
8780
std::cin >> size;
8881
}
@@ -92,28 +85,22 @@ int main()
9285

9386
// Input for the array elements
9487
std::cout << "Enter the array of " << size << " numbers: ";
95-
for (int i = 0; i < size; i++)
96-
{
88+
for (int i = 0; i < size; i++) {
9789
std::cin >> array[i];
9890
}
9991

10092
std::cout << "\nEnter the number to be searched: ";
10193
std::cin >> key;
10294

10395
int index = LinearSearch(array, size, key);
104-
if (index != -1)
105-
{
96+
if (index != -1) {
10697
std::cout << "Number found at index: " << index << "\n";
107-
}
108-
else
109-
{
98+
} else {
11099
std::cout << "Array element not found";
111100
}
112101
delete[] array;
113-
}
114-
else
115-
{
116-
tests(); // run self-test implementations
102+
} else {
103+
tests(); // run self-test implementations
117104
}
118105
return 0;
119106
}

search/median_search2.cpp

Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
/**
2+
* @file
3+
* @brief Given a linked list L[0,....,n] of n numbers, find the middle node.
4+
*
5+
* @details The technique utilized in this implementation is the ["Floyd's
6+
* tortoise and
7+
* hare"](https://en.wikipedia.org/wiki/Cycle_detection#Floyd's_tortoise_and_hare)
8+
* approach. This technique uses two pointers that iterate through the list at
9+
* different 'speeds' in order to solve problems. In this implementation, for
10+
* every iteration the slow pointer advances one node while the fast pointer
11+
* advances two nodes. The result of this is that since the fast pointer moves
12+
* twice as fast as the slow pointer, when the fast pointer reaches the end of
13+
* the list the slow pointer will be pointing to the middle node of the list.
14+
*
15+
* Here are some example lists you can use to see how the algorithm works
16+
* A = [1,2,3,4,5]
17+
* B = [1,2,3,4,5,6]
18+
* print median(A) #should be 39
19+
* print median(B) #should be 4
20+
*
21+
* @author [Benjamin Weiss](https://github.com/weiss-ben)
22+
* @see median_search.cpp
23+
*/
24+
25+
#include <cassert> /// for assert
26+
#include <iostream> /// for IO operations
27+
28+
/**
29+
* Definition for singly-linked list.
30+
*/
31+
struct ListNode {
32+
int val{0}; ///< the value stored in the node
33+
ListNode* next{nullptr}; ///< pointer to the next node
34+
ListNode() = default; ///< default constructor
35+
explicit ListNode(int x)
36+
: val(x) {} ///< constructor with value for node->val provided
37+
ListNode(int x, ListNode* next)
38+
: val(x),
39+
next(next) {
40+
} ///< constructor with values provided for node->val and node->next
41+
};
42+
43+
/**
44+
* @namespace search
45+
* @brief Search algorithms
46+
*/
47+
namespace search {
48+
/**
49+
* @namespace median_search
50+
* @brief Functions for the Median Search algorithm implementation. Wkipedia
51+
* link to algorithm: https://en.wikipedia.org/wiki/Median_search
52+
*/
53+
namespace median_search2 {
54+
/**
55+
* This function searches for the median of a linked list.
56+
* @param head The head of the linked list.
57+
* @returns Median node of the linked list.
58+
*/
59+
ListNode* middleNode(ListNode* head) {
60+
if (!head) {
61+
return nullptr;
62+
}
63+
64+
// Fast and slow pointers
65+
ListNode* fastptr = nullptr;
66+
ListNode* slowptr = fastptr = head;
67+
68+
// fast jumps 2 while slow jumps 1
69+
while (fastptr->next && fastptr->next->next) {
70+
slowptr = slowptr->next;
71+
fastptr = fastptr->next->next;
72+
}
73+
74+
return (fastptr->next) ? slowptr->next : slowptr;
75+
}
76+
} // namespace median_search2
77+
} // namespace search
78+
79+
/**
80+
* @brief Self-test implementations
81+
* @returns void
82+
*/
83+
static void test() {
84+
auto* head1 = new ListNode;
85+
head1->val = 1;
86+
87+
ListNode* temp = head1;
88+
for (int i = 2; i < 6; ++i) {
89+
// Allocate next
90+
auto* temp1 = new ListNode;
91+
temp1->val = i;
92+
93+
// Advance
94+
temp->next = temp1;
95+
temp = temp1;
96+
}
97+
temp->next = nullptr;
98+
99+
ListNode* median = search::median_search2::middleNode(head1);
100+
assert(3 == median->val); // 3 is the value of the median node.
101+
std::cout << "test case:1 passed\n";
102+
103+
// Test case # 2
104+
auto* head2 = new ListNode;
105+
head2->val = 1;
106+
107+
ListNode* temp2 = head2;
108+
for (int i = 2; i < 7; ++i) {
109+
// Allocate next
110+
auto* temp3 = new ListNode;
111+
temp3->val = i;
112+
113+
// Advance
114+
temp2->next = temp3;
115+
temp2 = temp3;
116+
}
117+
temp2->next = nullptr;
118+
119+
ListNode* median1 = search::median_search2::middleNode(head2);
120+
assert(4 == median1->val); // 4 is the value of the median node.
121+
std::cout << "test case:2 passed\n";
122+
123+
delete head1;
124+
delete temp;
125+
126+
delete head2;
127+
delete temp2;
128+
129+
std::cout << "--All tests passed--\n";
130+
}
131+
132+
/**
133+
* @brief Main function
134+
* @returns 0 on exit
135+
*/
136+
int main() {
137+
test(); // run self-test implementations
138+
return 0;
139+
}

0 commit comments

Comments
 (0)