冒泡排序
两两交换,稳定排序
时间复杂度O(n2)
空间复杂度O(1)
class BubbleSort {
public:
int* bubbleSort(int* A, int n) {
for(int i=0;i!=n-1;++i)
{
for(int j=0;j!=n-1-i;++j)
{
if(A[j]>A[j+1])
{
int temp;
temp=A[j];
A[j]=A[j+1];
A[j+1]=temp;
}
}
}
return A;
}
};
选择排序 时间复杂度O(n2)
选择最小和第一个位置交换,之后第二个位置以后选择最小和第二个位置交换。
不稳定排序
空间复杂度O(1)
class SelectionSort {
public:
int* selectionSort(int* A, int n) {
int temp;
int pos;
for(int i=0;i!=n;++i)
{
temp=A[i];
pos=i;
for(int j=i+1;j!=n;++j)
{
if(temp>A[j])
{
temp=A[j];
pos=j;
}
}
if(pos!=i)
swap(A+pos,A+i);
}
return A;
// write code here
}
void swap(int *a,int *b)
{
int temp;
temp=*a;
*a=*b;
*b=temp;
}
};
插入排序 时间复杂度O(n2)
从后向前比较代码比较简单
稳定排序
空间复杂度O(1)
class InsertionSort {
public:
int* insertionSort(int* A, int n) {
for(int i=1;i!=n;++i)
{
if(A[i]<A[i-1])
{
int temp=A[i];
int j=i-1;
A[i]=A[i-1];
int pos=i-1;
while(j)
{
if(temp<A[j-1])
{
A[j]=A[j-1];
pos=j-1;
}
--j;
}
A[pos]=temp;
}
}
return A;
// write code here
}
};
归并排序 时间复杂度O(nlgn) 空间复杂度O(n)
稳定排序
空间复杂度O(n)
class MergeSort {
public:
int* mergeSort(int* A, int n) {
int *temp=new int[n];
mergerecur(A,0,n-1,temp);
return A;
// write code here
}
void mergerecur(int *input,int first,int end,int *temp)
{
if(end>first)
{
int mid=(first+end)/2;
mergerecur(input,first,mid,temp);
mergerecur(input,mid+1,end,temp);
mergearray(input,temp,input+first,mid-first+1,input+mid+1,end-mid);
}
}
void mergearray(int *input,int *res,int *a,int lena,int *b,int lenb)
{
int first=a-input;
int i=0;
int j=0;
int k=0;
while(i!=lena&&j!=lenb)
{
if(a[i]<b[j])
res[k++]=a[i++];
else
res[k++]=b[j++];
}
while(j!=lenb)
res[k++]=b[j++];
while(i!=lena)
res[k++]=a[i++];
for(int i=0;i!=k;++i)
input[first++]=res[i];
}
};
快速排序 平均时间复杂度O(nlgn) 空间复杂度O(nlgn)
空间复杂度O(N)~O(logN)
不稳定排序
class QuickSort {
public:
int* quickSort(int* A, int n) {
sortrecur(A,0,n-1);
return A;
// write code here
}
void sortrecur(int *a,int l,int r)
{
if(l<r)
{
int mid=sortmove(a,l,r);
sortrecur(a,l,mid-1);
sortrecur(a,mid+1,r);
}
}
int sortmove(int *a,int l,int r)
{
int i=l;
int j=r;
int x=a[i];
while(i<j)
{
while(i<j&&a[j]>=x)
--j;
a[i]=a[j];
while(i<j&&a[i]<=x)
++i;
a[j]=a[i];
}
a[i]=x;
return i;
}
};
堆排序 时间性能O(nlgn) 空间性能O(1)
不稳定排序
利用最大或最小堆进行排序
核心思想首先将序列构建成最大堆或者最小堆,之后选择最大堆顶部元素和最后一个元素交换
之后无序序列长度减1,重新构建最大堆最小堆,迭代上述步骤即可完成整个排序过程和选择排序有些类似,注意其有序序列从后端向前端生长。
空间复杂度O(1)
class HeapSort {
public:
int* heapSort(int* A, int n) {
// write code here
sortrecur(A,n);
return A;
}
void sortrecur(int *a,int lena)
{
if(lena>1){
buildheap(a,lena);
swapnum(a,a+lena-1);
sortrecur(a,lena-1);
}
}
void buildheap(int *a,int lena)
{
if(lena<2)
return;
for(int i=(lena-2)/2;i>=0;--i)
{
if(a[i]<a[2*i+1])
swapnum(a+i,a+2*i+1);
if(2*i+2<lena)
{
if(a[i]<a[2*i+2])
swapnum(a+i,a+2*i+2);
}
}
}
void swapnum(int *a,int *b)
{
int temp;
temp=*a;
*a=*b;
*b=temp;
}
};
希尔排序
希尔增量时间复杂度为O(n²),而Hibbard增量的希尔排序的时间复杂度为O(n3/2),希尔排序时间复杂度的下界是n*log2n。
空间复杂度O(1)
不稳定排序
class ShellSort {
public:
int* shellSort(int* A, int n) {
sortrecur(A,n,n/2);
return A;
// write code here
}
void sortrecur(int *a,int n,int dk)
{
if(dk>0){
shellinsert(a,n,dk);
dk=dk/2;
sortrecur(a,n,dk);
}
}
void shellinsert(int *a,int n,int dk)
{
for(int i=0;i<dk;++i) //所有组数
{
for(int j=i+dk;j<n;j+=dk) //插入排序
{
int k=j;
int temp=a[k];
while(k-dk>=i&&temp<a[k-dk])//先判断下标再比较大小,否则还会内存越界
{
a[k]=a[k-dk];
k=k-dk;
}
a[k]=temp;
}
}
}
};
计数排序
桶排序的一种时间复杂度O(n),空间复杂度O(M)(取决于桶的个数)
适合数字在一定范围内的排序。
稳定排序
class CountingSort {
public:
int* countingSort(int* A, int n) {
int max=A[0];
int min=A[0];
for(int i=0;i!=n;++i)
{
if(min>A[i])
min=A[i];
if(max<A[i])
max=A[i];
}
int *bucket=new int[max-min+1];
memset(bucket,0,(max-min+1)*sizeof(int));
for(int i=0;i!=n;++i)
{
++(*(bucket+A[i]-min));
}
int pos=0;
for(int i=0;i!=max-min+1;++i)
{
int k=*(bucket+i);
while(k--)
{
*(A+pos)=i+min;
++pos;
}
}
return A;
// write code here
}
};
基数排序
其时间复杂度为O (nlog(r)m),其中r为所采取的基数,而m为堆数,
稳定排序
class RadixSort {
public:
int* radixSort(int* A, int n) {
vector<queue<int>> vec_pos(10,queue<int>{});
vector<queue<int>> vec_neg(10,queue<int>{});
int max=abs(A[0]);
for(int i=0;i!=n;++i)
{
if(max<abs(A[i]))
max=abs(A[i]);
}
int i=1;
while(max/10)
{
++i;
max=max/10;
}
int k=i;
while(i--)
{
int div=1;
int num=k-i-1;
while(num--)
div=div*10;
for(int j=0;j!=n;++j)
{
if(A[j]>=0)
vec_pos[(A[j]/div)%10].push(A[j]);
else
{
vec_neg[(0-(A[j])/div)%10].push(A[j]);
}
}
int pos=0;
for(int neg_iter=vec_neg.size()-1;neg_iter>=0;--neg_iter)
{
while(!vec_neg[neg_iter].empty())
{
A[pos]=vec_neg[neg_iter].front();
vec_neg[neg_iter].pop();
++pos;
}
}
for(int pos_iter=0;pos_iter!=10;++pos_iter)
{
while(!vec_pos[pos_iter].empty())
{
A[pos]=vec_pos[pos_iter].front();
vec_pos[pos_iter].pop();
++pos;
}
}
// write code here
}
return A;
}
};