希尔排序
一、算法思想
1.思想
先追求表中元素部分有序,再逐渐逼近全局有序
2.步骤
先划分子表,再对子表进行直接插入排序,缩小增量d,重复上述过程,直至d = 1为止
希尔本人建议:每次将增量缩小一半(考试中可能遇到各种增量)
第一趟:d1 = n / 2
第二趟:d2 = d1 / 2
第三趟:d3 = d2 / 2
…
整个表已呈现出“基本有序”,对整体再进行一次“直接插入排序”
二、代码实现
1.切换子表排序
//希尔排序
void shellSort1(int A[], int n){
int i, j, d;
for(d=n/2; d>=1; d=d/2){//增量以2的倍数递减
for(i=d+1; i<=n; i++){//插入排序默认子序列的第一个数为有序
if(A[i] < A[i-d]){
A[0] = A[i];
for(j=i-d; j>0 && A[0]<A[j]; j=j-d){//移动元素,给插入的数腾出空间
A[j+d] = A[j];
}
A[j+d] = A[0];
}
}
}
}
2.不切换子表排序
//希尔排序
shellSort2
三、算法性能分析
1.空间复杂度:O(1)
2.时间复杂度:和增量序列的选择有关,目前无法用数学手段证明确切的时间复杂度,最坏时间复杂度为O(n ^ 2),当在某个范围内时,可达O(n ^ 1.3)
四、稳定性和适用性
1.稳定性:不稳定!
eg:65、49、49
2.适用性:仅适用于顺序表,不适用于链表。