您的位置:程序门 -> vc/mfc -> 图形处理/算法



闲来无事,放分 + 算法(clistctrl的排序算法)。


[收藏此页] [打印本页]选择字色:背景色:字体:[][][]


闲来无事,放分 + 算法(clistctrl的排序算法)。[已结贴,结贴人:vcplayer]
发表于:2007-08-17 14:44:46 楼主
加班了两个月,好不容易轻松下来。来和大家讨论一下今天用clistctrl的小发现:

对列表控件中的项目进行排序。10条记录用“冒泡”的话要做45次比较;但clistctrl只做了22次(根据我的数据测试),疑似“二分”法快排!   正在分析它的算法细节。有兴趣或知情的朋友能否说说你们的看法?

呵呵,祝大家周末愉快。
发表于:2007-08-17 14:47:561楼 得分:2
jf   ding
发表于:2007-08-17 14:52:352楼 得分:2
周末愉快,请上分
发表于:2007-08-17 15:01:243楼 得分:5
不清楚windows用的什么算法,但不是冒泡就是了。。。
发表于:2007-08-17 15:14:184楼 得分:5
应该是二分法吧,vcl也是二分法啊。m$那么多人,写个二分法不会有问题吧。
以上纯属瞎猜。
发表于:2007-08-17 15:14:545楼 得分:10
用高低2叉树的结构,高的值永远在左边,低的值永远在右,这样放的话查找起来很节省
发表于:2007-08-17 15:26:356楼 得分:0
补充:ms对10条记录的22次比较顺序:(记录编号从1~10,每次是两两比较)

比较次数:     参与比较的记录号
1                                 3、4
2                                 2、3
3                                 1、2
4                                 1、3
5                                 6、7
6                                 5、6
7                                 9、10
8                                 8、10
9                                 5、8
10                               6、8
11                               6、10
12                               6、9
13                               7、9
14                               2、5
15                               1、5
16                               3、5
17                               3、8
18                               3、10
19                               4、10
20                               4、6
21                               4、9
22                               4、7

cayido()的二叉树提醒了俺:)。哈哈,楼下继续。。。。。。。
发表于:2007-08-17 15:57:417楼 得分:8
还真没研究过,晚上看看它的代码
发表于:2007-08-17 16:12:498楼 得分:0
ls的说的是源码?能否发一份共享啊:)。
发表于:2007-08-17 16:16:419楼 得分:0
哈哈,让大家见笑了,我还以为源码附在mfc中呢,   原来这个实现是在标准控件内部..   :)
发表于:2007-08-17 16:26:1810楼 得分:5
它可能直接使用qsort函数了
发表于:2007-08-17 16:40:2611楼 得分:100
windows的实现代码:

bool   near   pascal   listview_onsortitems(lv   *plv,   lparam   lparam,   pfnlvcompare   pfncompare,   bool   bpasslp)
{
        lvsortinfo   sortinfo;
        listitem   far   *pitemfocused;
        sortinfo.pfncompare   =   pfncompare;
        sortinfo.lparam           =   lparam;
        sortinfo.plv   =   plv;
        sortinfo.bpasslp   =   bpasslp;

      if   (listview_isownerdata(plv))   {
            ripmsg(0,   "lvm_sortitems:   invalid   for   owner-data   listview ");
            return   false;
      }

        listview_dismissedit(plv,   true);         //   cancel   edits

        //   we 're   going   to   screw   with   the   indices,   so   stash   away   the   pointer   to   the
        //   focused   item.
        if   (plv-> ifocus   !=   -1)   {
                pitemfocused   =   listview_getitemptr(plv,   plv-> ifocus);
        }   else
                pitemfocused   =   null;

        if   (listview_sortallcolumns(plv,   &sortinfo))   {

                //   restore   the   focused   item.
                if   (pitemfocused)   {
                        int   i;
                        for   (i   =   listview_count(plv)   -   1;   i   > =   0   ;   i--)   {
                                if   (listview_getitemptr(plv,   i)   ==   pitemfocused)   {
                                        plv-> ifocus   =   i;
                                        plv-> imark   =   i;
                                }
                        }
                }

                if   (listview_issmallview(plv)   ¦ ¦   listview_isiconview(plv))
                {
                        listview_commonarrange(plv,   lva_default,   plv-> hdpa);
                }
                else   if   (listview_isreportview(plv)   ¦ ¦   listview_islistview(plv))
                {
                        invalidaterect(plv-> ci.hwnd,   null,   true);
                }

                //   the   items   in   the   view   have   moved   around;   let   apps   know
                mynotifywinevent(event_object_reorder,   plv-> ci.hwnd,   objid_client,   0);
                return(true);
        }
        return   false;
}
发表于:2007-08-17 16:40:3512楼 得分:0
bool   near   pascal   listview_sortallcolumns(lv*   plv,   lvsortinfo   far   *   psi)
{
        assert(!listview_isownerdata(plv));

        listview_invalidatettlasthit(plv,   plv-> ittlasthit);

        //   don 't   do   this   optimization   if   we   will   need   the   indices   to   sort   by
        if   (psi-> bpasslp   &&   ((!plv-> hdpasubitems)   ¦ ¦   !dpa_getptrcount(plv-> hdpasubitems)))   {
                psi-> fsortindices   =   false;
                return   (dpa_sort(plv-> hdpa,   listview_sortcallback,   (lparam)psi));
        }   else   {
                //   if   we   need   to   sort   several   hdpa 's,   create   one   dpa   of   just   indices
                //   and   sort   that,   then   fix   up   all   the   dpa 's
                bool   freturn   =   false;
                hdpa   hdpa;
                int   i;
                int   imax;
                void   far   *   far   *   ph;
                void   far   *   far   *pnewindices;

                //   initialize   the   hdpa   with   indices
                hdpa   =   dpa_clone(plv-> hdpa,   null);
                if   (hdpa)   {
                        assert(dpa_getptrcount(plv-> hdpa)   ==   dpa_getptrcount(hdpa));
                        ph   =   pnewindices   =   dpa_getptrptr(hdpa);
                        imax   =   dpa_getptrcount(hdpa);
                        for(   i   =   0;   i   <   imax;   ph++,   i++)   {
                                *ph   =   (lpvoid)(handle)i;
                        }

                        psi-> fsortindices   =   true;
                        if   (dpa_sort(hdpa,   listview_sortcallback,   (lparam)psi))   {
#ifdef   win32
                                ph   =   localalloc(lptr,   sizeof(lpvoid)   *   imax);
#else
                                ph   =   alloc(sizeof(lpvoid)   *   imax);
#endif

                                if   (ph)   {
                                        int   j;
                                        void   far   *   far   *psubitems;

                                        //   we   could   get   here   because   bpasslp   is   false,   even   if   we   don 't   have   subitems
                                        if   (plv-> hdpasubitems   &&   dpa_getptrcount(plv-> hdpasubitems))
                                        {
                                                for   (i   =   dpa_getptrcount(plv-> hdpasubitems)   -   1;   i   > =   0;   i--)   {
                                                        hdpa   hdpasubitem   =   listview_getsubitemdpa(plv,   i);

                                                        if   (hdpasubitem)   {

                                                                //   make   sure   it 's   of   the   right   size
                                                                while   (dpa_getptrcount(hdpasubitem)   <   imax)   {
                                                                        if   (dpa_insertptr(hdpasubitem,   imax,   null)   ==   -1)
                                                                                goto   bail;
                                                                }


                                                                //   actually   copy   across   the   dpa   with   the   new   indices
                                                                psubitems   =   dpa_getptrptr(hdpasubitem);
                                                                for   (j   =   0;   j   <   imax;   j++)   {
                                                                        ph[j]   =   psubitems[ptrtoulong(pnewindices[j])];
                                                                }

                                                                //   finally,   copy   it   all   back   to   the   psubitems;
                                                                hmemcpy(psubitems,   ph,   sizeof(lpvoid)   *   imax);
                                                        }
                                                }
                                        }

                                        //   now   do   the   main   hdpa
                                        psubitems   =   dpa_getptrptr(plv-> hdpa);
                                        for   (j   =   0;   j   <   imax;   j++)   {
                                                ph[j]   =   psubitems[ptrtoulong(pnewindices[j])];
                                        }

                                        //   finally,   copy   it   all   back   to   the   psubitems;
                                        hmemcpy(psubitems,   ph,   sizeof(lpvoid)   *   imax);
                                        freturn   =   true;
bail:
#ifdef   win32
                                        localfree(ph);
#else
                                        free(ph);
#endif

                                }
                        }
                        dpa_destroy(hdpa);
                }
                return   freturn;

        }
}
发表于:2007-08-17 16:41:5313楼 得分:0
希望能通过对外部数据的研究,还原出ms的这个排序算法:)。没有源码,就只有通过现象看本质了。

另:刚才发现,对于同样的数据,这个算法的比较次序不尽相同。
发表于:2007-08-17 16:42:1914楼 得分:0
bool   winapi   dpa_sort(hdpa   pdpa,   pfndpacompare   pfncmp,   lparam   lparam)
{
        sortparams   sp;

        sp.cp   =   pdpa-> cp;
        sp.pp   =   pdpa-> pp;
        sp.pfncmp   =   pfncmp;
        sp.lparam   =   lparam;

#ifdef   usequicksort
        return   dpa_quicksort(&sp);
#endif
#ifdef   useheapsort
        return   dpa_heapsort(&sp);
#endif
#ifdef   mergesort
        return   dpa_mergesort(&sp);
#endif
}
发表于:2007-08-17 16:42:5815楼 得分:0
呵呵,可以看到ms用了三种排序,快速排序,堆排序和归并排序,这三种都是性能较好的。
发表于:2007-08-17 16:43:3516楼 得分:0
先看quicksort:
#ifdef   usequicksort

bool   near   dpa_quicksort(sortparams   far*   psp)
{
        return   dpa_quicksort2(0,   psp-> cp   -   1,   psp);
}

bool   near   dpa_quicksort2(int   i,   int   j,   sortparams   far*   psp)
{
        void   far*   far*   pp   =   psp-> pp;
        lparam   lparam   =   psp-> lparam;
        pfndpacompare   pfncmp   =   psp-> pfncmp;

        int   ipivot;
        void   far*   pfirst;
        int   k;
        int   result;

        ipivot   =   -1;
        pfirst   =   pp[i];
        for   (k   =   i   +   1;   k   <=   j;   k++)
        {
                result   =   (*pfncmp)(pp[k],   pfirst,   lparam);

                if   (result   >   0)
                {
                        ipivot   =   k;
                        break;
                }
                else   if   (result   <   0)
                {
                        ipivot   =   i;
                        break;
                }
        }

        if   (ipivot   !=   -1)
        {
                int   l   =   i;
                int   r   =   j;
                void   far*   pivot   =   pp[ipivot];

                do
                {
                        void   far*   p;

                        p   =   pp[l];
                        pp[l]   =   pp[r];
                        pp[r]   =   p;

                        while   ((*pfncmp)(pp[l],   pivot,   lparam)   <   0)
                                l++;
                        while   ((*pfncmp)(pp[r],   pivot,   lparam)   > =   0)
                                r--;
                }   while   (l   <=   r);

                if   (l   -   1   >   i)
                        dpa_quicksort2(i,   l   -   1,   psp);
                if   (j   >   l)
                        dpa_quicksort2(l,   j,   psp);
        }
        return   true;
}
#endif     //   usequicksort
发表于:2007-08-17 16:44:0417楼 得分:0
再看heapsort:
#ifdef   useheapsort

void   near   dpa_heapsortpushdown(int   first,   int   last,   sortparams   far*   psp)
{
        void   far*   far*   pp   =   psp-> pp;
        lparam   lparam   =   psp-> lparam;
        pfndpacompare   pfncmp   =   psp-> pfncmp;
        int   r;
        int   r2;
        void   far*   p;

        r   =   first;
        while   (r   <=   last   /   2)
        {
                int   wrto2r;
                r2   =   r   *   2;

                wrto2r   =   (*pfncmp)(pp[r-1],   pp[r2-1],   lparam);

                if   (r2   ==   last)
                {
                        if   (wrto2r   <   0)
                        {
                                p   =   pp[r-1];   pp[r-1]   =   pp[r2-1];   pp[r2-1]   =   p;
                        }
                        break;
                }
                else
                {
                        int   wr2tor21   =   (*pfncmp)(pp[r2-1],   pp[r2+1-1],   lparam);

                        if   (wrto2r   <   0   &&   wr2tor21   > =   0)
                        {
                                p   =   pp[r-1];   pp[r-1]   =   pp[r2-1];   pp[r2-1]   =   p;
                                r   =   r2;
                        }
                        else   if   ((*pfncmp)(pp[r-1],   pp[r2+1-1],   lparam)   <   0   &&   wr2tor21   <   0)
                        {
                                p   =   pp[r-1];   pp[r-1]   =   pp[r2+1-1];   pp[r2+1-1]   =   p;
                                r   =   r2   +   1;
                        }
                        else
                        {
                                break;
                        }
                }
        }
}

bool   near   dpa_heapsort(sortparams   far*   psp)
{
        void   far*   far*   pp   =   psp-> pp;
        int   c   =   psp-> cp;
        int   i;

        for   (i   =   c   /   2;   i   > =   1;   i--)
                dpa_heapsortpushdown(i,   c,   psp);

        for   (i   =   c;   i   > =   2;   i--)
        {
                void   far*   p   =   pp[0];   pp[0]   =   pp[i-1];   pp[i-1]   =   p;

                dpa_heapsortpushdown(1,   i   -   1,   psp);
        }
        return   true;
}
#endif     //   useheapsort
发表于:2007-08-17 16:44:1518楼 得分:5
嗯,学习了
发表于:2007-08-17 16:44:3419楼 得分:0
晕,刚才回复的时候,没看见codewarrior(会思考的草)贴的代码。谢了,研究一下先:)。
发表于:2007-08-17 16:44:3720楼 得分:0
最后是mergesort:
#if   defined(mergesort)   &&   defined(win32)

#define   sortcompare(psp,   pp1,   i1,   pp2,   i2)   \
        (psp-> pfncmp(pp1[i1],   pp2[i2],   psp-> lparam))

//
//     this   function   merges   two   sorted   lists   and   makes   one   sorted   list.
//       psp-> pp[ifirst,   ifirst+cites/2-1],   psp-> pp[ifirst+citems/2,   ifirst+citems-1]
//
void   near   dpa_mergethem(sortparams   far*   psp,   int   ifirst,   int   citems)
{
        //
        //   notes:
        //     this   function   is   separated   from   dpa_mergesort2()   to   avoid   comsuming
        //   stack   variables.   never   inline   this.
        //
        int   chalf   =   citems/2;
        int   iin1,   iin2,   iout;
        lpvoid   *   ppvsrc   =   &psp-> pp[ifirst];

        //   copy   the   first   part   to   temp   storage   so   we   can   write   directly   into
        //   the   final   buffer.     note   that   this   takes   at   most   psp-> cp/2   dword 's
        hmemcpy(psp-> ppt,   ppvsrc,   chalf*sizeof(lpvoid));

        for   (iin1=0,   iin2=chalf,   iout=0;;)
        {
                if   (sortcompare(psp,   psp-> ppt,   iin1,   ppvsrc,   iin2)   <=   0)   {
                        ppvsrc[iout++]   =   psp-> ppt[iin1++];

                        if   (iin1==chalf)   {
                                //   we   used   up   the   first   half;   the   rest   of   the   second   half
                                //   should   already   be   in   place
                                break;
                        }
                }   else   {
                        ppvsrc[iout++]   =   ppvsrc[iin2++];
                        if   (iin2==citems)   {
                                //   we   used   up   the   second   half;   copy   the   rest   of   the   first   half
                                //   into   place
                                hmemcpy(&ppvsrc[iout],   &psp-> ppt[iin1],   (citems-iout)*sizeof(lpvoid));
                                break;
                        }
                }
        }
}

//
//     this   function   sorts   a   give   list   (psp-> pp[ifirst,ifirst-citems-1]).
//
void   near   dpa_mergesort2(sortparams   far*   psp,   int   ifirst,   int   citems)
{
        //
        //   notes:
        //       this   function   is   recursively   called.   therefore,   we   should   minimize
        //     the   number   of   local   variables   and   parameters.   at   this   point,   we
        //     use   one   local   variable   and   three   parameters.
        //
        int   chalf;

        switch(citems)
        {
        case   1:
                return;

        case   2:
                //   swap   them,   if   they   are   out   of   order.
                if   (sortcompare(psp,   psp-> pp,   ifirst,   psp-> pp,   ifirst+1)   >   0)
                {
                        psp-> ppt[0]   =   psp-> pp[ifirst];
                        psp-> pp[ifirst]   =   psp-> pp[ifirst+1];
                        psp-> pp[ifirst+1]   =   psp-> ppt[0];
                }
                break;

        default:
                chalf   =   citems/2;

                //   sort   each   half
                dpa_mergesort2(psp,   ifirst,   chalf);
                dpa_mergesort2(psp,   ifirst+chalf,   citems-chalf);
                //   then,   merge   them.
                dpa_mergethem(psp,   ifirst,   citems);
                break;
        }
}

bool   near   dpa_mergesort(sortparams   far*   psp)
{
        if   (psp-> cp==0)
                return   true;

        //   note   that   we   divide   by   2   below;   we   want   to   round   down
        psp-> ppt   =   localalloc(lptr,   psp-> cp/2   *   sizeof(lpvoid));
        if   (!psp-> ppt)
                return   false;

        dpa_mergesort2(psp,   0,   psp-> cp);
        localfree(psp-> ppt);
        return   true;
}
#endif   //   mergesort
发表于:2007-08-17 16:45:2621楼 得分:0
这三种排序都是耳熟能详的了,不需要分析了,随便一个数据结构书上都有。
发表于:2007-08-17 16:46:4622楼 得分:0
最后再贴一下listview所用的查找,很熟悉的二分查找。
int   winapi   dpa_search(hdpa   pdpa,   void   far*   pfind,   int   istart,
                        pfndpacompare   pfncompare,   lparam   lparam,   uint   options)
{
        int   cp   =   dpa_getptrcount(pdpa);

        assert(pfncompare);
        assert(0   <=   istart);

        //   only   allow   these   wierd   flags   if   the   list   is   sorted
        assert((options   &   dpas_sorted)   ¦ ¦   !(options   &   (dpas_insertbefore   ¦   dpas_insertafter)));

        if   (!(options   &   dpas_sorted))
        {
                //   not   sorted:   do   linear   search.
                int   i;

                for   (i   =   istart;   i   <   cp;   i++)
                {
                        if   (0   ==   pfncompare(pfind,   dpa_fastgetptr(pdpa,   i),   lparam))
                                return   i;
                }
                return   -1;
        }
        else
        {
                //   search   the   array   using   binary   search.     if   several   adjacent
                //   elements   match   the   target   element,   the   index   of   the   first
                //   matching   element   is   returned.

                int   iret   =   -1;             //   assume   no   match
                bool   bfound   =   false;
                int   ncmp   =   0;
                int   ilow   =   0;               //   don 't   bother   using   istart   for   binary   search
                int   imid   =   0;
                int   ihigh   =   cp   -   1;

                //   (ok   for   cp   ==   0)
                while   (ilow   <=   ihigh)
                {
                        imid   =   (ilow   +   ihigh)   /   2;

                        ncmp   =   pfncompare(pfind,   dpa_fastgetptr(pdpa,   imid),   lparam);

                        if   (0   >   ncmp)
                                ihigh   =   imid   -   1;               //   first   is   smaller
                        else   if   (0   <   ncmp)
                                ilow   =   imid   +   1;                 //   first   is   larger
                        else
                        {
                                //   match;   search   back   for   first   match
                                bfound   =   true;
                                while   (0   <   imid)
                                {
                                        if   (0   !=   pfncompare(pfind,   dpa_fastgetptr(pdpa,   imid-1),   lparam))
                                                break;
                                        else
                                                imid--;
                                }
                                break;
                        }
                }

                if   (bfound)
                {
                        assert(0   <=   imid);
                        iret   =   imid;
                }

                //   did   the   search   fail   and
                //   is   one   of   the   strange   search   flags   set?
                if   (!bfound   &&   (options   &   (dpas_insertafter   ¦   dpas_insertbefore)))
                {
                        //   yes;   return   the   index   where   the   target   should   be   inserted
                        //   if   not   found
                        if   (0   <   ncmp)               //   first   is   larger
                                iret   =   ilow;
                        else
                                iret   =   imid;
                        //   (we   don 't   distinguish   between   the   two   flags   anymore)
                }
                else   if   (   !(options   &   (dpas_insertafter   ¦   dpas_insertbefore))   )
                {
                        //   sanity   check   with   linear   search
                        assert(dpa_search(pdpa,   pfind,   istart,   pfncompare,   lparam,   options   &   ~dpas_sorted)   ==   iret);
                }
                return   iret;
        }
}
发表于:2007-08-17 16:47:5423楼 得分:0
以上代码出自windows   2000源代码,感谢老比的大力支持,感谢cctv,感谢……
发表于:2007-08-17 16:52:1024楼 得分:0
感谢codewarrior(会思考的草)…………
感谢csdn……
感谢。。。。。。

我就在想,如果没有这个源码的话,我们能否给老比还原出基本接近的算法呢?莫非源码泄露是有意为之?哈哈,瞎猜。
发表于:2007-08-17 16:53:3025楼 得分:0
排序算法就那么几种。我老比之所以用三种是为了适应不同的情况下的需要。这三种的性能都是差不多的。
发表于:2007-08-17 16:55:5126楼 得分:0
to:   codewarrior(会思考的草)

啥也不说了,牛就一个字!   :)
发表于:2007-08-17 17:02:5727楼 得分:0
排序算法就那么几种。我老比之所以用三种是为了适应不同的情况下的需要。这三种的性能都是差不多的。
===================================================

主要是想看看我们学的东西和成熟的产品采用的有什么差别!!!

ms不是天天都在捣腾什么新概念么?我就想看看他到底比“图灵”们先进到哪儿去了。真是遗憾,我以为能发现一点我们所不知道的。。。。。。。
发表于:2007-08-17 17:05:1428楼 得分:0
作为产品嘛,还是成熟,稳定最重要。何况一个简单的列表控件排序,用得着搞什么特别复杂的算法吗?log级别的足够了。新概念基本上都在微软研究院里面。
发表于:2007-08-17 17:06:0829楼 得分:0
去mra做做就知道新东西拉。牛人挺多的。
发表于:2007-08-17 17:14:2030楼 得分:0
所以啊,其它的我不知道。但从这个代码实现来讲,ms前年叫嚷的源码外泄风波,简直就是他起家时的盗版风波一个样了,只不过是这次有故意为之之嫌。

这辈子是去不了mra了,看来以后还得多多向codewarrior(会思考的草)兄学习才是!
发表于:2007-08-17 17:22:4231楼 得分:2
up!
发表于:2007-08-17 17:22:5632楼 得分:5
这个……泄漏代码和盗版还是有区别的吧?不过微软已经公开了2k3   server的kernel   source(仅限于kernel)。我也去不了mra,不是搞理论的。我们宿舍有俩哥们一个在ms一个在google,人家那是做图形算法和文本挖掘的……
发表于:2007-08-17 17:27:5633楼 得分:3
呵呵,大家七夕愉快哦
发表于:2007-08-17 17:46:4134楼 得分:7
作为产品嘛,还是成熟,稳定最重要。何况一个简单的列表控件排序,用得着搞什么特别复杂的算法吗?log级别的足够了。新概念基本上都在微软研究院里面。
-----------------------------------------------------------
无论上面哪种排序算法,都不可能达到o(logn)级别,事实上,不采取分段选择不同算法的策略,单一排序算法的话,极限时间级别也就o(nlogn),而且暂时没有算法能稳定的达到这个时间。
发表于:2007-08-17 17:54:5735楼 得分:2
学习,接分
发表于:2007-08-17 18:55:3536楼 得分:0
呵呵我当然知道是nlog2n,只不过简单起见写成了log级别。能达到nlogn的稳定排序算法是有的,我们系的朱洪老师发现的,叫做z算法,可能知道的比较少。
发表于:2007-08-17 19:05:1437楼 得分:0
merge   sort也是稳定的其实。
发表于:2007-08-18 08:32:5838楼 得分:3
顶上去..
发表于:2007-08-18 08:58:2039楼 得分:2
up
发表于:2007-08-18 09:12:0940楼 得分:2
mark
发表于:2007-08-18 10:41:1241楼 得分:2
mark   too!
发表于:2007-08-18 10:48:5142楼 得分:0
学习了
发表于:2007-08-18 12:21:0943楼 得分:7
我自己封装的个类,发给你哈.


csortlist::csortlist(cimageretrievalview*   pv)
{
m_basc=   true;
//this-> m_nsortedcol   =   -1;
createsorticons();
//getheaderctrl()-> setimagelist(&m_imglstsorticons);
pview   =   pv;
}

csortlist::~csortlist(void)
{
m_imglstsorticons.deleteimagelist();
m_bmpuparrow.deleteobject();
m_bmpdownarrow.deleteobject();
}

//implement_dyncreate(csercurityview,   cformview)
begin_message_map(csortlist,   clistctrl)
on_notify_reflect(lvn_columnclick,   onlvncolumnclick)
end_message_map()


/////////////////////////////////////////////////////////////////////////////
//   csortlist   message   handlers

void   csortlist::onlvncolumnclick(nmhdr   *pnmhdr,   lresult   *presult)
{
lpnmlistview   pnmlistview   =   reinterpret_cast <lpnmlistview> (pnmhdr);
//   todo:   add   your   control   notification   handler   code   here
//nm_listview*   pnmlistview   =   (nm_listview*)pnmhdr;
if(   pnmlistview-> isubitem   ==   m_nsortedcol   )
m_basc   =   !m_basc;
else
{
m_basc   =   false;
m_nsortedcol   =   pnmlistview-> isubitem;
}
sortitems(   listcompare,   (dword)this   );  
setsorticon();
for     (int   i=0;i <this-> getitemcount();i++)      
this-> setitemdata(i,       i);    
pview-> invalidate();
*presult   =   0;
}


void   csortlist::createsorticons()
{
if   (!m_imglstsorticons.m_himagelist)
{
colormap   cm   =   {rgb(0,   0,   0),   getsyscolor(color_graytext)};
m_imglstsorticons.create       (9,   5,   ilc_color24   ¦   ilc_mask,   2,   0);
m_bmpuparrow.loadmappedbitmap(idb_hdrup,   0,   &cm,   1);
m_nuparrow   =   m_imglstsorticons.add(&m_bmpuparrow,   rgb(255,   255,   255));
m_bmpdownarrow.loadmappedbitmap(idb_hdrdown,   0,   &cm,   1);
m_ndownarrow   =   m_imglstsorticons.add(&m_bmpdownarrow,   rgb(255,   255,   255));
}
}

void   csortlist::setsorticon()
{
cheaderctrl*   pheaderctrl   =   this-> getheaderctrl();
assert(pheaderctrl);

pheaderctrl-> setimagelist(&m_imglstsorticons);
for(   int   col   =   0;   col <   getheaderctrl()-> getitemcount();   col++   )
{
hditem   hdritem   =   {   0,};

hdritem.mask   =   hdi_format   ¦   hdi_image;

bool   ret   =   pheaderctrl-> getitem(col-1,   &hdritem);
ret   =   pheaderctrl-> getitem(col+1,   &hdritem);
ret   =   pheaderctrl-> getitem(col,   &hdritem);
if   (   m_nsortedcol   ==   col)
{
hdritem.fmt   =   hdritem.fmt   &   hdf_justifymask   ¦   hdf_image   ¦   hdf_string   ¦   hdf_bitmap_on_right;
if(   m_basc   )
hdritem.iimage   =   m_nuparrow;
else
hdritem.iimage   =   m_ndownarrow;
}
else
{
hdritem.fmt   =   hdritem.fmt   &   hdf_justifymask   ¦   hdf_string;
}
pheaderctrl-> setitem(col,   &hdritem);
}
}

bool   csortlist::getfullrowselect()
{
return   (   getextendedstyle()&lvs_ex_fullrowselect)   ==   lvs_ex_fullrowselect;
}

void   csortlist::setfullrowselect(   bool   bfullrowselect   )
{
if(   bfullrowselect   )
setextendedstyle(   getextendedstyle() ¦lvs_ex_fullrowselect   );
else
setextendedstyle(   getextendedstyle()&(~lvs_ex_fullrowselect)   );    
}

bool   csortlist::getgridlines()
{
return   (   getextendedstyle()   &   lvs_ex_gridlines   )   ==   lvs_ex_gridlines;
}

void   csortlist::setgridlines(   bool   bgridlines   )
{
if(   bgridlines   )
setextendedstyle(   getextendedstyle() ¦lvs_ex_gridlines   );
else
setextendedstyle(   getextendedstyle()&(~lvs_ex_gridlines)   );    
}

int   callback   csortlist::listcompare(lparam   lparam1,   lparam   lparam2,   lparam   lparamsort)
{
csortlist*   plist=(csortlist*)lparamsort;
int   nitem1,   nitem2;  

lvfindinfo   findinfo;  
findinfo.flags   =   lvfi_param;         //   指定查找方式
findinfo.lparam   =   lparam1;  
nitem1   =   plist-> finditem(&findinfo,   -1);   //   得到对应item索引
findinfo.lparam   =   lparam2;  
nitem2   =   plist-> finditem(&findinfo,   -1);  

if((nitem1   ==   -1)   ¦ ¦   (nitem2   ==   -1))  
{  
trace( "无法找到!\n ");  
return   0;  
}  

cstring   str1,str2;  
str1   =   plist-> getitemtext(nitem1,   plist-> m_nsortedcol);   //   得到排序列的text
str2   =   plist-> getitemtext(nitem2,   plist-> m_nsortedcol);  
int   icompres   =   0;
if(str1   >   str2)  
icompres   =   1;  
else   if(str1   ==   str2)  
icompres   =   0;  
else  
icompres   =   -1;

if(plist-> m_basc)
return   icompres;
else
return   icompres*-1;
return   0;
}

发表于:2007-08-18 17:50:3544楼 得分:1

有好的排序算法为什么还要用冒泡呢
发表于:2007-08-18 20:02:2845楼 得分:1
接分
发表于:2007-08-19 00:28:5846楼 得分:1
接分愉快..
发表于:2007-08-19 01:18:2447楼 得分:2
一般都用二分法。。。

.net平台上很多排序都是用二分法(参见msdn)
发表于:2007-08-19 11:20:1148楼 得分:4
有必要在用户界面层讲究排序性能么?数据量大的话我都是直接上数据库取排好了的数据
发表于:2007-08-19 14:21:2949楼 得分:0
有必要在用户界面层讲究排序性能么?数据量大的话我都是直接上数据库取排好了的数据
==========================================================================

这个也不尽然吧?况且我的初衷是想从ms的产品中借鉴一下一些先进的东西(比如这个帖子提到的算法)。这种基础性的东西,即使在数据库的排序中也会用到。

基础性的东西应该有自己的看法,至于用不用,什么场不是合用就是另一个话题了:)。
发表于:2007-08-19 15:17:5550楼 得分:2
mark.sorry.
发表于:2007-08-20 00:36:2851楼 得分:2
mark
发表于:2007-08-20 00:47:5252楼 得分:2
mark
发表于:2007-08-20 09:40:0453楼 得分:0
lz你要看先进的东西不应该看这里。微软不会拿一个小小的列表控件当新技术试验田,在这里想掏到什么前端科技是缘木求鱼了。数据库里的排序要复杂的多,而且也不是内排序。
发表于:2007-08-20 09:47:2954楼 得分:2
mark
发表于:2007-08-20 15:13:2855楼 得分:2
jf
good   luck!
发表于:2007-08-21 13:51:5356楼 得分:2
路过,学习
发表于:2007-08-21 14:12:0457楼 得分:2
学学学,接接接
发表于:2007-08-23 13:05:3858楼 得分:0
打烊了,谢谢各位光顾寒店。尤其是codewarrior(会思考的草)还带来了那么多美味。。。。

希望以后蔽人开的小店也能得到各位客倌的支持。
发表于:2007-08-23 13:14:5859楼 得分:0
mark
发表于:2007-08-23 13:33:3660楼 得分:0
jf
发表于:2007-08-26 10:44:3961楼 得分:0
好东西,学了好多
发表于:2007-10-26 10:01:1262楼 得分:0
学习