我自己想出来的排序算法,求大虾拍砖

zl5z 2010-01-19 01:04:44
http://hi.baidu.com/richselian/blog/item/ee8cd383e5c7229bf703a60b.html
...全文
262 17 打赏 收藏 转发到动态 举报
写回复
用AI写文章
17 条回复
切换为时间正序
请发表友善的回复…
发表回复
xiaofan8888 2010-01-20
  • 打赏
  • 举报
回复
好帖子,呵呵,学习了,
zl5z 2010-01-20
  • 打赏
  • 举报
回复
11楼 WorseCase时间复杂度是O(n*sqrt(n))
zl5z 2010-01-20
  • 打赏
  • 举报
回复
这个算法绝对不是ShellSort的退化版,你们说的“退化版”我想应该是这样:
void shell_sb_sort(int* array, int from, int to)
{
int i, noswap = 0, edge = sqrt(to - from + 1);

// 只有一个Gap的ShellSort
while(!noswap) for(noswap = 1, i = from; i < to; i++)
if(i + edge <= to && array[i] > array[i + edge])
swap(&array[i], &array[i + edge]), noswap = 0;
noswap = 0;
while(!noswap) for(noswap = 1, i = from; i < to; i++)
if(array[i] > array[i + 1])
swap(&array[i], &array[i + 1]), noswap = 0;
return;
}
这个还是基于线性空间的比较,效率和比我的排序法差了很多。
Sorting 100000 numbers ranged from 1 to 32767
========= Test Result =========
Size Filename Time
1458 2DBubbleSort.c 0.913s
1501 ShellSbSort.c 6.283s
1315 BubbleSort.c 61.273s

至于为什么排序一个元素的时间是sqrt(n),我们可以考虑最坏情况(从第一个移动到最后一个):
对于传统冒泡法,需要移动(n-1)次。
对于我的排序法,在一个边长sqrt(n)的二维表里面,从左上角移动到右下角只需要延对角线移动2*[sqrt(n)-1]次就可以了。

在百度贴吧上有人提出这个算法和"Young Tableau"有关系,我不知道这个名词指的是什么,网上查不到。如果最后证实这个算法不是我首创的,那就当我给大家介绍一个非主流算法好了。
  • 打赏
  • 举报
回复
挺好的,加快了泡泡的速度。

有点像求素数的筛数,大筛子和小筛子。

不知道加个中筛子是否可行。
go_Michael 2010-01-19
  • 打赏
  • 举报
回复
确实和希尔排序挺像的
gbb21 2010-01-19
  • 打赏
  • 举报
回复
希望作者给出时间复杂度的严格证明~
gbb21 2010-01-19
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 gbb21 的回复:]
感觉像shellsort的退化版~事实也证明比shellsort差一些~
[/Quote]
所以WorstCast 时间复杂度有O(N^2)貌似是必然的~
gbb21 2010-01-19
  • 打赏
  • 举报
回复
感觉像shellsort的退化版~事实也证明比shellsort差一些~
80后传播者 2010-01-19
  • 打赏
  • 举报
回复
上面提问有误
为什么排序一个元素的时间复杂度为O(sqrt(n))呢?
80后传播者 2010-01-19
  • 打赏
  • 举报
回复
请教一下:
为什么排序一个元素的时间复杂度为O(n)呢?
for(noswap = 1, i = from; i < to; i++)
{
if(array[i] > array[i + 1])
swap(&array[i], &array[i + 1]), noswap = 0;
if(i + edge <= to && array[i + 1] > array[i + edge]) swap(&array[i + 1], &array[i + edge]), noswap = 0;
}
是完成一个元素的排序吧,但是循环是从form到to,第一个比较array[i] > array[i + 1]是直到to-1的
而array[i + 1] > array[i + edge]的比较只是一个“跨越式”的比较,可能会使数列尽快趋于有序,但是没有较少比较的次数啊。请指教。
zl5z 2010-01-19
  • 打赏
  • 举报
回复
6楼的未必可以加速,因为你的方法是2 * 0.5n == n,即使能提速也只是O(n)的常数项减小而已,而我的排序法是2 * sqrt(n)(外层循环最多执行sqrt(n)次),速度上是有本质提升的。
5楼能不能帮我找找?我这里一时弄不到这本书,我在wikipedia上没看到这种算法。
LeonTown 2010-01-19
  • 打赏
  • 举报
回复
看了一下您的算法,
我联想到另一个加速的例子:


//比如,传统上拷贝一个数组元素的代码为:
for(pSrc=srcArr, pDst=dstArr, i=0; i<num; i++)
*pDst++ = *pSrc++; //一个一个元素的拷贝

//而如果如下编码,则可以加速:
for(pSrc=srcArr, pDst=dstArr, i=0; i<num; i+=2)
{
*pDst++ = *pSrc++;
*pDst++ = *pSrc++; //一次拷贝两个(或多个)元素(还要避免越界)
}


感觉上述提速的原理有些类似你的排序代码。。。
dskit 2010-01-19
  • 打赏
  • 举报
回复
或许你这种改进已经有人研究过了哦

算法设计与分析, 朱清新的书里好像就讨论了两种改进方法。
zl5z 2010-01-19
  • 打赏
  • 举报
回复
确实有差距,感觉快排已经是比较排序法的极根了。不过当时第一次测试的时候确实很兴奋,没想到在冒泡排序里加上两行会有这么大的效率提升。
V68V6 2010-01-19
  • 打赏
  • 举报
回复
精神可嘉。。。

可用性需要实践去检验。。。
  • 打赏
  • 举报
回复
不错,不错,但是效率跟快排,堆排这些还是有差距哈。。
yujunfei_xy 2010-01-19
  • 打赏
  • 举报
回复
顶了再看!
赞一下,先!

33,008

社区成员

发帖
与我相关
我的任务
社区描述
数据结构与算法相关内容讨论专区
社区管理员
  • 数据结构与算法社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧