#include <iostream>
using namespace std;
void swap(int array[], int beginPos, int endPos){
int t = array[beginPos];
array[beginPos] = array[endPos];
array[endPos]=t;
}
int partition(int array[], int begin, int end, int val)
{
int headCursor = begin;
int tailCursor = end;
while(true)
{
while(array[headCursor] < val && headCursor < end) headCursor++;
while(array[tailCursor] > val) tailCursor--;
if (headCursor >= tailCursor){break;}
swap(array, headCursor, tailCursor);
}
return tailCursor;
}
int partition2(int array[], int beginPos, int endPos)
{
int comparedVal = array[beginPos];
int cursorFromBegin = beginPos + 1;
int cursorFromEnd = endPos;
while(true){
while (array[cursorFromBegin] < comparedVal){cursorFromBegin++;}
while (array[cursorFromEnd] > comparedVal){cursorFromEnd--;}
if (cursorFromBegin>=cursorFromEnd){break;}
swap(array, cursorFromBegin, cursorFromEnd);
}
swap(array,cursorFromEnd,beginPos);
return cursorFromEnd;
}
void quickSort(int array[],int begin,int end){
if (begin >= end){cout<<begin<<":"<<end<<endl;return;}
int k = partition2(array,begin,end);
quickSort(array, begin,k-1);
quickSort(array, k+1, end);
}
int select_middle_element(int array[], int begin,int end, int k){
if (end - begin <=10){
quickSort(array, begin,end);
return array[(end+begin)/2];
}
int groupNum = (end-begin-4)/5;
int groupBegin = begin;
int groupEnd = begin + 4;
int arraybegin = begin;
for (int i = 0; i <groupNum;i++){
quickSort(array, groupBegin, groupEnd);
swap(array, arraybegin, (groupBegin+groupEnd)/2);
groupBegin = groupEnd + 1;
groupEnd = groupBegin +4;
arraybegin++;
}
int middleVal = select_middle_element(array, begin, begin+(groupNum-1), (groupNum/2));
cout<<"middle "<<middleVal<<endl;
int pos = partition(array, begin, end, middleVal);
int j = pos - begin;
cout<<"pos "<<pos<<endl;
cout<<"k "<<k<<endl;
cout<<"begin"<<begin<<endl;
for (int i = 0;i<=24;i++)
{
cout<<array[i]<<" ";
}
cout<<endl;
for (int i = begin;i<=end;i++)
{
cout<<array[i]<<" ";
}
cout<<endl;
if (k > j){
return select_middle_element(array, pos, end, k-j);
}else if (k==j){return array[k+begin];}
else{
return select_middle_element(array, begin, pos, k);
}
return k;
}
int main(){
int array[25]={4,7,1,2,3,
9,8,10,13,56,
90,100,877,900,1000,
30,89,40,45,28,
85};
cout<<"middle value"<<select_middle_element(array, 0, 20, 10)<<endl;
quickSort(array, 0, 20);
/*1 if n <=75, get the middle element .*/
/*1 divide the n elements into n-4/5 gorups, find the middle element of each group
(every group only have 5 elements), and find the middle element among the middle elements
of each group, and then kick out those elements that are not possible*/
for (int i = 0;i<=20;i++)
{
cout<<i<<":"<<array[i]<<endl;
}
}