总结各种常见的排序算法,参考leetcode912题
一、简单排序算法
1.选择排序
任何情况下都要遍历n²次,效率低下。
vector<int> sortArray(vector<int>& nums) {
//选择排序
selectionSort(nums,nums.size());
return nums;
}
void selectionSort(vector<int>& nums, int n)
{
for(int i = 0; i < n; i++)
{
//寻找[i,n)中的最小值
int minIndex = i;
for(int j = i+1; j < n; j++)
if(nums[j] < nums[minIndex])
minIndex = j;
swap(nums[i],nums[minIndex]);
}
}
2.插入排序(洗牌的思想)
最差时间复杂度为n²,但是在数据近乎有序的情况下时间复杂度只有n,效率很高(因为可以提前终止循环),有时候甚至优于nlogn级别的排序算法。
vector<int> sortArray(vector<int>& nums) {
//插入排序
insertionSort(nums,nums.size());
return nums;
}
void insertionSort(vector<int>& nums, int n)
{
for(int i = 1; i < n; i++)
{
//寻找nums[i]合适的插入位置
for(int j = i; j > 0; j--)
{
if(nums[j] < nums[j-1])
swap(nums[j],nums[j-1]);
else
break;
}
}
}
二、高级排序算法
1.归并排序
空间复杂度为n,时间复杂度nlogn。
vector<int> sortArray(vector<int>& nums) {
//归并排序
int n = nums.size();
mergesort(nums,0,n-1);
return nums;
}
//递归使用归并排序,对nums[l...r]的范围进行排序
void mergesort(vector<int>& nums, int l, int r)
{
if(l >= r)
return ;
int mid = l + ( r - l ) / 2;
mergesort(nums,l,mid);
mergesort(nums,mid+1,r);
merge(nums,l,mid,r);
}
//将nums[l...mid]和nums[mid+1...r]两部分进行归并
void merge(vector<int>& nums, int l, int mid, int r)
{
vector<int> aux(r-l+1,-1);
for(int i = l; i <= r; i++)
aux[i-l] = nums[i];
int i = l, j = mid+1;
for(int k = l; k <= r; k++)
{
if(i > mid)
{
nums[k] = aux[j-l];
j++;
}
else if(j > r)
{
nums[k] = aux[i-l];
i++;
}
else if(aux[i-l] < aux[j-l])
{
nums[k] = aux[i-l];
i++;
}
else
{
nums[k] = aux[j-l];
j++;
}
}
}
2.快速排序
最坏情况,数据近乎有序的情况,时间复杂度为n²。
vector<int> sortArray(vector<int>& nums) {
//快速排序
int n = nums.size();
quicksort(nums,0,n-1);
return nums;
}
//对nums[l...r]部分进行快速排序
void quicksort(vector<int>& nums, int l, int r)
{
if(l >= r)
return ;
int base = nums[l];
int i = l, j = r;
while(i < j)
{
while(i<j && nums[j]>=base)
j--;
while(i<j && nums[i]<=base)
i++;
if(i < j)
swap(nums[i],nums[j]);
}
nums[l] = nums[i];
nums[i] = base;
quicksort(nums,l,i-1);
quicksort(nums,i+1,r);
}