2022-09-10 22:52:27 +08:00
/**
2022-09-11 19:15:35 +08:00
* @ file
2022-09-16 01:34:03 +08:00
* @ brief Given a linked list L [ 0 , . . . . , n ] of n numbers , find the middle node .
*
* @ details The technique utilized in this implementation is the " Floyd's tortise and hare " approach . Wikipedia link to technique : https : //en.wikipedia.org/wiki/Cycle_detection#Floyd's_tortoise_and_hare
2022-09-15 04:32:43 +08:00
* This technique uses two pointers that iterate through the list at different ' speeds ' in order to solve problems .
* In this implementation , for every iteration the slow pointer advances one node while the fast pointer advances two nodes .
* The result of this is that since the fast pointer moves twice as fast as the slow pointer , when the fast pointer reaches the end of the list
* the slow pointer will be pointing to the middle node of the list .
2022-09-10 22:52:27 +08:00
*
* Here are some example lists you can use to see how the algorithm works
* A = [ 1 , 2 , 3 , 4 , 5 ]
* B = [ 1 , 2 , 3 , 4 , 5 , 6 ]
* print median ( A ) # should be 39
* print median ( B ) # should be 4
*
* @ author [ Benjamin Weiss ] ( https : //github.com/weiss-ben)
*/
2022-09-17 08:40:03 +08:00
# include <iostream> /// for IO operations
# include <cassert> /// for assert
2022-09-10 22:52:27 +08:00
/**
* Definition for singly - linked list .
*/
struct ListNode {
2022-09-16 00:47:59 +08:00
int val ; ///< the value stored in the node
ListNode * next ; ///< pointer to the next node
ListNode ( ) : val ( 0 ) , next ( nullptr ) { } ///< default constructor
ListNode ( int x ) : val ( x ) , next ( nullptr ) { } ///< constructor with value for node->val provided
ListNode ( int x , ListNode * next ) : val ( x ) , next ( next ) { } ///< constructor with values provided for node->val and node->next
2022-09-10 22:52:27 +08:00
} ;
/**
* @ namespace search
* @ brief Search algorithms
*/
namespace search {
/**
* @ namespace median_search
2022-09-16 01:34:03 +08:00
* @ brief Functions for the Median Search algorithm implementation . Wkipedia link to algorithm : https : //en.wikipedia.org/wiki/Median_search
2022-09-10 22:52:27 +08:00
*/
namespace median_search2 {
/**
* This function searches for the median of a linked list .
2022-09-14 05:41:48 +08:00
* @ param head The head of the linked list .
2022-09-10 22:52:27 +08:00
* @ returns Median node of the linked list .
*/
ListNode * middleNode ( ListNode * head ) {
if ( ! head )
return nullptr ;
//Fast and slow pointers
ListNode * fastptr ;
ListNode * slowptr = fastptr = head ;
// fast jumps 2 while slow jumps 1
while ( fastptr - > next & & fastptr - > next - > next ) {
slowptr = slowptr - > next ;
fastptr = fastptr - > next - > next ;
}
return ( fastptr - > next ) ? slowptr - > next : slowptr ;
}
} // namespace median_search2
} // namespace search
/**
2022-09-12 19:11:15 +08:00
* @ brief Self - test implementations
* @ returns void
2022-09-10 22:52:27 +08:00
*/
2022-09-12 19:11:15 +08:00
static void test ( ) {
2022-09-10 22:52:27 +08:00
ListNode * head = new ListNode ;
head - > val = 1 ;
ListNode * temp1 = head ;
for ( int i = 1 ; i < 6 ; + + i )
{
ListNode * temp2 = new ListNode ;
temp2 - > val = i ;
temp1 - > next = temp2 ;
temp1 = temp2 ;
}
ListNode * median = search : : median_search2 : : middleNode ( head ) ;
assert ( 3 = = median - > val ) ; // 3 is the value of the median node.
std : : cout < < " test case:1 passed \n " ;
// Clean up
while ( head )
{
ListNode * t = head - > next ;
delete head ;
}
2022-09-12 19:26:23 +08:00
head = new ListNode ;
2022-09-10 22:52:27 +08:00
head - > val = 1 ;
2022-09-12 19:26:23 +08:00
temp1 = head ;
2022-09-10 22:52:27 +08:00
for ( int i = 1 ; i < 7 ; + + i )
{
ListNode * temp2 = new ListNode ;
temp2 - > val = i ;
temp1 - > next = temp2 ;
temp1 = temp2 ;
}
2022-09-12 19:26:23 +08:00
median = search : : median_search2 : : middleNode ( head ) ;
2022-09-10 22:52:27 +08:00
assert ( 4 = = median - > val ) ; // 3 is the value of the median node.
std : : cout < < " test case:1 passed \n " ;
// Clean up
while ( head )
{
ListNode * t = head - > next ;
delete head ;
}
2022-09-12 19:26:23 +08:00
std : : cout < < " test case:2 passed \n " ;
2022-09-10 22:52:27 +08:00
std : : cout < < " --All tests passed-- \n " ;
}
/**
2022-09-12 19:11:27 +08:00
* @ brief Main function
* @ returns 0 on exit
2022-09-10 22:52:27 +08:00
*/
int main ( )
{
2022-09-12 19:11:37 +08:00
test ( ) ; // run self-test implementations
2022-09-10 22:52:27 +08:00
return 0 ;
}