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、排序過程圖