基础知识
理解
希尔(shell)排序:又称为缩小增量排序,是对于直接插入排序的优化。
直接插入排序的缺点在于时间复杂度O(n^2),也就是说n大的话,n^2就会特别大。
在希尔排序中,将n尽可能变小:
将数据分段,分成好几段,则n变小。
如果n=15,n^2=225;
假如分为3段,则一段5个值,则时间 = 5^2 * 3 = 75;
但是这里只是说明这三段分别有序,合在一起,不一定有序。
但是,直接插入排序还有一个特点:数据越有序,则交换的次数越少,时间复杂度就越低。
所以,可以利用直接插入排序这一特点是数据变得越来越有序,最后应用直接插入排序(group=1).
时间复杂度
O(n^1.3)<--->O(n^1.5)
空间复杂度
O(1)
稳定性
不稳定
图解
实现
#include <iostream>
#include <assert.h>
using namespace std;
#define DATANUM 15
void Show(int* arr, int length)
{
for (int i = 0; i < length; i++)
{
cout<<arr[i]<<" ";
}
cout << endl;
}
int IsOrder(int* arr, int length)
{
for (int i = 0; i < length - 1; i++)
{
if (arr[i] > arr[i + 1])
{
return 0;
}
}
return 1;
}
void Swap(int* pa, int* pb)
{
int tmp = *pa;
*pa = *pb;
*pb = tmp;
}
static void Shell(int* arr, static int length, int group)
{
int j = 0;
for (int i = group; i < length; i++)
{
int tmp = arr[i];
for (j = i - group; j >= 0 && tmp < arr[j]; j = j - group)
{
arr[j + group] = arr[j];
}
arr[j + group] = tmp;
}
}
static void Shell2(int* arr, static int length, int group)
{
int j = 0;
for (int i = 0; i < group; i++)
{
int tmp = arr[i];
for (j = i + group; j + group < length && tmp < arr[j]; j = j + group)
{
arr[j + group] = arr[j];
}
arr[j + group] = tmp;
}
}
void Shell_Sort(int* arr, int length)
{
assert(arr != NULL || length > 1);
if (arr == NULL || length < 2)
{
cout<<"Shell_Sort:Invalid Array"<<endl;
return;
}
int group[] = { 5,3,1 };
for (int i = 0; i < sizeof(group) / sizeof(int); i++)
{
Shell(arr, length, group[i]);
}
}
int main()
{
int arr[DATANUM];
for (int i = 0; i < DATANUM; i++)
{
arr[i] = rand() % 100;
}
printf("Before Shell_Sort:");
Show(arr, DATANUM);
Shell_Sort(arr, DATANUM);
if (IsOrder(arr, DATANUM))
{
cout<<"After Shell_Sort:";
Show(arr, DATANUM);
}
else
{
cout<<"Shell_Sort Failed"<<endl;
}
return 0;
}