三数取中:作为枢纽 防止卡时间复杂度
插排:排序个数少时可以优化时间复杂度
聚集相等元素:减少重复排序的时间浪费
#include<iostream>
using namespace std;
int array[100005];
int arr[1000005]={0};
/*函数作用:取待排序序列中low、mid、high三个位置上数据,选取他们中间的那个数据作为枢轴*/
int SelectPivotMedianOfThree(int arr[],int low,int high)
{
int mid = low + ((high - low) >> 1);//计算数组中间的元素的下标
//使用三数取中法选择枢轴
if (arr[mid] > arr[high])//目标: arr[mid] <= arr[high]
{
swap(arr[mid],arr[high]);
}
if (arr[low] > arr[high])//目标: arr[low] <= arr[high]
{
swap(arr[low],arr[high]);
}
if (arr[mid] > arr[low]) //目标: arr[low] >= arr[mid]
{
swap(arr[mid],arr[low]);
}
//此时,arr[mid] <= arr[low] <= arr[high]
return arr[low];
//low的位置上保存这三个位置中间的值
//分割时可以直接使用low位置的元素作为枢轴,而不用改变分割函数了
}
void InsertSort(int arr[], int low, int high)
{
int len=high-low+1;
int temp;//保存要插入的元素
int j;//从当前要要比较插入的元素的前面一个开始
for (int i = 1; i < len; i++)//第一个元素视为有序,把后面的元素一个一个的插入到前面
{
temp = arr[i];
j = i - 1;
while (j >= 0&&arr[j]>temp)
{
arr[j + 1] = arr[j];//前面的元素往后面移动
j--;
}
arr[j + 1] = temp;//把要插入的元素,插入进对应的位置
}
}
void QSort(int arr[],int low,int high)
{
int first = low;
int last = high;
int left = low;
int right = high;
int leftLen = 0;
int rightLen = 0;
if (high - low + 1 < 10)
{
InsertSort(arr,low,high);
return;
}
//一次分割
int key = SelectPivotMedianOfThree(arr,low,high);//使用三数取中法选择枢轴
while(low < high)
{
while(high > low && arr[high] >= key)
{
if (arr[high] == key)//处理相等元素
{
swap(arr[right],arr[high]);
right--;
rightLen++;
}
high--;
}
arr[low] = arr[high];
while(high > low && arr[low] <= key)
{
if (arr[low] == key)
{
swap(arr[left],arr[low]);
left++;
leftLen++;
}
low++;
}
arr[high] = arr[low];
}
arr[low] = key;
//一次快排结束
//把与枢轴key相同的元素移到枢轴最终位置周围
int i = low - 1;
int j = first;
while(j < left && arr[i] != key)
{
swap(arr[i],arr[j]);
i--;
j++;
}
i = low + 1;
j = last;
while(j > right && arr[i] != key)
{
swap(arr[i],arr[j]);
i++;
j--;
}
QSort(arr,first,low - 1 - leftLen);
QSort(arr,low + 1 + rightLen,last);
}
int main()
{
int n;
cin>>n;
for(int i=0;i<n;i++)
cin>>array[i];
QSort(array,0,n-1);
for (int i=0;i<n;i++)
cout << array[i] << " ";
return 0;
}