希尔排序是对插入排序的一种改进
一、基本思路
希尔排序按照增量进行分组,在每一个组别内进行插入排序,一般而言,希尔排序的增量取值为不断除2,比如,现在需要对arr[9]={9,8,7,6,5,4,3,2,1};这组数进行排序,那么可以简单描述一下其思路。
首先,需要确定一个增量序列,如4(length/2),2,1,从大到小使用增量
第一,使用第一个增量4,将序列划分为若干个子序列,下标组合为0-4-8,1-5,2-6,3-7
第二,依次对子序列使用直接插入排序法
第三,使用第二个增量2,将序列划分为若干个子序列,下标组合为0-2-4-6-8,1-3-5-7
第四,依次对子序列使用直接插入排序法
第五,使用第三个增量1,这时只有一个子序列,就是原序列0-1-2-3-4-5-6-7-8
第六,使用直接插入排序法
二、时间复杂度和控件复杂度
1、时间复杂度 O(nlogn)~O(n^2)
2、空间复杂度 O(1)
三、稳定性
由于相同的元素可能会被划分到不同的子序列单独排序,因此希尔排序是一种不稳定的排序
比如{9 2 2 3 5},按照希尔排序的思路,最终的结果第2个2会在第一个2之前
四、代码实现
#include<bits/stdc++.h> using namespace std; #define MAX 100 //交换函数 void Swap(int* a,int* b) { int temp=*a; *a=*b; *b=temp; } //打印函数 void printArray(int arr[],int length) { for(int i=0;i<length;i++) { cout<<arr[i]<<" "; } cout<<endl; } void shellSort(int arr[],int length) { //外层循环不断的缩小增量,减去增量和加上增量进行比较 for(int interval=length/2;interval>0;interval=interval/2) { //增量为1的插入排序 for(int i=interval;i<length;i++) { int target=arr[i]; int j=i-interval; while(j>-1&&target<arr[j]) { arr[j+interval]=arr[j]; j-=interval; } arr[j+interval]=target; } } } int main() { int arr[MAX]; srand((unsigned int)time(NULL)); for(int i=0;i<MAX;i++) { int randNum=rand()%MAX; arr[i]=randNum; } printArray(arr,MAX); shellSort(arr,MAX); printArray(arr,MAX); getchar(); return 0; }