#include <iostream>
#include <ctime>
using namespace std;
// const int len = 100;
// int a[len]; //在调试时,为了能够关注到数组a中的变化,可将其声明为全局变量,同时,不能和函数内的局部变量同名,否则仍然看不到内容。
//冒泡排序
template <class Type>
void bubble_Sort(Type a[],int p,int r);
//************************************
// Method: partition 在arr[low:high]中以x为枢轴所确定的位置
// FullName: partition
// Access: public
// Returns: int
// Qualifier:
// Parameter: Type arr[]
// Parameter: int low
// Parameter: int high
// Parameter: Type x
//************************************
template <class Type>
int partition(Type arr[],int low,int high,Type x)
{ //注意这个函数不要用《算法分析与设计》上的思想来写,最好用《数据结构》上的来。
Type temp = arr[low];
while (low < high)
{
while (low<high && arr[high]>=x)--high;
arr[low] = arr[high];
while (low<high && arr[low]<=x)++low;
arr[high] = arr[low];
}
arr[low] = temp;
return low;
}
//************************************
// Method: partition 在arr[low:high]中以arr[low]为枢轴所确定的位置
// FullName: partition
// Access: public
// Returns: int
// Qualifier:
// Parameter: Type arr[]
// Parameter: int low
// Parameter: int high
//************************************
template <class Type>
int partition(Type arr[], int low, int high)
{
int i = low;
int j = high + 1;
Type x = arr[low];
while (true)
{
while (arr[++i]<x);
while (arr[--j]>x);
if (i>=j)
break;
swap(arr[i], arr[j]);
}
arr[low] = arr[j];
arr[j] = x;
return j;
}
//************************************
// Method: partition_2 思想:显然元素x是在arr中的,故找到它所在位置,并与arr[low]互换位置
// 就可看做是以arr[low]为枢轴来划分了
// FullName: partition_2
// Access: public
// Returns: int
// Qualifier:
// Parameter: Type arr[]
// Parameter: int low
// Parameter: int high
// Parameter: Type x
//************************************
template <class Type>
int partition_2(Type arr[],int low,int high,Type x)
{
for (int i=low; i<high; ++i)
{
if (arr[i]==x)
{
swap(arr[low], arr[i]);
break;
}
}
return partition(arr, low, high); //此时可以利用arr[low]为枢轴来划分
}
template <class Type>
int compare(const void * p, const void *q)
{
return *(Type*)p - *(Type*)q;
}
//************************************
// Method: select_my 在数组arr[low:high]中选择第k小的元素
// FullName: select_my
// Access: public
// Returns: Type
// Qualifier:
// Parameter: Type arr[]
// Parameter: int low
// Parameter: int high
// Parameter: int k
//************************************
template<class Type>
Type select_my(Type arr[], int low, int high, int k)
{
if (high - low < 75)
{//此时使得当元素个数小于75时,select具有排序功能
// qsort(arr, high - low +1, sizeof(Type),compare<Type>); //这里的compare<Type>尤其要注意!!模板函数的特化,深刻理解Type是类型参数
bubble_Sort(arr, low, high);
return arr[low+k-1];
}
for (int i=0;i<=(high-low-4)/5; ++i)
{
// select_my(arr, low+5*i, low+5*i+4, 3); //此处也可以用select来排序,因为元素个数小于75
bubble_Sort(arr, low+5*i, low+5*i+4);
swap(arr[low+5*i+2], arr[low+i]);
cout <<"中位数:" << arr[low+i] << ' ';
}
cout << endl;
Type x ;
if ((low+(high-low-4)/5 - low +1)%2==0)
x = select_my(arr, low, low+(high-low-4)/5, (high-low-4)/10+1);
else
x = select_my(arr, low, low+(high-low-4)/5, (high-low-4)/10);
cout << "中位数的中位数X=" << x << endl;
int location = partition(arr, low, high,x); //int location = partition_2(arr, low, high,x); //success
cout <<"以中位数的中位数为基准来划分,位置为" <<location << endl;
int j = location-low+1;
if (k <= j)
return select_my(arr,low,location, k);
else
return select_my(arr, location+1, high, k-j);
}
//冒泡排序
template <class Type>
void bubble_Sort(Type a[],int p,int r)
{
bool exchange;
for(int i=0; i<=r-p+1;i++)
{
exchange = false ;
for(int j=p; j<r-i; j++)
{
if(a[j]>a[j+1])
{
swap(a[j], a[j+1]);
exchange = true;
}
}
//如果这次遍历没有元素的交换,那么排序结束
if(false == exchange)
{
break ;
}
}
}
int main()
{
const int len = 100;
int a[len]; //在调试时,为了能够关注到数组a中的变化,可将其声明为全局变量,同时,不能和函数内的局部变量同名,否则仍然看不到内容。
cout << "起初数组中的元素为:" << endl;
for (int i=0; i<len; ++i)
{
a[i] = len - i;
cout << a[i] << ' ';
}
cout << endl;
int k = 48;
cout <<"第"<< k << "小的元素为:"<< select_my(a, 0, len-1, k) << endl;
// qsort(arr, sizeof(arr)/sizeof(int), sizeof(int), compare<int>); //success
cout << "此时数组中的元素为:"<< endl;
for (int i=0; i<len; ++i)
{
cout << "a[" <<i<< "]:"<<a[i] << ' ';
}
return 0;
}