名称 | 分类 | 时间复杂度 | 空间复杂度 | 稳定性 |
直接插入排序 | 插入类 | 最好 O(n) 最坏O(n^2) 平均O(n^2) | O(1) | 稳定 |
折半插入排序 | 最好 O(n) 最坏O(n^2) 平均O(n^2) | O(1) | 稳定 | |
希尔排序 | 最好O(n^1.3) 最坏O(n^2) 平均O(nlogn) | O(1) | 不稳定 | |
冒泡排序 | 交换类 | 最好 O(n) 最坏O(n^2) 平均O(n^2) | O(1) | 稳定 |
快速排序 | 最好O(nlogn) 最坏O(n^2) 平均O(nlogn) | 最好O(nlogn) 最坏O(n) 平均O(nlogn) (产生于递归的深度) | 不稳定 | |
简单选择排序 | 选择类 | O(n^2) | O(1) | 不稳定 |
堆排序 | O(nlogn) | O(1) | 不稳定 | |
归并排序 | O(nlogn) | O(n) | 稳定 | |
基数排序 | 桶思想类 | O(d(n+k)) d:分配和收集的趟数 n:每趟待排序数目 k:需要的辅助队列数目 | O(n+k) | 稳定 |
插入类:
void insertsort(int *arr,int length)
{
if(length<=1)
{
cout<<"数组长度为1,无需排序"<<endl;
}
for(int i=1;i<length;i++)
{
if(arr[i]<arr[i-1])
{
int temp = arr[i];
int j;
for(j=i-1;j>=0&&arr[j]>temp;j--)
{
arr[j+1] = arr[j];
}
arr[j+1] = temp;
}
}
cout<<"直接排序的结果为:"<<endl;
for(int i=0;i<length;i++)
{
cout<<arr[i]<<" ";
}
cout<<endl;
}
//二分插入排序
void halfinsertsort(int *arr,int length)
{
if(length<=1)
{
cout<<"数组长度为1,无需排序"<<endl;
}
for(int i =1;i<length;i++)
{
if(arr[i]<arr[i-1])
{
int temp = arr[i];
int left = 0;
int right = i-1;
while(left<=right)//查找插入位置
{
int mid = (right-left)/2+left;
if(arr[mid]>temp)
{
right = mid-1;
}
else
{
left = mid+1;
}
}
for(int j =i-1;j>=right+1;j--)
{
arr[j+1]=arr[j];
}
arr[right+1] = temp;
}
}
cout<<"二分排序为:"<<endl;
for(int i=0;i<length;i++)
{
cout<<arr[i]<<" ";
}
cout<<endl;
}
//希尔排序
void xiersort(int *arr,int length)
{
if(length<=1)
{
cout<<"数组长度为1,无需排序"<<endl;
}
cout<<"原始数组为:"<<endl;
for(int i=0;i<length;i++)
{
cout<<arr[i]<<" ";
}
cout<<endl;
int dim = length/2;//设置增量
while(dim>=1)
{
for(int i=dim;i<length;i++)
{
if(arr[i]<arr[i-dim])
{
int temp = arr[i];
int j;
for(j = i-dim;j>=0&&arr[j]>temp;j = j-dim)
{
arr[j+dim] = arr[j];
}
arr[j+dim] = temp;
}
}
cout<<"本次排序,增量为:"<<dim<<endl;
for(int i =0;i<length;i++)
{
cout<<arr[i]<<" ";
}
cout<<endl;
dim = dim/2;
}
}
交换类
//冒泡排序
void maopaosort(int *arr,int length)
{
if(length<=1)
{
cout<<"数组长度为1,不需要排序"<<endl;
}
bool type = false;
for(int i=0;i<length-1;i++)
{
for(int j=0;j<length-1-i;j++)
{
if(arr[j]>arr[j+1])
{
int temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
type = true;
}
}
if(type == false)
break;
}
for(int i=0;i<length;i++)
{
cout<<arr[i]<<" ";
}
cout<<endl;
}
//快速排序
int partition(int *arr,int low,int high)//都不是传的引用,并不会影响实际的值
{
int temp = arr[low];
while(low<high)
{
while(low<high&&arr[high]>=temp)
high--;
if(low==high)
break;
if(low<high)
arr[low] = arr[high];
while(low<high&&arr[low]<=temp)
low++;
if(low==high)
break;
if(low<high)
arr[high] = arr[low];
}
arr[low] = temp;
return low;
}
void choosesort(int *arr,int low,int high,int length)
{
assert(low<high);
int temp = partition(arr,low,high);
cout<<"本轮排序的low:"<<low<<" high:"<<high<<" 轴为:"<<temp<<endl;
for(int i =0;i<length;i++)
{
cout<<arr[i]<<" ";
}
cout<<endl;
if((temp-1)>low)
choosesort(arr,low,temp-1,length);
if((temp+1)<high)
choosesort(arr,temp+1,high,length);
}
void choosesort(int* arr,int length)
{
if(length<=1)
{
cout<<"数组长度为1,不需要排序"<<endl;
}
int low = 0;
int high = length - 1;
choosesort(arr,low,high,length);
}
选择类
//简单选择排序
void simsort(int *arr,int length)
{
if(length<=1)
{
cout<<"数组长度为1,无需排序"<<endl;
}
for(int i =0;i<length-1;i++)
{
int minidx = i;
for(int j=i+1;j<length;j++)
{
if(arr[j]<arr[minidx])
{
minidx = j;
}
}
if(minidx != i)
{
int temp = arr[minidx];
arr[minidx] = arr[i];
arr[i] = temp;
}
}
for(int i=0;i<length;i++)
{
cout<<arr[i]<<" ";
}
cout<<endl;
}
void adjustdown(int* arr,int length,int cur)
{
int i = cur;
int j = cur*2+1;
while(j<length)
{
if(j+1<length)//有右孩子
{
if(arr[j+1]>arr[j])
{
j=j+1;
}
}
if(arr[i]>arr[j])
{
break;
}
int temp = arr[j];
arr[j] = arr[i];
arr[i] = temp;
i=j;
j = j*2+1;
}
}
void removemaxvalue(int*arr,int length)
{
if(length-1==0)
return;
int temp = arr[0];
arr[0] = arr[length-1];
arr[length-1] = temp;
adjustdown(arr,length-1,0);
}
//堆排序
void stacksort(int *arr,int length)
{
if(length<=1)
{
cout<<"数组长度为1,不需要排序"<<endl;
}
int cur = length/2-1;//找到第一个非叶子节点
while(cur>=0)
{
adjustdown(arr,length,cur);//调整该节点的子树
cur--;
}//构造大栈顶
for(int i=0;i<length-1;i++)
{
removemaxvalue(arr,length-i);//换根,重新调回大栈顶
}
for(int i=0;i<length;i++)
{
cout<<arr[i]<<" ";
}
cout<<endl;
}
归并排序
//递归方式
void merge(int *arr,int* temp,int left,int mid, int right,int length)
{
for(int i=left;i<=right;i++)
{
temp[i] = arr[i];
}
int cur1 = left;//左序列第一个
int cur2 = mid+1;//右序列第一个
int cur3 = left;//新序列的第一个
while(cur1<=mid&&cur2<=right)
{
if(temp[cur1]<=temp[cur2])
{
arr[cur3] = temp[cur1];
cur1++;
}
else
{
arr[cur3] = temp[cur2];
cur2++;
}
cur3++;
}
while(cur1<=mid)
{
arr[cur3] = temp[cur1];
cur1++;
cur3++;
}
while(cur2<=right)
{
arr[cur3] = temp[cur2];
cur2++;
cur3++;
}
}
void mergesort(int* arr,int*temp,int left,int right,int length)//划分数组
{
int mid = (right+left)/2;
if(left>=right)
return;
mergesort(arr,temp,left,mid,length);
mergesort(arr,temp,mid+1,right,length);
merge(arr,temp,left,mid,right,length);//将左右两边合到一起
}
void mergesort(int *arr,int length)
{
if(length<=1)
{
cout<<"数组长度为1,无需排序"<<endl;
}
int* temparray = new int[length];
mergesort(arr,temparray,0,length-1,length); //length仅仅作为显示使用
delete []temparray;
}
//非递归排序
void mergesort_nodigui(int*arr,int length)
{
if(length<=1)
{
cout<<"数组长度为1,无需排序"<<endl;
}
int step = 1;//子序列间的间隔
int subsetoatl = length;//当前子序列的数目
int left,right,mid;
int* temp = new int[length];
while(subsetoatl>1)
{
for(int i=0;i<length;i=i+step*2)//遍历每个子列
{
left = i;
mid = left+step-1;
if(mid>=length)
{
break;
}
right = mid+(mid-left+1);
if(right>=length)
{
right = length-1;
}
if(left<=mid&&left<right&&mid<right)
{
merge(arr,temp,left,mid,right,length);
subsetoatl--;
}
else
{
break;
}
}
step*=2;
}
delete []temp;
}
基数排序
void radixsort(int*arr,int length)
{
if(length<=1)
{
cout<<"数组长度为1,无需排序"<<endl;
}
int* temp = new int[length];
list<int *>mylist[10];//0~9
//分配
for(int i=0;i<3;i++)
{
for(int j=0;j<length;j++)
{
int tmpi=i;//判断比较哪一位
int value = arr[j];
int lastvalue;//存放个位十位百位
while(tmpi>=0)
{
lastvalue = value%10;
value = value/10;
tmpi--;
}
mylist[lastvalue].push_back(&arr[j]);//余数对应下标
}
//收集
int idx = 0;
for(int k=0;k<10;k++)//就0-9十个位置
{
for(auto iter = mylist[k].begin();iter!=mylist[k].end();iter++)
{
temp[idx] = *(*(iter));
idx++;
}
mylist[k].clear();
}
cout<<"第"<<i<<"次排序结果"<<endl;
for(int m = 0;m<length;m++)
{
cout<<temp[m]<<" ";
}
cout<<endl;
for(int m=0;m<length;m++)
{
arr[m] = temp[m];
}//下一次分配要建立在上一次的收集成果之上
}
delete []temp;
}