1,直接插入
void InsertSort(ElemType A[],int n)
{
int i,j;
for(i=2;i<n;i++)
{
if(A[i]<A[i-1])
{
A[0]=A[i];//A[0]为哨兵
for(j=i-1;A[0]<A[j];--j)//从后向前查找待插入的位置
A[j+1]=A[j];
A[j+1]=A[0];
}
}
}
空间复杂度为 O(1)
在最好的情况下,元素已基本有序,此时插入时只需要比较一次,而不用移动元素,此时时间复杂度为O(n)平均情况下,时间复杂度为O(n2)
稳定的
适用于顺序存储和链式存储的线性表
2,折半插入算法
void InsertSort(ElemType A[], int n)
{
int i,j,low high,mid;
for(i=2;i<n;i++)//依次将A[2]~A[n]插入到前面已排序序列
{
A[0]=A[i];
low=1;high=i-1;
while(low<=high){
mid=(high+low)/2;
if(A[mid]>A[0]) high=mid-1;
else low=mid+1;
}
for(j=i-1;j>=high+1;--j)
A[j+1]=A[j];
A[high+1]=A[0];
}
}
折半查找仅仅减少了元素的比较次数,该比较次数与待排续表的初始状态无关,仅取决于表中元素的个数n,而移动次数并为改变,它依赖于表的初始序列,因此时间复杂度仍未O(n2),是稳定的。
3,希尔排序
void ShellSort(ElemType A[], int n)
{
//A[0]只是暂存单元,不是哨兵,当j<=0时,插入位置已到
for(dk=n/2;dk>=1;dk=dk/2)
{
for(i=dk+1;i<=n;++i)
if(A[i]<A[i-dk]){
A[0]=A[i];
for(j=i-dk;j>0&&A[0]<A[j];j-=dk)
A[j+dk]=A[0];
}
}
空间复杂度为O(1)
最坏的情况下,时间复杂度为O(n2)
是一种不稳定的算法,仅适用于线性表尾顺序存储的情况。
1,冒泡排序
void BubbleSort(ElemType A[],int n)
{
for(i=0;i<n-1;i++)
{
flag=false;
for(j=n-1;j>i;j--)
if(A[j-1]>A[j]){
swap(A[j-1],A[j]);
flag=true;
}
if(flag==false)//本趟遍历没有发生交换,说明表已经有序。
return;
}
}
空间复杂度为O(1)
最坏情况下时间复杂度为O(n2),平均情况下时间复杂度也为O(n2)
稳定
每趟都会将一个元素放在其最终位置上
2,快速排序
递归的调用快速排序算法进行排序
void QuickSort(EleType A[], int low, int high){
if(low<high){
int pivotpos=partition(A,low,high);
QuickSort(A,low,pivotpos-1);
QuickSort(A,pivotpos+1,high);
}
}
非递归方法,假设每次总以当前表中第一个元素作为枢轴来对表进行划分。
int Partition(ElemType A[], int low, int high)
{
ElemType pivot=A[low];
while(low<high){
while(low<high&&A[high]>=pivot) --high;
A[low]=A[high];
while(low<high&&A[low]<=pivot) ++low;
A[high]=A[low];//将比枢轴大的元素移动到右端
}
A[low]=pivot;//枢轴元素存放到最终位置
return low;
}
每趟排序后会将枢轴元素放到其最终位置上。
不稳定
最好的情况下,空间效率为O(log2n),最坏的情况下,栈的深度为O(n),平均情况下,栈的深度为O(log2n)
时间效率:快速排序的运行时间与划分是否对称有关,初始排序表基本有序或基本逆序时,情况最坏,时间复杂度为O(n2),理想情况下,时间复杂度为O(nlog2n)
快速排序算法是所有内部排序算法中平均性能最优的排序算法
1,简单选择排序
void SelectSort(ElemType A[], int n){
for(i=0;i<n-1;i++){
min=i;
for(j=i+1;j<n;j++)
if(A[j]<A[min]) min=j;
if(min!=i) swap(A[i],A[min]);
}
}
空间效率为O(1)
时间复杂度为O(n2)
不稳定
元素之间的比较次数和初始序列无关
2,堆排序
空间复杂度为O(1)
建堆时间为O(n),每次调整时间复杂度为O(h)
在最好,最坏和平均情况下,堆排序的时间复杂度为O(nlog2n)
归并排序的空间复杂度为O(n)
时间复杂度为O(nlog2n)
稳定
基数排序不基于比较和移动进行排序
空间复杂度为O®
一趟分配需要O(n),一趟收集需要O®,所以时间复杂度为O(d(n+r)),它与序列的初始状态无关