1.排序算法基础知识
1.1排序算法分类
十种常见排序算法可以分为两大类:
比较类排序:通过比较来决定元素间的相对次序,由于其时间复杂度不能突破O(nlogn),因此也称为非线性时间比较类排序。
非比较类排序:不通过比较来决定元素间的相对次序,它可以突破基于比较排序的时间下界,以线性时间运行,因此也称为线性时间非比较类排序。
1.2 算法复杂度
1.3 知识点
稳定:如果a原本在b前面,而a=b,排序之后a仍然在b的前面。
不稳定:如果a原本在b的前面,而a=b,排序之后 a 可能会出现在 b 的后面。
时间复杂度:对排序数据的总的操作次数。反映当n变化时,操作次数呈现什么规律。
空间复杂度:是指算法在计算机内执行时所需存储空间的度量,它也是数据规模n的函数
注:对于排序算法,我们多数情况下只考虑它的时间复杂度,而对于空间复杂度则可以放宽松一些
2.排序算法分析
/*by kzl*/
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<queue>
#include<stack>
#include<vector>
using namespace std;
const int maxx = 1e5+500;
const int INF = 0x3f3f3f3f;
typedef long long LL;
void print(int arr[],int n){
for(int i=0;i<n;i++){
cout<<arr[i]<<" ";
}
cout<<endl;
}
//冒泡排序,每一轮比较相邻位置,如果逆序则交换。
void BubbleSort(int arr[],int n){
for(int i=1;i<n;i++){
for(int j = 0;j<n-i;j++){
if(arr[j]>arr[j+1])swap(arr[j+1],arr[j]);
}
}
}
//选择排序,每一轮选择最小值放到数组的最前面
void selectSort(int arr[],int n){
for(int i=0;i<n;i++){
for(int j=i+1;j<n;j++){
if(arr[i]>arr[j])swap(arr[i],arr[j]);
}
}
}
//插入排序,保证当前元素之前的元素有序,然后看当前元素能够插入到前面的哪个位置。
void insertSort(int arr[],int n){
for(int i=1;i<n;i++){
int temp = arr[i];
int j = i-1;
while(temp<arr[j]&&j>=0)j--;
for(int k = i-1;k>j;k--)arr[k+1] = arr[k];
arr[j+1] = temp;
}
}
//快速排序,选一个基值,然后从后面遍历,比他小的放前面,从前面遍历,比他大放后面,不断挖坑填坑。
int partitionsort(int arr[],int le,int ri)
{
int l = le,r = ri;
int temp = arr[l];
while(l<r){
while(l<r&&arr[r]>temp)r--;
if(l<r)arr[l] = arr[r];
while(l<r&&arr[l]<=temp)l++;
if(l<r)arr[r] = arr[l];
// cout<<l<<" "<<r<<endl;
}
arr[l] = temp;
return l;
}
void quickSort(int arr[],int le,int ri)
{
if(le>ri)return ;
int mid = partitionsort(arr,le,ri);
quickSort(arr,le,mid-1);
quickSort(arr,mid+1,ri);
}
//堆排序,先构建一个最大堆,然后依次交换最大值和数组最末位置的值,保证数组有序。
void heapAdjust(int arr[],int sta,int en)
{
int temp = arr[sta];
for(int i=2*sta+1;i<=en;i++)
{
if(arr[i]<arr[i+1]&&i<en)i++;
if(temp>=arr[i])break;
arr[sta] = arr[i];
sta = i;
}
arr[sta] = temp;
}
void heapSort(int arr[],int n)
{
for(int i = (n)/2;i>=0;i--){
heapAdjust(arr,i,n-1);
}
for(int i=n-1;i>=0;i--){
swap(arr[i],arr[0]);
heapAdjust(arr,0,i-1);
}
}
//希尔排序,其实就是插入排序,不过是间隔为D的序列中进行的
void shellInsert(int arr[],int d,int n){
for(int i=d;i<n;i++){
int j = j-d;
int temp = arr[i];
while(j>=0&&arr[j]>temp)
{
arr[j+d] = arr[j];
j -= d;
}
arr[j+d] = temp;
}
}
void ShellSort(int arr[],int n)
{
int d = n/2;
while(d>=1){
shellInsert(arr,d,n);
d/=2;
}
}
//归并排序,先不断的分割区间,至区间只有两个元素,然后在不断地合并子区间
void Mymerge(int arr[],int le,int ri,int ll,int rr){
int temp[1000];int k = 0;
int sta = le,en = rr;
while(le<=ri&&ll<=rr){
if(arr[le]<arr[ll])temp[k++] = arr[le++];
else temp[k++] = arr[ll++];
}
while(le<=ri)temp[k++] = arr[le++];
while(ll<=rr)temp[k++] = arr[ll++];
for(int i = sta;i<=en;i++){
arr[i] = temp[i-sta];
}
}
void mergeSort(int arr[],int le,int ri){
if(le>=ri)return ;
int mid = (le+ri)>>1;
mergeSort(arr,le,mid);
mergeSort(arr,mid+1,ri);
Mymerge(arr,le,mid,mid+1,ri);
}
//基数排序,对一列数字,先根据个位进行排序,然后根据十位进行排序。。依次
int getbit(int x){
int bit = 0;
while(x>0)
{
x/=10;
bit++;
}
return bit;
}
//获取数组中最大的数的位数
int maxbit(int arr[],int n)
{
int ma = -1;
for(int i=0;i<n;i++){
ma = max(ma,getbit(arr[i]));
}
return ma;
}
void radixSort(int arr[],int n)
{
int bit = maxbit(arr,n);
int coun[10],tmp[1000];
int radio = 1;
for(int i=0;i<bit;i++){
memset(coun,0,sizeof(coun));
for(int j=0;j<n;j++){
int k = (arr[j]/radio)%10;
coun[k]++;
}
for(int j = 1;j<10;j++){
coun[j] = coun[j] + coun[j-1];
}
for(int j=n-1;j>=0;j--){
int k = (arr[j]/radio)%10;
tmp[coun[k]-1] = arr[j];
coun[k]--;
}
for(int j=0;j<n;j++){
arr[j] = tmp[j];
}
radio= radio * 10;
}
}
//计数排序,将数字映射成数组下标,然后遍历一遍就可知道其所在位置。
void CountSort(int arr[],int n)
{
int temp[1000];//能进行1000以内数字的排序,取决于数字范围,如有需要,可增大。
memset(temp,0,sizeof(temp));
int ma = -1;
for(int i=0;i<n;i++){
temp[arr[i]]++;
ma = max(ma,arr[i]);
}
int k = 0;
for(int i=0;i<=ma;i++){
for(int j=0;j<temp[i];j++){
arr[k++] = i;
}
}
}
//桶排序,计数排序的升级版,实际上计数排序就是桶的个数十分多的时候的例子
int f(int x){
//映射函数,决定这个数应该放到哪一个桶里面,此处是简单的除以100,根据我的数据可知,此处有四个桶,0,1,3,4,
//然后对每个桶单独排序,保证下一个桶的最大值必定大于上一个桶的最小值
return x/100;
}
void bucketSort(int arr[],int n)
{
int bucketNums = 10;//桶的个数
vector<int>ve[10];//记录每一个桶里面有的数
for(int i=0;i<n;i++){
int aa = f(arr[i]);
ve[aa].push_back(arr[i]);
}
//单独对每个桶排序
for(int i=0;i<bucketNums;i++){
if(ve[i].size()==0)continue;
sort(ve[i].begin(),ve[i].end());
}
int k = 0;
for(int i=0;i<bucketNums;i++){
int sz = ve[i].size();
for(int j = 0;j<sz;j++){
arr[k++] = ve[i][j];
}
}
}
int main(){
int arr[10] = {3,24,76,345,12,87,100,30,21,456};//试验数组
bucketSort(arr,10);
print(arr,10);
return 0;
转载于:https://blog.csdn.net/lwgkzl/article/details/79941786
https://blog.csdn.net/weixin_43442778/article/details/107547310