希尔排序算法思想
希尔排序的实质就是分组插入排序,该方法又称缩小增量排序.
基本思想是:先将整个待排元素序列分割成若干个子序列(由相隔某个“增量”的元素组成的)分别进行直接插入排序,然后依次缩减增量再进行排序,待整个序列中的元素基本有序(增量足够小)时,再对全体元素进行一次直接插入排序。因为直接插入排序在元素基本有序的情况下(接近最好情况),效率是很高的,因此希尔排序在时间效率上比前两种方法有较大提高。
代码
要求
对于一个int数组,请编写一个希尔排序算法,对数组元素排序。
给定一个int数组A及数组的大小n,请返回排序后的数组。保证元素小于等于2000。
测试样例:
[1,2,3,5,2,3],6
[1,2,2,3,3,5]
程序一(好理解,但是比较麻烦)
class ShellSort {
public:
int* shellSort(int* A, int n) {
// write code here
if(n<2){
return A;
}
int count = 2, argument; //count:一个子序列中的元素数,argument:增量,也是子序列的数量
while(count<=n){
argument = n/count;
for(int i=0;i<argument;i++){
sortArgu(A,n,i,argument); //这里把一次插入排序过程抽出来
}
count *=2;
}
return A;
}
private:
void sortArgu(int* A, int n, int begin, int argu){
int temp, last, current; //begin:子序列的起始元素
current = begin+argu;// current: 一次插入排序中,当前要排序的元素,也就是无序部分的第一个元素
while(current<n){
last = current;
while(last-argu>=begin){
if(A[last]<A[last-argu]){
temp = A[last];
A[last] = A[last-argu];
A[last-argu] = temp;
}
last -= argu;
}
current +=argu;
}
}
};
程序二
class ShellSort {
public:
int* shellSort(int* A, int n) {
// write code here
if(n<2){
return A;
}
int temp,j;
for(int step=n/2; step>0; step/=2){ //这里控制增量,最小值时为1,也就是一次普通的插入排序
for(int i=step; i<n; i++){ //重点是在这里!!!这里是对第一个增量后的元素进行插入排序(插入排序时起始有序序列为1),没有把一个子序列单独抽出来进行排序(区别程序一),而是依次对第一个增量后的元素在其所属的子序列中进行插入排序
for(j=i; j>=step; j-=step){
if(A[j]<A[j-step]){
temp = A[j]; //这里还可以进一步优化,详见程序三
A[j] = A[j-step];
A[j-step] = temp;
}else{
break;
}
}
}
}
return A;
}
};
程序三
class ShellSort {
public:
int* shellSort(int* A, int n) {
// write code here
if(n<2){
return A;
}
int temp,j;
for(int step=n/2; step>0; step/=2){
for(int i=step; i<n; i++){ //思想:找到待排序元素在有序部分的位置,然后插入,而不是每一次都把待排序元素与前一个元素交换位置。
temp = A[i]; //记录下待排序元素
for(j=i; j>=step; j-=step){
if(temp<A[j-step]){ //有序部分的每一个元素都与待排序元素比较
A[j]=A[j-step]; //满足上述条件,则元素后移
}else{
break;
}
}
A[j]=temp; //将待排序元素插入合适位置
}
}
return A;
}
};
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。