两个49在排序前后位置颠倒了,所以希尔排序是不稳定的
希尔排序是基于插入排序的以下两点性质而提出改进方法的:
- 1.插入排序在对几乎已经排好序的数据操作时,效率高,即可以达到线性排序的效率。
- 2.但插入排序一般来说是低效的,因为插入排序每次只能将数据移动一位。
希尔排序的基本思想是:
先将整个待排序的记录序列分割成为若干子序列分别进行直接插入排序,待整个序列中的记录“基本有序”时,再对全体记录进行依次直接插入排序。
设计思路:
1.首先用一个增量来分组,控制增量为一层循环
2.然后控制分组为1层循环,假如增量一开始为5,则分组为:第一组:0 5 15…第二组:1 6 11…
3.直接插入排序
注意这里是对这些分组进行直接插入排序
最后增量为1,就是对整个序列进行直接插入排序
#include <iostream>
using namespace std;
//希尔排序
void shellSort(int arrs[], int len){
for(int d=len/2; d>=1; d=d/2){//控制增量
for(int k=0; k<d; k++){//控制分组
for(int i=k+d; i<len; i=i+d){//直接插入排序
//直接插入排序,默认第一个元素有序,每次从最后一个有序序列后增量单位开始
int temp = arrs[i];
int j = i-d;//游动下标指向有序序列最后一个元素
while(j>=0 && temp<arrs[j]){
arrs[j+d] = arrs[j];//移动增量个单位
j-=d;
}
arrs[j+d] = temp;
}
}
}
}
int main(){
int arrs[] = {1,10,9,4,7,5,8,2,3,6};
int len = sizeof(arrs)/sizeof(int);
shellSort(arrs,len);
for(int &i : arrs){
cout<<i<<" ";
}
return 0;
}
希尔排序在序列元素较多时,比较次数比直接插入排序少很多
1000个长度的数组,分别用直接插入排序和希尔排序分别比较多少次
#include <iostream>
#include <cstdlib>
using namespace std;
//直接插入排序
int count1=0;
void isSort(int arrs[], int len){
for(int i=1; i<len; i++){//默认看作第一个元素为有序,从第二个元素开始往前比较(因为相邻的比较所以是稳定的)
int temp = arrs[i];
int j = i-1;//有序序列最后一个下标
while(j>=0 && temp<arrs[j]){//升序,降序的话是>
count1++;
arrs[j+1] = arrs[j];// 比较过程中,待插入元素是小于当前元素,则当前元素后移
j--;
}
arrs[j+1] = temp;
}
}
//希尔排序
int count2=0;
void shellSort(int arrs[], int len){
for(int d=len/2; d>=1; d=d/2){//控制增量
for(int k=0; k<d; k++){//控制分组
for(int i=k+d; i<len; i=i+d){//直接插入排序
int temp = arrs[i];
int j = i-d;//游动下标指向有序序列最后一个元素
while(j>=0 && temp<arrs[j]){
count2++;
arrs[j+d] = arrs[j];//移动增量个单位
j-=d;
}
arrs[j+d] = temp;
}
}
}
}
int main(){
int arrs[1000];
int arrs2[1000];
for(int i=0; i<1000; i++){
arrs[i] = rand()%100;
arrs2[i] = rand()%100;
}
isSort(arrs,1000);
shellSort(arrs2,1000);
cout<<"count1: "<<count1<<endl;
cout<<"count2: "<<count2<<endl;
return 0;
}
来源:CSDN
作者:Dr_W
链接:https://blog.csdn.net/qq_42363032/article/details/103930122