class Solution {
public:
//堆排序
void heapsort(){//明天写
}
//归并排序函数
void mergesort(vector<int>& nums,int tmp[],int left,int right){
//printf("%d %d\n",left,right);
if(left>=right)
return;
int mid=(right+left)/2;
mergesort(nums,tmp,left,mid);
mergesort(nums,tmp,mid+1,right);
int begin1=left;
int end1=mid;
int begin2=mid+1;
int end2=right;
int i=left;
while(begin1<=end1&&begin2<=end2){
if(nums[begin1]>nums[begin2]){
tmp[i]=nums[begin2];
begin2++;
i++;
}
else{
tmp[i]=nums[begin1];
begin1++;
i++;
}
}
while(begin1<=end1){
tmp[i]=nums[begin1];
begin1++;
i++;
}
while(begin2<=end2){
tmp[i]=nums[begin2];
begin2++;
i++;
}
for(int i=left;i<=right;i++){ //把排好序的数组更新到原数组
nums[i]=tmp[i];
}
}
//快速排序函数
int quicksort(vector<int>& nums,int low,int high){
if(low>=high)
return -1;
int low_index=low;
int high_index=high;
int pivot=low;
while(low_index<high_index){ //左右指针移动直至重合
while(low_index<high_index && nums[high_index]>=nums[pivot]) //先移动high指针,直到找到一个比pivot小的,或者两个指针重合
high_index--;
while(low_index<high_index && nums[low_index]<=nums[pivot]) //移动low指针,直到找到一个比pivot大的,或者两个指针重合
low_index++;
int index=nums[high_index]; //high与low指针所指元素互换
nums[high_index]=nums[low_index];
nums[low_index]=index;
}
int index=nums[low_index]; //high与low重合后,将pivot元素与重合位置元素互换
nums[low_index]=nums[pivot];
nums[pivot]=index;
quicksort(nums,low_index+1,high); //使用pivot将数据分割成两部分,对每部分使用一次quicksort
quicksort(nums,0,low_index-1);
return low_index;
}
vector<int> sortArray(vector<int>& nums) {
//nums为待排序数组,nums.size()为数组长度
//升序排序
if(nums.size()==1) return nums;
//插入排序,稳定排序算法,时间复杂度O(n^2),空间复杂度O(1)
//算法思想:
//1.将序列分为有序序列和无序序列两部分,初始状态有序序列为空集,无序序列为全集
//2.每次将无序序列的第一个待排序元素插入到有序序列中合适的位置,循环操作直到无序序列为空,即全部排好序
//3.具体操作是,用一个临时变量保存待插入的元素值,将该值从后到前与有序数据比较,若不是合适的位置,则将比较的有序数据后移一位
//4.继续向前比较,直到找到合适的位置,插入到空位中
// for(int i=1;i<nums.size();i++){ //每次从无序集中选一个,第一个元素不用排序,从第二个开始
// int tmp=nums[i];//临时变量保存元素值
// int index=i; //保存当前元素索引
// while(index>=1&&nums[index-1]>tmp){ //找到合适的位置,将大于该值的元素依次前移一位
// nums[index]=nums[index-1];
// index--;
// }
// nums[index]=tmp; //最后把剩下的空位给tmp
// }
// return nums;
//选择排序,非稳定排序算法,时间复杂度O(n^2),空间复杂度O(1)
//算法思想:
//1.每次从待排序序列中选择一个最小(最大)的,与待排序序列第一个做交换,直至全部有序
// for(int i=0;i<nums.size()-1;i++){ //序列最后一个元素一定是最大(最小)的不需要操作
// int nums_min=99999999;
// int nums_min_index=0;
// for(int j=i;j<nums.size();j++){ //找到待排序序列中最小的
// if(nums[j]<nums_min){
// nums_min=nums[j];
// nums_min_index=j;
// }
// }
// nums[nums_min_index]=nums[i]; //和第一个元素做交换
// nums[i]=nums_min;
// }
// return nums;
//交换(冒泡)排序,稳定排序算法,时间复杂度O(n^2),空间复杂度O(1)
//算法思想:
//1.依次交换相邻的两个元素,如果逆序则交换,即交换(a1,a2),(a2,a3),(a3,a4)
//2.每次排序都使一个元素放置到正确的位置上,排序n次使全部有序
// int index=0;
// for(int i=0;i<nums.size();i++){
// for(int j=0;j<nums.size()-1;j++){
// if(nums[j]>nums[j+1]){
// index=nums[j];
// nums[j]=nums[j+1];
// nums[j+1]=index;
// }
// }
// }
// return nums;
//希尔排序(插入排序的改进版),非稳定排序算法,时间复杂度平均O(n^1.3),空间复杂度O(1)
//算法思想:
//1.将这组待排序元素按一定规则分成若干组(以gap为间隔),对每组内进行插入排序
//2.将组再次细分(gap=gap/3+1),对组内再次进行插入排序
//3.直至gap=1,间隔为1,退化成直接插入排序,但是组内基本有序,大大提高了插入排序的效率
// int gap=nums.size();
// while(gap>1){
// gap=gap/3+1;
// for(int i=0;i<nums.size()-gap+1;i++){//内层循环思想为一次插入排序,只不过元素间隔为gap,将插入排序中的“+-1”改为“+-gap”
// int tmp=nums[i];
// int index=i;
// while(index>=gap && nums[index-gap]>tmp){
// nums[index]=nums[index-gap];
// index=index-gap;
// }
// nums[index]=tmp;
// }
// }
// return nums;
//快速排序(交换排序的改进版),非稳定性排序,时间复杂度O(nlogn),空间复杂度O(1)
//算法思想:
//1.从这组待排序的数据中选择一个枢轴pivot,一般选择这组数据的第一个元素
//2.两个指针分别从首low,尾high出发,当low指针碰到第一个大于pivot的元素则停下,当high指针碰到第一个小于pivot的元素则停下
//3.low,high指针指向元素互换位置,然后继续按上述方式移动,知道low,high指针相遇
//4.将pivot的值与low,high指针相遇位置的值互换,则该序列满足,pivot左边的元素都比pivot小,右边的元素都比pivot大
//5.将pivot左边和右边划分为两个区域,对这两个区域递归的再次执行上述步骤
//6.排序结束
// quicksort(nums,0,nums.size()-1);
// return nums;
//归并排序,稳定性排序算法,时间复杂度O(nlogn),空间复杂度O(n)
//算法思想:
//1.新建一个辅助数组用来存储最后结果
//2.只要数组可分成两半,就把它分成两半
//3.直到只剩一个元素不可再分,就把左右两个数据按顺序摆放在新数组里
// int tmp[50005]={0};
// mergesort(nums,tmp,0,nums.size()-1);
// for(int i=0;i<nums.size();i++){
// nums[i]=tmp[i];
// }
// return nums;
//堆排序,非稳定性排序算法,时间复杂度O(nlogn),空间复杂度O(n)
}
};