我正在尝试自己实现shell排序算法。我编写了自己的代码,并没有注意任何代码示例只能看the video of algorithm description
我的排序有效,但非常慢(冒泡排序100项 - 0.007秒;外壳排序100项 - 4.83秒),如何改进它呢?
void print(vector<float>vec)
{
for (float i : vec)
cout << i << " ";
cout << "\n\n";
}
void Shell_sorting(vector<float>&values)
{
int swapping = 0;
int step = values.size();
clock_t start;
double duration;
start = clock();
while (step/2 >= 1)
{
step /= 2;
for (int i = 0; i < values.size()-step; i++)
{
if ((i + step < values.size()))
{
if ((values[i + step] < values[i]))
{
swap(values[i], values[i + step]);
print(values);
++swapping;
int c = i;
while (c - step > 0)
{
if (values[c] < values[c - step])
{
swap(values[c], values[c - step]);
print(values);
++swapping;
c -= step;
}
else
break;
}
}
}
else
break;
}
}
duration = (clock() - start) / (double)CLOCKS_PER_SEC;
print(values);
cout << swapping << " " << duration;
print(values);
}
答案 0 :(得分:0)
更好的实施可能是:
#include <iostream>
#include <vector>
int main()
{
std::vector<int> vec = {
726,621,81,719,167,958,607,130,263,108,
134,235,508,407,153,162,849,923,996,975,
250,78,460,667,654,62,865,973,477,912,
580,996,156,615,542,655,240,847,613,497,
274,241,398,84,436,803,138,677,470,606,
226,593,620,396,460,448,198,958,566,599,
762,248,461,191,933,805,288,185,21,340,
458,592,703,303,509,55,190,318,310,189,
780,923,933,546,816,627,47,377,253,709,
992,421,587,768,908,261,946,75,682,948,
};
std::vector<int> gaps = {5, 2, 1};
int j;
for (int gap : gaps) {
for (int i = gap; i < vec.size(); i++)
{
j = i-gap;
while (j >= 0) {
if (vec[j+gap] < vec[j])
{
int temp = vec[j+gap];
vec[j+gap] = vec[j];
vec[j] = temp;
j = j-gap;
}
else break;
}
}
}
for (int item : vec) std::cout << item << " " << std::endl;
return 0;
}
我更喜欢使用向量来存储间隙数据,这样您就不需要计算除法(这是一个扩展操作)。此外,这种选择使您的代码更具灵活性。
extern循环在间隙值上循环。一旦选择了差距,就从vec[gap]
开始迭代你的向量,并根据Shell排序的逻辑探索是否有更小的元素。
因此,您开始设置j=i-gap
并测试if条件。如果为true,则交换项目,然后重复while循环递减j
。 注意:vec[j+gap]
是最后一个循环周期中交换的元素。如果条件为真,则没有理由继续循环,因此您可以使用break
退出。
在我的机器上,使用time
shell命令计算了0.002秒(时间包括打印数字的过程)。
P.S。生成所有数字并将它们写入数组中,因为我懒得编写随机函数,我使用this link然后我用shell编辑了输出:
sed -e 's/[[:space:]]/,/g' num | sed -e 's/$/,/'