一.插入排序
1.直接插入排序
空间效率:使用常数个辅助单元,空间复杂度为o(1)
时间效率:在排序过程中,向有序子表逐个插入元素的操作进行了n-1躺,每趟都比较和移动元素,而比较和移动元素的次数取决于待排序表的初始状态。在最好的情况下,元素已经有序,此时插入一个元素,都只需要比较一次不需要移动元素,时间复杂度为o(1)。在最坏的情况下,表中的元素是逆序的,总的比较次数和总的移动次数达到最大。平均情况为o(n^2)
稳定性:每次插入元素总是从后向前进行比较,所以不会出现相同元素的相对位置发生变化,所以是稳定的。
适用性:适用于顺序存储和链式存储的线性表。当为链式存储时,可以从前向后查找指定元素的位置。
public void insert(int[] array){
int i,j;
for(i=2;i<array.length;i++){ //依次将array[2]...array[n]插入到前面已经排序好的数组
if(array[i]<array[i-1]){ //如果array[i]的关键字小于前驱,插入
array[0]=array[i]; //将array[0]作为哨兵
for( j=i-1;array[j]>array[0];j--){
array[j+1]=array[j];
}
array[j+1]=array[0];
}
}
}
2.折半插入排序
空间复杂度:o(1)
时间复杂度:该比较次数与待排序的初始状态无关,取决表中元素的个数n,约为:o(nlog₂n)。元素的移动次数仍然没有改变,取决于待排序的初始状态,时间复杂度是o(n^2)
稳定性:稳定的
public void InsertSort(int[] a){
int i,j,low,high,mid;
for(i=2;i<a.length;i++) //将a[2]~a[n]插入到前面已经排序的数组
{
a[0]=a[i]; //取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];
}
}
3.希尔排序
空间效率:o(1)
时间效率:只知道最坏情况下的为o(n^2)
稳定性:当相同关键