排序稳定性:
稳定的排序算法有:冒泡、插入、归并、桶排序
不稳定的算法:快排、选择、堆排
1.计数排序(只能排序正整数)
1.计数排序不基于比较,准备max值+1个桶;
2.遍历数组,数值为a时,把桶位置为a的数加一;
3.重构数组。
class Solution {
public:
vector<int> sortArray(vector<int>& nums) {
int maxn=INT_MIN;
for(int i=0;i<nums.size();i++){
maxn=max(maxn,nums[i]);
}
vector<int> bucket(maxn+1,0);
for(int i=0;i<nums.size();i++){
bucket[nums[i]]++;
}
int j=0;
for(int i=0;i<bucket.size();i++){
while(bucket[i]--){
nums[j++] = i;
}
}
return nums;
}
};
2.应用
给定一个数组,求如果排序之后,相邻两数的最大差值,要求时间复杂度O(N),且要求不能用非基于比较的排序。
1.假设有N个数,则准备N+1个桶;
2.遍历,得到最大max、最小值min,若相等,则返回0;
3.最大值max和最小值min分别放在[N]和[0]桶位置;
4.将max~min N+1等分,中间某个元素属于哪个范围就放置进去,中间必然存在一个空桶;
5.准备三个长度为N+1的数组,分别为nmax[],nmin[] ,nempty[]。表示当前位置桶内的最大值、最小值和桶是否为空。把数组填入N+1个桶中,更新最大值、最小值;
6.从1号桶开始,如果桶为空则继续下一个,若桶非空找前一个非空桶的最大值和当前桶的最小值求差值。
#include<iostream>
#include <algorithm>
#include <windows.h>
#define length 10
using namespace std;
int main(){
int nums[length]={-4,18,1,23,3,52,7,9,66,11} ;
int minm=INT_MAX;
int maxm=INT_MIN;
//找到最大最小值
for(int i=0;i<length;i++){
minm=minm<nums[i]?minm:nums[i];
maxm=maxm>nums[i]?maxm:nums[i];
}
//三个数组,是否为空、最大、最小值
//一定,一定,一定要初始化为0!!!
bool mempty[length+1]={0};
int mmax[length+1]={0};
int mmin[length+1]={0};
for(int i=0;i<length+1;i++){
//该数在哪一个桶里(这个公式有待商榷)
int a = (nums[i]-minm)*(length+1) / (maxm-minm);
//桶为空,则最大最小值=该数
if(mempty[a]==0){
mmax[a]=nums[i];
mmin[a]=nums[i];
mempty[a]=1;
//不为空则更新
}else{
mmax[a]=mmax[a]>nums[i]?mmax[a]:nums[i];
mmin[a]=mmin[a]<nums[i]?mmin[a]:nums[i];
}
}
//桶不为空,则计算和前一个非空桶的差值,不断更新
int large=mmax[0],res=0;
for(int i=0;i<length+1;i++){
if(mempty[i]!=0){
res=max(res,mmin[i]-large);
large=mmax[i];
}
}
cout<<res<<endl;
system("pause");
}