DSharp 无心之心,道之所存
寻找生命的意义
posts - 31,  comments - 89,  trackbacks - 1

发现.net排序算法的Bug!
.Net Framework 的ArrayList的Sort使用了快速排序算法,只要加入的元素实现IComparable接口,就可调用Sort方法快速排序,但最近在编程中发现了此算法的Bug,如下例子。

using System;
using System.Collections;
using System.Diagnostics;
namespace SortTest
{
    
/// <summary>
    
/// Summary description for Class1.
    
/// </summary>

    class SortTest
    
{
        
/// <summary>
        
/// The main entry polong for the application.
        
/// </summary>

        [STAThread]
        
static void Main(string[] args)
        
{
            ArrayList list 
= new ArrayList();
            TestItem item1 
= new TestItem(1"1");
            TestItem item2 
= new TestItem(1"2");
            TestItem item3 
= new TestItem(1"3");
            TestItem item4 
= new TestItem(1"4");
            TestItem item5 
= new TestItem(1"5");
            TestItem item6 
= new TestItem(1"6");
            list.Add(item3);
            list.Add(item1);
            list.Add(item2);
            list.Add(item4);
            list.Add(item6);
            list.Add(item5);

            list.Sort();

            
foreach(TestItem item in list)
                Console.WriteLine(item.Name);

            Console.ReadLine();
        }


        
public class TestItem : IComparable
        
{
            
private int x;
            
public int X
            
{
                
get
                
{
                    
return x;
                }

            }


            
private string name;
            
public string Name
            
{
                
get
                
{
                    
return name;
                }

            }


            
public TestItem(int x, string name)
            
{
                
this.x = x;
                
this.name = name;
            }

        
            
public int CompareTo(object obj)
            
{
                TestItem item 
= obj as TestItem;
                Debug.Assert(item 
!= null);
                
return (int)(this.x - item.x);
            }

        }

    }

}


期望输出:3,1,2,4,6,5
实际输出:4,6,5,3,1,2

发现在排序的过程中,对于相等的对象,排序后前后位置被折半对调了,所以如果排序的对象中如果相等,输出不能保证原来的顺序。

posted on 2004-11-12 19:10 DSharp 阅读(1314) 评论(6)  编辑 收藏

FeedBack:
2004-11-12 19:32 | 寒枫天伤      
.............这不是bug,这是算法问题
  回复  引用  查看    
2004-11-12 19:35 | sumtec      
真有此事?如果有的话也有可能,因为快速排序并不是稳定排序,或者说并不保证相等元素的顺序和原来一致。呵呵,好久没有动过这些知识了,不知道对不对了。不过按道理来讲,这种不稳定性也应该在发生交换的时候才会发生,但这里似乎看不出有交换的必要性。不太清楚问题发生的机制。

另外有一个地方的写法似乎不是很对,最后CompareTo虽然实际上是通过和零比较来断定大小关系的,但是规范上面好像写的是-1、0、1这三个值。一般来说我写的时候就是写成:
return this.x.CompareTo(item.x);

感觉保险一点。
  回复  引用  查看    
2004-11-12 21:37 | montaque      
你从哪里觉得这是bug?
  回复  引用  查看    
2004-11-12 22:50 | Meyer      
sumtec 说的对的
快速排序不是稳定的算法Sort

  回复  引用  查看    
2004-11-25 11:11 | Teaks [未注册用户]
这是算法的特性啦,不稳定排序嘛。
  回复  引用    
2008-02-29 15:12 | Sunny _Paul [未注册用户]
你的TestItem对象里面的值怎么都是1啊。
我修改正确后测试,发现没有问题,给大家纠正一下。

共同进步。。。。。。
(差点把我忽悠了。。。。。。哈哈)
  回复  引用    

标题  
姓名  
主页
Email (只有博主才能看到) 
验证码 *  看不清,换一张 [登录][注册]
内容(请不要发表任何与政治相关的内容)  
  登录  使用高级评论  新用户注册  返回页首  恢复上次提交      


相关链接:
 



Free Web Counter

<2004年11月>
31123456
78910111213
14151617181920
21222324252627
2829301234
567891011

与我联系

搜索

 

常用链接

留言簿(3)

随笔分类(26)

随笔档案(31)

文章分类(1)

文章档案(2)

收藏夹(1)

最新随笔

积分与排名

  • 积分 - 17656
  • 排名 - 2149

最新评论

阅读排行榜

评论排行榜