1、测试代码
#include <iostream>
using namespace std;
int g_loop = 0; /* 循环计数 */
int g_move = 0; /* 数据移动次数 */
void output_info(int *buff,int len, int flag)
{
int i;
if(0 == flag)
{
cout << "before: ";
}
else
{
cout << "after: ";
}
for(i = 0; i < len; ++i)
{
cout << *(buff + i) << " ";
}
cout << endl;
}
/* 插入排序 */
void insert_sort(int arr[], int gap, int len)
{
int temp;
int i;
int j;
for (i = gap; i < len; ++i)
{
output_info(arr, len, 0);
temp = arr[i];
for (j = i - gap; j >= 0; j -= gap)
{
++g_loop;
if(temp < arr[j])
{
arr[j + gap] = arr[j];
++g_move;
}
else
{
break;
}
}
if(j != i - gap)
{
arr[j + gap] = temp;
}
output_info(arr, len, 1);
cout << endl;
}
}
/* 希尔排序 */
void shell_sort(int arr[], int len)
{
int gap;
if (len < 2)
{
return;
}
for (gap = len / 2; gap > 0; gap /= 2)
{
insert_sort(arr, gap, len);
}
return;
}
int main()
{
int buff[10]= {10,9,8,7,6,5,4,3,2,1};
shell_sort(buff, 10);
// insert_sort(buff, 1, 10);
cout << "move=" << g_move << endl;
cout << "loop=" << g_loop << endl;
return 0;
}
2、测试log
before: 10 9 8 7 6 5 4 3 2 1
after: 5 9 8 7 6 10 4 3 2 1
before: 5 9 8 7 6 10 4 3 2 1
after: 5 4 8 7 6 10 9 3 2 1
before: 5 4 8 7 6 10 9 3 2 1
after: 5 4 3 7 6 10 9 8 2 1
before: 5 4 3 7 6 10 9 8 2 1
after: 5 4 3 2 6 10 9 8 7 1
before: 5 4 3 2 6 10 9 8 7 1
after: 5 4 3 2 1 10 9 8 7 6
before: 5 4 3 2 1 10 9 8 7 6
after: 3 4 5 2 1 10 9 8 7 6
before: 3 4 5 2 1 10 9 8 7 6
after: 3 2 5 4 1 10 9 8 7 6
before: 3 2 5 4 1 10 9 8 7 6
after: 1 2 3 4 5 10 9 8 7 6
before: 1 2 3 4 5 10 9 8 7 6
after: 1 2 3 4 5 10 9 8 7 6
before: 1 2 3 4 5 10 9 8 7 6
after: 1 2 3 4 5 10 9 8 7 6
before: 1 2 3 4 5 10 9 8 7 6
after: 1 2 3 4 5 8 9 10 7 6
before: 1 2 3 4 5 8 9 10 7 6
after: 1 2 3 4 5 8 7 10 9 6
before: 1 2 3 4 5 8 7 10 9 6
after: 1 2 3 4 5 6 7 8 9 10
before: 1 2 3 4 5 6 7 8 9 10
after: 1 2 3 4 5 6 7 8 9 10
before: 1 2 3 4 5 6 7 8 9 10
after: 1 2 3 4 5 6 7 8 9 10
before: 1 2 3 4 5 6 7 8 9 10
after: 1 2 3 4 5 6 7 8 9 10
before: 1 2 3 4 5 6 7 8 9 10
after: 1 2 3 4 5 6 7 8 9 10
before: 1 2 3 4 5 6 7 8 9 10
after: 1 2 3 4 5 6 7 8 9 10
before: 1 2 3 4 5 6 7 8 9 10
after: 1 2 3 4 5 6 7 8 9 10
before: 1 2 3 4 5 6 7 8 9 10
after: 1 2 3 4 5 6 7 8 9 10
before: 1 2 3 4 5 6 7 8 9 10
after: 1 2 3 4 5 6 7 8 9 10
before: 1 2 3 4 5 6 7 8 9 10
after: 1 2 3 4 5 6 7 8 9 10
move=13
loop=27
3、算法分析
- 原地排序算法;
- 非稳定排序算法;
- 空间复杂度 O(1);
- 时间复杂度 O(nlogn)。时间复杂度与增量序列选择有关。
4、优化增量序列
采用Hibbard增量序列,时间复杂度为O(n^1.5)。
Hibbard增量序列=[1,3,7,15,31,63,...];
#include <iostream>
#include<math.h>
using namespace std;
int g_loop = 0; /* 循环计数 */
int g_move = 0; /* 数据移动次数 */
void output_info(int *buff,int len, int flag)
{
int i;
if(0 == flag)
{
cout << "before: ";
}
else
{
cout << "after: ";
}
for(i = 0; i < len; ++i)
{
cout << *(buff + i) << " ";
}
cout << endl;
}
/* 插入排序 */
void insert_sort(int arr[], int gap, int len)
{
int temp;
int i;
int j;
for (i = gap; i < len; ++i)
{
output_info(arr, len, 0);
temp = arr[i];
for (j = i - gap; j >= 0; j -= gap)
{
++g_loop;
if(temp < arr[j])
{
arr[j + gap] = arr[j];
++g_move;
}
else
{
break;
}
}
if(j != i - gap)
{
arr[j + gap] = temp;
}
output_info(arr, len, 1);
cout << endl;
}
}
//计算Hibbard增量
int get_hibbard(int count, int idx)
{
return (int)(pow(2, count - idx + 1) - 1);
}
/* 希尔排序修改增量 */
void shell_sort(int arr[], int len)
{
int gap;
int i;
int count = (int)(log(len + 1) / log(2)); /* 排序趟数 */
if (len < 2)
{
return;
}
cout << "count=" << count << endl;
for (i = 1; i <= count; ++i)
{
gap = get_hibbard(count, i);
cout << "gap=" << gap << endl;
insert_sort(arr, gap, len);
}
return;
}
int main()
{
int buff[10]= {10,9,8,7,6,5,4,3,2,1};
shell_sort(buff, 10);
cout << "move=" << g_move << endl;
cout << "loop=" << g_loop << endl;
return 0;
}
/*************************************************************/
count=3
gap=7
before: 10 9 8 7 6 5 4 3 2 1
after: 3 9 8 7 6 5 4 10 2 1
before: 3 9 8 7 6 5 4 10 2 1
after: 3 2 8 7 6 5 4 10 9 1
before: 3 2 8 7 6 5 4 10 9 1
after: 3 2 1 7 6 5 4 10 9 8
gap=3
before: 3 2 1 7 6 5 4 10 9 8
after: 3 2 1 7 6 5 4 10 9 8
before: 3 2 1 7 6 5 4 10 9 8
after: 3 2 1 7 6 5 4 10 9 8
before: 3 2 1 7 6 5 4 10 9 8
after: 3 2 1 7 6 5 4 10 9 8
before: 3 2 1 7 6 5 4 10 9 8
after: 3 2 1 4 6 5 7 10 9 8
before: 3 2 1 4 6 5 7 10 9 8
after: 3 2 1 4 6 5 7 10 9 8
before: 3 2 1 4 6 5 7 10 9 8
after: 3 2 1 4 6 5 7 10 9 8
before: 3 2 1 4 6 5 7 10 9 8
after: 3 2 1 4 6 5 7 10 9 8
gap=1
before: 3 2 1 4 6 5 7 10 9 8
after: 2 3 1 4 6 5 7 10 9 8
before: 2 3 1 4 6 5 7 10 9 8
after: 1 2 3 4 6 5 7 10 9 8
before: 1 2 3 4 6 5 7 10 9 8
after: 1 2 3 4 6 5 7 10 9 8
before: 1 2 3 4 6 5 7 10 9 8
after: 1 2 3 4 6 5 7 10 9 8
before: 1 2 3 4 6 5 7 10 9 8
after: 1 2 3 4 5 6 7 10 9 8
before: 1 2 3 4 5 6 7 10 9 8
after: 1 2 3 4 5 6 7 10 9 8
before: 1 2 3 4 5 6 7 10 9 8
after: 1 2 3 4 5 6 7 10 9 8
before: 1 2 3 4 5 6 7 10 9 8
after: 1 2 3 4 5 6 7 9 10 8
before: 1 2 3 4 5 6 7 9 10 8
after: 1 2 3 4 5 6 7 8 9 10
move=11
loop=25
5、排序过程图