各种排序算法:
1.快排 时间复杂度O(nlogn),最坏O(n2),空间复杂度最好logn,.最坏n
void quick_sort(vector<int>& b, int l, int r)
{
if (l >= r) return;
int base = b[l];
int i = l;
int j = r;
while (i < j)
{
while (i < j && b[j] >= base) j--;
if (i < j) b[i] = b[j];
while (i < j && b[i] < base) i++;
if (i < j) b[j] = b[i];
}
b[i] = base;
quick_sort(b, l, i-1);
quick_sort(b, i+1, r);
}
2.插入排序 O(n2),稳定,原地排序
void insert_sort(vector<int>& nums)
{
int len = nums.size();
for (int i = 1; i < len; i++)
{
int a = nums[i];
int j = i - 1;
for (; j >= 0; j--)
{
if (nums[j] > a) nums[j+1] = nums[j];
else break;
}
nums[j+1] = a;
}
}
3.折半插入排序:仅仅减少了比较的次数 O(n2), 原地排序
void insert_sort2(vector<int>& a ) // 加入了二分查找的插入排序
{
int len = a.size();
for (int i = 1; i < len; i++)
{
if (a[i - 1] > a[i])
{
int st = 0;
int ed = i - 1;
int base = a[i];
while (st <= ed)
{
int mid = st + ((ed - st) >> 1);
if (a[mid] > base) ed = mid - 1;
else st = mid + 1;
}
for (int j = i; j > ed + 1; j--) a[j] = a[j - 1];
a[ed + 1] = base;
}
}
}
4.选择排序 O(n2),不稳定
void select_sort(vector<int>& nums)
{
int len = nums.size();
for (int i = 0; i < len; i++)
{
int k = i;
for (int j = i+1; j < len; j++)
{
if (nums[j] < nums[k]) k = j;
}
if (k != i) swap(nums[i], nums[k]);
}
}
5.归并排序
void merge(vector<int>& nums, int st, int mid, int ed)
{
int len = ed - st + 1;
vector<int> tmp(len, 0);
int i = st;
int j = mid + 1;
int t = 0;
while (i <= mid && j <= ed)
{
if (nums[i] <= nums[j]) tmp[t++] = nums[i++];
else tmp[t++] = nums[j++];
}
while (i <= mid) tmp[t++] = nums[i++];
while (j <= ed) tmp[t++] = nums[j++];
for (int i = 0; i < len; i++) nums[i+st] = tmp[i];
}
void sort(vector<int>& nums, int st, int ed)
{
if (st < ed)
{
int mid = st + ((ed-st)>>1);
sort(nums, st, mid);
sort(nums, mid+1, ed);
merge(nums, st, mid, ed);
}
}
6.希尔排序 O(n^1.3) 到 O(n2) 不稳定, 4 1 1 3
void shell_sort(vector<int>& nums)
{
int len = nums.size();
int gap = len/2;
while (gap >= 1)
{
for (int i = gap; i < len; i++)
{
int j = i - gap;
int a = nums[i];
for (; j >= 0; j = j - gap)
{
if (nums[j] > a) nums[j+gap] = nums[j];
else break;
}
nums[j+gap] = a;
}
gap /= 2;
}
}
7.堆排序 O(nlogn),不稳定
void build(vector<int>& nums, int i, int len)
{
int ll = 2*i + 1;
int rr = 2*i + 2;
int mid = i;
if (ll < len && nums[ll] > nums[mid]) mid = ll;
if (rr < len && nums[rr] > nums[mid]) mid = rr;
if (mid != i)
{
swap(nums[i], nums[mid]);
build(nums, mid, len);
}
}
void sort(vector<int>& nums)
{
int len = nums.size();
for (int i = len/2; i >= 0; i--)
{
build(nums, i, len);
}
for (int i = len-1; i >= 0; i--)
{
swap(nums[0], nums[i]);
build(nums, 0, i);
}
}
8. 基数排序
9.桶排序 时间复杂度 假设有n个数,m个桶,那么复杂度为 O(n+n/m*mlog(n/m)) = O(n+nlogn/m) 空间复杂度 O( n+m)
一个参考链接如下:https://www.jianshu.com/p/e6ba35133375
基于m个桶的实现 https://blog.csdn.net/shengqianfeng/article/details/100074146
桶排序是稳定的排序算法吗?
由于桶排序是如果基于快排实现,就不是稳定的排序算法。
如果是基于归并排序实现的,则可以完成稳定的排序。
void sort(vector<int>& nums)
{
int MIN = INT_MAX;
int MAX = INT_MIN;
for (int i = 0; i < nums.size(); i++)
{
if (nums[i] > MAX) MAX = nums[i];
if (nums[i] < MIN) MIN = nums[i];
}
vector<int> vec(MAX-MIN+1, 0);
for (int i = 0; i < nums.size(); i++) vec[nums[i]-MIN]++;
int t = 0;
int len = nums.size();
vector<int> vec0(len, 0);
for (int i = 0; i <= MAX-MIN; i++)
{
while ((vec[i]--) > 0) vec0[t++] = i+MIN;
}
nums = vec0;
}
10. 计数排序 (稳定,O(n+k)
void jishu(vector<int>& nums)
{
int min = nums[0];
int max = nums[0];
int len = nums.size();
for (int i = 0; i < len; i++)
{
if (nums[i] > max) max = nums[i];
if (nums[i] < min) min = nums[i];
}
int gap = max - min + 1;
vector<int> tmp(gap, 0);
for (int i = 0; i < nums.size(); i++) tmp[nums[i]-min]++;
for (int i = 1; i < gap; i++) tmp[i] += tmp[i-1];
vector<int> c(len, 0);
for (int i = len - 1; i >= 0; i--)
{
int index = nums[i] - min;
c[--tmp[index]] = nums[i];
}
nums = c;
}
最后附上一张图