选择排序、快速排序、希尔排序、堆排序不是稳定的排序算法,而冒泡排序、插入排序、归并排序、计数排序(注意倒着插入)、桶排序和基数排序是稳定的排序算法
-
冒泡、选择、插入、归并、希尔、堆排序都是基于比较的排序
平均时间复杂度最低O(nlogn) -
计数排序、桶排序、基数排序不是基于比较的排序
使用空间换时间,某些时候,平均时间复杂度可以低于O(nlog)
class Solution {
public:
vector<int> sortArray(vector<int>& nums) {
// quicksort(nums,0,nums.size()-1);
// build(nums,nums.size());
// shellsort(nums,nums.size());
// countsort(nums);
// insertsort(nums);
// selectsort(nums);
// bucketsort(nums,100000);
// mergesort(nums,0,nums.size()-1);
// bubblesort(nums);
radixsort(nums,10);
return nums;
}
//插入排序 最好O(N), 稳定排序
void insertsort(vector<int> & nums)
{
for(int i = 1;i < nums.size(); i ++) {
int tmp = nums[i];
int j = i-1;
while(j >= 0 && nums[j] > tmp) {
nums[j+1] = nums[j];
j--;
}
nums[j+1] = tmp;
}
}
//冒泡排序 稳定排序
void bubblesort(vector<int>& nums)
{
for(int i = 0;i < nums.size(); i ++) {
for(int j = 1;j < nums.size() - i ; j ++) {
if(nums[j-1] > nums[j]) swap(nums[j-1],nums[j]);
}
}
}
//选择排序, 不稳定排序
void selectsort(vector<int> & nums)
{
for(int i = 0;i < nums.size(); i ++) {
int index = i;
for(int j = i + 1;j < nums.size(); j ++) {
if(nums[j] < nums[index]) index = j;
}
swap(nums[index],nums[i]);
}
}
//归并排序 稳定排序
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);
vector<int> tmp;
int i = l,j = mid+1;
while(i <= mid && j <= r) {
if(nums[i] < nums[j])
tmp.emplace_back(nums[i++]);
else
tmp.emplace_back(nums[j++]);
}
while(i <= mid) tmp.emplace_back(nums[i++]);
while(j <= r) tmp.emplace_back(nums[j++]);
for(int i = 0;i < r-l+1;i ++) nums[i+l] = tmp[i];
}
//快速排序,不稳定排序,最坏的时候是O(N^2)
void quicksort(vector<int>& nums,int l, int r)
{
if(l >= r) return;
int p = partition(nums,l,r);
cout << endl;
quicksort(nums,l,p-1);
quicksort(nums,p+1,r);
}
int partition(vector<int>& nums, int l,int r)
{
int val = nums[l];
while(l < r) {
while(l < r && nums[r] >= val) r --;
nums[l] = nums[r];
while(l < r && nums[l] <= val) l ++;
nums[r] = nums[l];
}
nums[l] = val;
return l;
}
// 堆排序,任何情况都是O(NlogN) 不稳定
void adjust(vector<int> & nums,int index,int size)
{
int l = 2*index+1;
int r = 2*index+2;
int maxid = index;
if(l <= size && nums[l] > nums[maxid]) maxid = l;
if(r <= size && nums[r] > nums[maxid]) maxid = r;
if(maxid == index) return;
swap(nums[index],nums[maxid]);
adjust(nums,maxid,size);
}
void build(vector<int>& nums,int size)
{
for(int i = size / 2 ; ~i; -- i) {
adjust(nums,i,size-1);
}
for(int i = size-1; i >= 1; -- i) {
swap(nums[0],nums[i]);
adjust(nums,0,i-1);
}
}
//希尔排序,不稳定排序
void shellsort(vector<int> &nums, int size)
{
for(int l = size/2; l >= 1; l /= 2) {
for(int i = l; i < size; i ++) {
if(nums[i] < nums[i-l]) {
int j = i - l;
int tmp = nums[i];
while(j >= 0 && nums[j] > tmp) {
nums[j+l] = nums[j];
j -= l;
}
nums[j+l] = tmp;
}
}
}
}
//计数排序 稳定排序
void countsort(vector<int>&nums) {
int maxv = *max_element(nums.begin(), nums.end());
int minv = *min_element(nums.begin(), nums.end());
vector<int> count(maxv - minv+1,0);
for(auto num : nums) count[num-minv] ++;
for(int i = 1;i <= maxv-minv;i ++) count[i] += count[i-1];
vector<int> tmp(nums.begin(),nums.end());
for(int i = tmp.size()-1;~i ;i --) { // 倒过来保持稳定
int pos = count[tmp[i] - minv];
nums[pos-1] = tmp[i];
count[tmp[i] - minv] --;
}
}
//桶排序 稳定排序
void bucketsort(vector<int>& nums,int k)
{
int maxv = *max_element(nums.begin(), nums.end());
int minv = *min_element(nums.begin(), nums.end());
int range = (maxv - minv + k - 1) / k;
range = max(range,1);
int cnt = 0;
vector<vector<int> > bucket(k+1,vector<int>(0));
for(auto num : nums) {
int id = (num - minv) / range;
bucket[id].emplace_back(num);
}
for(int i = 0;i <= k; i ++) {
sort(bucket[i].begin(),bucket[i].end());
for(int j = 0;j < bucket[i].size(); j ++) nums[cnt++] = bucket[i][j];
}
}
//基数排序 稳定排序
void radixsort(vector<int>& nums,int base)
{
vector<vector<int>> bucket;
int maxv = *max_element(nums.begin(),nums.end());
int minv = *min_element(nums.begin(), nums.end());
for(int i = 1; i <= maxv-minv; i = i * base) {
bucket.assign(base,vector<int>(0));
for(int j = 0;j < nums.size(); j ++) {
int index = (nums[j] - minv) / i % base;
bucket[index].emplace_back(nums[j]);
}
int cnt = 0;
for(int j = 0;j < base;j ++) {
for(int k = 0; k < bucket[j].size(); k ++) {
nums[cnt ++] = bucket[j][k];
}
}
}
}
};