leetcode链接:https://leetcode-cn.com/problems/sort-an-array/
注:时间复杂度O(n^2)的均超时
冒泡排序
时间复杂度O(n^2), 空间复杂度O(1)
vector<int> bubble(vector<int>& nums){
for(int i = 0; i < nums.size(); i++)
{
for(int j = 0; j < nums.size() - i -1; j++)
{
if(nums[j] > nums[j+1]) swap(nums[j],nums[j+1]);
}
}
return nums;
}
选择排序
时间复杂度O(n^2), 空间复杂度O(1)
vector<int> select(vector<int>& nums)
{
for(int i=0; i<nums.size() - 1; i++)
{
for(int j = i + 1; j<nums.size(); j++)
{
if(nums[i] > nums[j]) swap(nums[i], nums[j]);
}
}
return nums;
}
插入排序
时间复杂度O(n^2), 空间复杂度O(1)
vector<int> insertion(vector<int>& nums)
{
for(int i=1; i<nums.size(); i++)
{
int j = i - 1;
int flag = nums[i];
while(j >= 0 && nums[j] > flag)
{
nums[j+1] = nums[j];
j--;
}
nums[j+1] = flag;
}
return nums;
}
希尔排序
时间复杂度介于O(n^2)到O(nlogn)之间, 空间复杂度O(1)
vector<int> insertion(vector<int>& nums)
{
for(int i=1; i<nums.size(); i++)
{
int j = i - 1;
int flag = nums[i];
while(j >= 0 && nums[j] > flag)
{
nums[j+1] = nums[j];
j--;
}
nums[j+1] = flag;
}
return nums;
}
随机选取间隔一遍是数组长度的一半,然后每次减1,每个组中用插入排序,直到间隔为1.
归并排序
时间复杂度O(nlogn), 空间复杂度O(n) ,是稳定的算法
vector<int> tmp;
void mergeSort(vector<int>& nums, int l, int r)
{
if(l >= r) return;
int mid = (l + r)>>1;
mergeSort(nums, l, mid);
mergeSort(nums, mid+1, r);
int i = l, j = mid + 1;
int cnt = 0;
while(i <= mid && j <=r){
if(nums[i] <= nums[j])
{
tmp[cnt++] = nums[i++];
}
else tmp[cnt++] = nums[j++];
}
while(i <= mid)
{
tmp[cnt++] = nums[i++];
}
while(j <= r)
{
tmp[cnt++] = nums[j++];
}
for(int i = 0; i <r - l + 1; i++)
{
nums[i + l] = tmp[i];
}
}
vector<int> merge(vector<int>& nums)
{
tmp.resize((int)nums.size(), 0);
mergeSort(nums, 0, nums.size()-1);
return nums;
}
分而治之思想的体现。
堆排序
时间复杂度O(nlogn), 空间复杂度O(1) ,是不稳定的算法
void heapify(vector<int>& nums, int n, int idx)
{
int max = idx;
int l = 2 * idx + 1;
int r = 2 * idx + 2;
if(l < n && nums[max] < nums[l]) max = l;
if(r < n && nums[max] < nums[r]) max = r;
if(max != idx)
{
swap(nums[max], nums[idx]);
heapify(nums, n, max);
}
return;
}
vector<int> heap_sort(vector<int>& nums)
{
//建堆
for(int i = nums.size()/2 - 1; i>=0; i--)
{
heapify(nums, nums.size(), i);
}
//排序
for(int i = nums.size() - 1; i>0; i--)
{
swap(nums[i], nums[0]);
cout<<nums[i]<<endl;
heapify(nums, i, 0);
}
return nums;
}
大顶堆的概念要明确,就是父亲比左孩子和右孩子数值大。小顶堆就是反过来。