使用冒泡排序,时间复杂度为O(n^2),空间复杂度为O(1)
像气泡一样从低往上浮现
vector<int> bubbleSort(vector<int>nums)
{
int length=nums.size();
for(int i=0;i<length;i++)
{
for(int j=length-2;j>=i;j--)
{
if(nums[j]>nums[j+1])
{
int temp=nums[j+1];
nums[j+1]=nums[j];
nums[j]=temp;
}
}
}
return nums;
}
使用选择排序,时间复杂度为O(n^2),空间复杂度为O(1)。寻找关键字最小的坐标
vector<int>selectSort(vector<int>nums)
{
int length=nums.size();
int minPos=INT_MIN;
for(int i=0;i<length-1;i++)
{
minPos=i;
for(int j=i+1;j<length;j++)
{
minPos=nums[j]<nums[minPos]?j:minPos;
}
int temp=nums[i];
nums[i]=nums[minPos];
nums[minPos]=temp;
}
return nums;
}
使用插入排序,时间复杂度为O(n^2),空间复杂度O(1)
vector<int>insertSort(vector<int>nums)
{
int length=nums.size();
for(int i=0;i<length-1;i++)
{
//当找到满足非递增的数组时,进行处理
int temp=nums[i+1];
int preIndex=i;
while(preIndex>=0&&nums[preIndex]>temp)
{
//数组往后挪,直到找到第一个小于该值的值
nums[preIndex+1]=nums[preIndex];
preIndex--;
}
nums[preIndex+1]=temp;
}
return nums;
}
使用希尔排序进行实现,平均时间复杂度为O(nlogn),空间复杂度为O(1)
希尔排序是在插入排序的基础上进行改进的算法
先将序列划分成大区间,先对每一个区间进行排序,使后一个区间里的所有对应位置的值都大于前一个区间所有对应位置的值
然后不断循环,直到最后大区间全部都变成了小区间,则此时代表已经排号序了
vector<int>shellSort(vector<int>nums)
{
int length=nums.size();
int gap=length>>1;
int temp;
while(gap)
{
//类似插入排序
//i从第二个区间开始的
for(int i=gap;i<length;i++)
{
temp=nums[i];
int preIndex=i-gap;
while(preIndex>=0&&nums[preIndex]>temp)
{
nums[preIndex+gap]=nums[preIndex];
preIndex-=gap;
}
nums[preIndex+gap]=temp;
}
gap=gap>>1;
}
return nums;
}
归并排序,平均时间复杂度O(nlogn),空间复杂度O(n)
//归并排序,平均时间复杂度O(nlogn),空间复杂度O(n)
//使用递归实现归并排序
vector<int>mergeSort(vector<int>nums)
{
mSort(nums,0,nums.size()-1);
return nums;
}
//在[left,right]这个区间中进行归并排序,整个nums经过整个函数后就是一个有序数组
//使用回溯的思想
void mSort(vector<int>&nums,int left,int right)
{
//定义递归终止条件
if(left>=right)
{
return;
}
//防止位溢出
int mid=left+((right-left)>>1);
//回溯
mSort(nums,left,mid);
mSort(nums,mid+1,right);
merge(nums,left,mid,right);
}
void merge(vector<int>&nums,int left,int mid,int right)
{
//创建一个临时数组用以保存合并排序之后的数组,并把这个区间的值赋给其
vector<int>tempArr(nums.begin()+left,nums.begin()+right+1);
//合并两个区间,i代表左边开始索引,j代表右边开始索引
int i=left;
int j=mid+1;
for(int k=left;k<=right;k++)
{
//代表左边已经处理完毕,将右边的直接替代即可
if(i>mid)
{
nums[k]=tempArr[j-left];
j++;
}
//代表右边已经处理完毕,将左侧区间的值直接拷贝到原数组即可
else if(j>right)
{
nums[k]=tempArr[i-left];
i++;
}
//两边都未处理完毕,则比较二者大小,将元素中较小的元素放在左边
else if(tempArr[i-left]<=tempArr[j-left]){
nums[k]=tempArr[i-left];
i++;
}
else
{
nums[k]=tempArr[j-left];
j++;
}
}
}
平均时间复杂度为O(nlogn),最坏平均复杂度为O(n^2),空间复杂度O(logn)
vector<int>quickSort(vector<int>nums)
{
qSort(nums,0,nums.size()-1);
return nums;
}
void qSort(vector<int>&nums,int left,int right)
{
//定义递归终止条件
if(left>=right)
{
return;
}
//设置枢轴
int pivot=partition(nums,left,right);
//递归实现
qSort(nums,left,pivot-1);
qSort(nums,pivot+1,right);
}
int partition(vector<int>&nums,int left,int right)
{
int pivot=nums[left];
int j=left;
for(int i=left+1;i<=right;i++)
{
//大放过小交换
if(nums[i]<pivot)
{
j++;
swap(nums,i,j);
}
}
swap(nums,left,j);
return j;
}
void swap(vector<int>&nums,int index1,int index2)
{
int temp=nums[index1];
nums[index1]=nums[index2];
nums[index2]=temp;
}
堆排序,算法平均时间复杂度为O(nlogn),空间复杂度O(1)
vector<int>heapSort(vector<int>nums)
{
//首先构建一个最大堆
for(int i=nums.size()/2-1;i>=0;--i)
{
heapAdjust(nums,i,nums.size());
}
//从最大堆中逆序得到递增序列
for(int i=nums.size()-1;i>=0;--i)
{
swap(nums,0,i);
heapAdjust(nums,0,i);
}
return nums;
}
void heapAdjust(vector<int>&nums,int i,int length)
{
int max=i;
//构建左右结点
int lChild=i*2+1;
int rChild=i*2+2;
if(lChild<length&&nums[lChild]>nums[max])
{
max=lChild;
}
if(rChild<length&&nums[rChild]>nums[max])
{
max=rChild;
}
if(max!=i)
{
swap(nums,i,max);
heapAdjust(nums,max,length);
}
}
计数排序,时间复杂度O(n+k),空间复杂度O(k)
vector<int>countSort(vector<int>nums)
{
int maxVal=nums[max_element(nums.begin(),nums.end())-nums.begin()];
int minVal=nums[min_element(nums.begin(),nums.end())-nums.begin()];
//数值作为索引,个数作为值
vector<int>count(maxVal,0);
vector<int>temp(nums);
//数字需要减去1才能实现
for(int i=0;i<temp.size();i++)
{
++count[nums[i]-1];
}
nums.clear();
for(int i=0;i<count.size();i++)
{
for(int j=0;j<count[i];j++)
{
nums.push_back(i+1);
}
}
return nums;
}
vector<int>countSort2(vector<int>nums)
{
int maxVal=nums[max_element(nums.begin(),nums.end())-nums.begin()];
int minVal=nums[min_element(nums.begin(),nums.end())-nums.begin()];
//数值作为索引,个数作为值
vector<int>count(maxVal-minVal+1,0);
int bias=0-minVal;
for(int i=0;i<nums.size();i++)
{
++count[nums[i]+bias];
}
int index=0,i=0;
while(index<nums.size())
{
if(count[i]!=0)
{
nums[index]=i-bias;
count[i]--;
index++;
}
else{
i++;
}
}
return nums;
}
平均时间复杂度为O(n+k),空间复杂度为O(n+k)
//桶排序 平均时间复杂度为O(n+k),空间复杂度为O(n+k)
//设置总共有5个桶
vector<int>bucketSort(vector<int>nums)
{
int maxVal=nums[max_element(nums.begin(),nums.end())-nums.begin()];
int minVal=nums[min_element(nums.begin(),nums.end())-nums.begin()];
//设置桶的大小
int bucketSize=5;
//设置桶的数目
int bucketCount=(maxVal-minVal)/bucketSize+1;
vector<vector<int>>buckets(bucketCount,vector<int>());
//利用映射函数将数据分配到每个桶中
for(int i=0;i<nums.size();i++)
{
buckets[(nums[i]-minVal)/bucketSize].push_back(nums[i]);
}
int index=0;
for(int i=0;i<buckets.size();i++)
{
//对每个桶的内部函数进行排序
//调用之前写的排序算法
buckets[i]=quickSort(buckets[i]);
//取出每个桶中的元素
for(int j=0;j<buckets[i].size();j++)
{
nums[index++]=buckets[i][j];
}
}
return nums;
}
平均时间复杂度为O(n*k),空间复杂度为O(n+k)
//基数排序,平均时间复杂度为O(n*k),空间复杂度为O(n+k)
//按位对应的数,从高位开始依次比较,进行排序
vector<int>radixSort(vector<int>nums)
{
int length=nums.size();
int bits=maxBit(nums);
//设置数组保存从0~9的数字
int radix=1;
for(int i=0;i<=bits;i++)
{
//获取更新的数组
vector<int>newArray(length);
//根据最后一位数字的值保存排序数组
vector<int>count=vector<int>(10,0);
for(int j=0;j<length;j++)
{
int temp=(nums[j]/radix)%10;
count[temp]++;
}
//计算前缀和,判断前面由于个位数不存在的值
for(int j=1;j<10;j++)
{
count[j]+=count[j-1];
}
//指定更新阵列的新位置,count[temp]--则是用来判断这个位置是否到位
for(int j=length-1;j>=0;j--)
{
int temp=(nums[j]/radix)%10;
newArray[count[temp]-1]=nums[j];
count[temp]--;
}
nums=newArray;
radix*=10;
}
return nums;
}
//获取数组中最大值的位数
int maxBit(vector<int>nums)
{
int maxVal=nums[max_element(nums.begin(),nums.end())-nums.begin()];
int d=0;
// int p=10;
while(maxVal>0)
{
maxVal/=10;
++d;
}
return d;
}
#include
#include
#include
#include
using namespace std;
void mSort(vector<int>&nums,int left,int right);
void merge(vector<int>&nums,int left,int mid,int right);
void qSort(vector<int>&nums,int left,int right);
int partition(vector<int>&nums,int left,int right);
void swap(vector<int>&nums,int index1,int index2);
void heapAdjust(vector<int>&nums,int i,int length);
int maxBit(vector<int>nums);
//使用冒泡排序,时间复杂度为O(n^2),空间复杂度为O(1)
//像气泡一样从低往上浮现
vector<int> bubbleSort(vector<int>nums)
{
int length=nums.size();
for(int i=0;i<length;i++)
{
for(int j=length-2;j>=i;j--)
{
if(nums[j]>nums[j+1])
{
int temp=nums[j+1];
nums[j+1]=nums[j];
nums[j]=temp;
}
}
}
return nums;
}
//使用选择排序,时间复杂度为O(n^2),空间复杂度为O(1)
//寻找到关键字最小的坐标
vector<int>selectSort(vector<int>nums)
{
int length=nums.size();
int minPos=INT_MIN;
for(int i=0;i<length-1;i++)
{
minPos=i;
for(int j=i+1;j<length;j++)
{
minPos=nums[j]<nums[minPos]?j:minPos;
}
int temp=nums[i];
nums[i]=nums[minPos];
nums[minPos]=temp;
}
return nums;
}
//使用插入排序,时间复杂度为O(n^2),空间复杂度O(1)
vector<int>insertSort(vector<int>nums)
{
int length=nums.size();
for(int i=0;i<length-1;i++)
{
//当找到满足非递增的数组时,进行处理
int temp=nums[i+1];
int preIndex=i;
while(preIndex>=0&&nums[preIndex]>temp)
{
//数组往后挪,直到找到第一个小于该值的值
nums[preIndex+1]=nums[preIndex];
preIndex--;
}
nums[preIndex+1]=temp;
}
return nums;
}
//使用希尔排序进行实现,平均时间复杂度为O(nlogn),空间复杂度为O(1)
//希尔排序是在插入排序的基础上进行改进的算法
//先将序列划分成大区间,先对每一个区间进行排序,使后一个区间里的所有对应位置的值都大于前一个区间所有对应位置的值‘
//然后不断循环,直到最后大区间全部都变成了小区间,则此时代表已经排号序了
vector<int>shellSort(vector<int>nums)
{
int length=nums.size();
int gap=length>>1;
int temp;
while(gap)
{
//类似插入排序
//i从第二个区间开始的
for(int i=gap;i<length;i++)
{
temp=nums[i];
int preIndex=i-gap;
while(preIndex>=0&&nums[preIndex]>temp)
{
nums[preIndex+gap]=nums[preIndex];
preIndex-=gap;
}
nums[preIndex+gap]=temp;
}
gap=gap>>1;
}
return nums;
}
//归并排序,平均时间复杂度O(nlogn),空间复杂度O(n)
//使用递归实现归并排序
vector<int>mergeSort(vector<int>nums)
{
mSort(nums,0,nums.size()-1);
return nums;
}
//在[left,right]这个区间中进行归并排序,整个nums经过整个函数后就是一个有序数组
//使用回溯的思想
void mSort(vector<int>&nums,int left,int right)
{
//定义递归终止条件
if(left>=right)
{
return;
}
//防止位溢出
int mid=left+((right-left)>>1);
//回溯
mSort(nums,left,mid);
mSort(nums,mid+1,right);
merge(nums,left,mid,right);
}
void merge(vector<int>&nums,int left,int mid,int right)
{
//创建一个临时数组用以保存合并排序之后的数组,并把这个区间的值赋给其
vector<int>tempArr(nums.begin()+left,nums.begin()+right+1);
//合并两个区间,i代表左边开始索引,j代表右边开始索引
int i=left;
int j=mid+1;
for(int k=left;k<=right;k++)
{
//代表左边已经处理完毕,将右边的直接替代即可
if(i>mid)
{
nums[k]=tempArr[j-left];
j++;
}
//代表右边已经处理完毕,将左侧区间的值直接拷贝到原数组即可
else if(j>right)
{
nums[k]=tempArr[i-left];
i++;
}
//两边都未处理完毕,则比较二者大小,将元素中较小的元素放在左边
else if(tempArr[i-left]<=tempArr[j-left]){
nums[k]=tempArr[i-left];
i++;
}
else
{
nums[k]=tempArr[j-left];
j++;
}
}
}
//快速排序:平均时间复杂度为O(nlogn),最坏平均复杂度为O(n^2),空间复杂度O(logn)
vector<int>quickSort(vector<int>nums)
{
qSort(nums,0,nums.size()-1);
return nums;
}
void qSort(vector<int>&nums,int left,int right)
{
//定义递归终止条件
if(left>=right)
{
return;
}
//设置枢轴
int pivot=partition(nums,left,right);
//递归实现
qSort(nums,left,pivot-1);
qSort(nums,pivot+1,right);
}
int partition(vector<int>&nums,int left,int right)
{
int pivot=nums[left];
int j=left;
for(int i=left+1;i<=right;i++)
{
//大放过小交换
if(nums[i]<pivot)
{
j++;
swap(nums,i,j);
}
}
swap(nums,left,j);
return j;
}
void swap(vector<int>&nums,int index1,int index2)
{
int temp=nums[index1];
nums[index1]=nums[index2];
nums[index2]=temp;
}
//堆排序,算法平均时间复杂度为O(nlogn),空间复杂度O(1)
vector<int>heapSort(vector<int>nums)
{
//首先构建一个最大堆
for(int i=nums.size()/2-1;i>=0;--i)
{
heapAdjust(nums,i,nums.size());
}
//从最大堆中逆序得到递增序列
for(int i=nums.size()-1;i>=0;--i)
{
swap(nums,0,i);
heapAdjust(nums,0,i);
}
return nums;
}
void heapAdjust(vector<int>&nums,int i,int length)
{
int max=i;
//构建左右结点
int lChild=i*2+1;
int rChild=i*2+2;
if(lChild<length&&nums[lChild]>nums[max])
{
max=lChild;
}
if(rChild<length&&nums[rChild]>nums[max])
{
max=rChild;
}
if(max!=i)
{
swap(nums,i,max);
heapAdjust(nums,max,length);
}
}
//计数排序,时间复杂度O(n+k),空间复杂度O(k)
vector<int>countSort(vector<int>nums)
{
int maxVal=nums[max_element(nums.begin(),nums.end())-nums.begin()];
int minVal=nums[min_element(nums.begin(),nums.end())-nums.begin()];
//数值作为索引,个数作为值
vector<int>count(maxVal,0);
vector<int>temp(nums);
//数字需要减去1才能实现
for(int i=0;i<temp.size();i++)
{
++count[nums[i]-1];
}
nums.clear();
for(int i=0;i<count.size();i++)
{
for(int j=0;j<count[i];j++)
{
nums.push_back(i+1);
}
}
return nums;
}
//计数排序,时间复杂度O(n+k),空间复杂度O(k)
//优化空间
vector<int>countSort2(vector<int>nums)
{
int maxVal=nums[max_element(nums.begin(),nums.end())-nums.begin()];
int minVal=nums[min_element(nums.begin(),nums.end())-nums.begin()];
//数值作为索引,个数作为值
vector<int>count(maxVal-minVal+1,0);
int bias=0-minVal;
for(int i=0;i<nums.size();i++)
{
++count[nums[i]+bias];
}
int index=0,i=0;
while(index<nums.size())
{
if(count[i]!=0)
{
nums[index]=i-bias;
count[i]--;
index++;
}
else{
i++;
}
}
return nums;
}
//桶排序 平均时间复杂度为O(n+k),空间复杂度为O(n+k)
//设置总共有5个桶
vector<int>bucketSort(vector<int>nums)
{
int maxVal=nums[max_element(nums.begin(),nums.end())-nums.begin()];
int minVal=nums[min_element(nums.begin(),nums.end())-nums.begin()];
//设置桶的大小
int bucketSize=5;
//设置桶的数目
int bucketCount=(maxVal-minVal)/bucketSize+1;
vector<vector<int>>buckets(bucketCount,vector<int>());
//利用映射函数将数据分配到每个桶中
for(int i=0;i<nums.size();i++)
{
buckets[(nums[i]-minVal)/bucketSize].push_back(nums[i]);
}
int index=0;
for(int i=0;i<buckets.size();i++)
{
//对每个桶的内部函数进行排序
//调用之前写的排序算法
buckets[i]=quickSort(buckets[i]);
//取出每个桶中的元素
for(int j=0;j<buckets[i].size();j++)
{
nums[index++]=buckets[i][j];
}
}
return nums;
}
//基数排序,平均时间复杂度为O(n*k),空间复杂度为O(n+k)
//按位对应的数,从高位开始依次比较,进行排序
vector<int>radixSort(vector<int>nums)
{
int length=nums.size();
int bits=maxBit(nums);
//设置数组保存从0~9的数字
int radix=1;
for(int i=0;i<=bits;i++)
{
//获取更新的数组
vector<int>newArray(length);
//根据最后一位数字的值保存排序数组
vector<int>count=vector<int>(10,0);
for(int j=0;j<length;j++)
{
int temp=(nums[j]/radix)%10;
count[temp]++;
}
//计算前缀和,判断前面由于个位数不存在的值
for(int j=1;j<10;j++)
{
count[j]+=count[j-1];
}
//指定更新阵列的新位置,count[temp]--则是用来判断这个位置是否到位
for(int j=length-1;j>=0;j--)
{
int temp=(nums[j]/radix)%10;
newArray[count[temp]-1]=nums[j];
count[temp]--;
}
nums=newArray;
radix*=10;
}
return nums;
}
//获取数组中最大值的位数
int maxBit(vector<int>nums)
{
int maxVal=nums[max_element(nums.begin(),nums.end())-nums.begin()];
int d=0;
// int p=10;
while(maxVal>0)
{
maxVal/=10;
++d;
}
return d;
}
int main()
{
vector<int>nums={9,9,2,18,3,7,34,356,5};
vector<int>res=bubbleSort(nums);
cout<<"冒泡排序的结果为:";
for(int i:res)
{
cout<<i<<" ";
}
cout<<endl;
res=selectSort(nums);
cout<<"选择排序的结果为:";
for(int i:res)
{
cout<<i<<" ";
}
cout<<endl;
res=insertSort(nums);
cout<<"插入排序的结果为:";
for(int i:res)
{
cout<<i<<" ";
}
cout<<endl;
res=shellSort(nums);
cout<<"希尔排序的结果为:";
for(int i:res)
{
cout<<i<<" ";
}
cout<<endl;
res=mergeSort(nums);
cout<<"归并排序的结果为:";
for(int i:res)
{
cout<<i<<" ";
}
cout<<endl;
res=quickSort(nums);
cout<<"快速排序的结果为:";
for(int i:res)
{
cout<<i<<" ";
}
cout<<endl;
res=heapSort(nums);
cout<<"堆排序的结果为:";
for(int i:res)
{
cout<<i<<" ";
}
cout<<endl;
res=countSort2(nums);
cout<<"计数排序的结果为:";
for(int i:res)
{
cout<<i<<" ";
}
cout<<endl;
res=bucketSort(nums);
cout<<"堆排序的结果为:";
for(int i:res)
{
cout<<i<<" ";
}
cout<<endl;
res= radixSort(nums);
cout<<"基数排序的结果为:";
for(int i:res)
{
cout<<i<<" ";
}
cout<<endl;
}