快速排序的非递归算法

 
求取快速排序的非递归算法(最好能给出C/C++的源代码)
如题。  
  对我们自学者来说,算法设计与分析真的好难! <script language="javascript" src="/js/googlehead.js" type="text/javascript"></script> <script type="text/javascript"> </script> <script src="http://pagead2.googlesyndication.com/pagead/show_ads.js" type="text/javascript"> </script>

1 楼
如果死记,当然不容易

2 楼
设栈模拟即可.

3 楼
最好能给出源代码,以利于与自己的思路进行核对,取长补短。

4 楼
void   QuickSortWithStack(   int*   pSrcArray,   int   iStart,   int   iEnd)  
  {  
  int*   pStackArray   =   new   int[80];  
  int   iLastPosition   =   0;  
  pStackArray[iLastPosition]   =   iStart;  
  pStackArray[iLastPosition   +   1]   =   iEnd;  
  iLastPosition   +=   2;  
   
  int   iMaxStackSize   =   0;  
  while   (iLastPosition   !=   0)  
  {  
  int   iEndParation   =   pStackArray[iLastPosition   -   1];  
  int   iStartParation   =   pStackArray[iLastPosition   -   2];  
  iLastPosition   -=   2;  
   
                                    //   下面用于小文件优化处理,在执行完该函数后,再调用插入排序,能提高性能  
  if   (   iEndParation   <=   iStartParation   +   32)  
  {  
  continue;  
  }  
   
  int   iBegin   =   iStartParation   -   1;  
  int   iLast   =   iEndParation;  
  int   iParationValue   =   pSrcArray[   iEndParation];  
   
  //   Paration   one   value  
  while   (1)  
  {  
  while   (pSrcArray[   ++iBegin]   <   iParationValue);  
  while   ((pSrcArray[   --iLast]   >=   iParationValue))   if   (iLast   ==   iStartParation)   break;  
   
  if   (iLast   <=   iBegin)  
  {  
  break;  
  }  
  else  
  {  
  Exchange(pSrcArray,   iBegin,   iLast);  
  }  
  }  
   
  Exchange(pSrcArray,   iBegin,   iEndParation);  
   
  if   (iBegin   >=   (iStartParation   +   iEndParation)   /   2)  
  {  
  pStackArray[iLastPosition]   =   iStartParation;  
  pStackArray[iLastPosition   +   1]   =   iBegin   -   1;  
  pStackArray[iLastPosition   +   2]   =   iBegin   +   1;  
  pStackArray[iLastPosition   +   3]   =   iEndParation;  
  }  
  else  
  {  
  pStackArray[iLastPosition]   =   iBegin   +   1;  
  pStackArray[iLastPosition   +   1]   =   iEndParation;  
  pStackArray[iLastPosition   +   2]   =   iStartParation;  
  pStackArray[iLastPosition   +   3]   =   iBegin   -   1;  
  }  
  iLastPosition   +=   4;  
  }  
   
  delete[]   pStackArray;  
 

5 楼
上面的可排序的最大元素的个数为2^40

6 楼
使用栈的话效率应该和递归是几乎一样的吧?不用栈有没可能?

7 楼
void   QSort(int   arr[],   int   low,   int   high)  
  {  
  int   pivot,   lHold,   rHold,   pivotPos;  
   
  lHold   =   low;  
  rHold   =   high;  
  pivot   =   arr[low];  
  pivotPos   =   low;  
   
  while   (low   <   high)  
  {  
  while   ((low   <   high)   &&   (arr[high]   >=   pivot))  
  --high;  
  if   (low   !=   high)  
  {  
  arr[low]   =   arr[high];  
  ++low;  
  }  
   
  while   ((low   <   high)   &&   (arr[low]   <=   pivot))  
  ++low;  
  if   (low   !=   high)  
  {  
  arr[high]   =   arr[low];  
  --high;  
  }  
  }  
   
  arr[low]   =   pivot;  
  pivotPos   =   low;  
  low   =   lHold;  
  high   =   rHold;  
   
  if   (low   <   pivotPos)  
  QSort(arr,   low,   pivotPos-1);  
  if   (high   >   pivotPos)  
  QSort(arr,   pivotPos+1,   high);  
  }  
   
  void   QuickSort(int   arr[],   int   array_size)  
  {  
  QSort(arr,   0,   array_size-1);  
  }

8 楼
我看的几个   CRT   函数里的   qsort   都木有用递归,   比如   M$   的:  
   
  void   __cdecl   qsort   (  
          void   *base,  
          unsigned   num,  
          unsigned   width,  
          int   (__cdecl   *comp)(const   void   *,   const   void   *)  
          )  
  {  
          char   *lo,   *hi;                             /*   ends   of   sub-array   currently   sorting   */  
          char   *mid;                                     /*   points   to   middle   of   subarray   */  
          char   *loguy,   *higuy;                 /*   traveling   pointers   for   partition   step   */  
          unsigned   size;                             /*   size   of   the   sub-array   */  
          char   *lostk[30],   *histk[30];  
          int   stkptr;                                   /*   stack   for   saving   sub-array   to   be   processed   */  
   
          /*   Note:   the   number   of   stack   entries   required   is   no   more   than  
                1   +   log2(size),   so   30   is   sufficient   for   any   array   */  
   
          if   (num   <   2   ||   width   ==   0)  
                  return;                                   /*   nothing   to   do   */  
   
          stkptr   =   0;                                   /*   initialize   stack   */  
   
          lo   =   base;  
          hi   =   (char   *)base   +   width   *   (num-1);                 /*   initialize   limits   */  
   
          /*   this   entry   point   is   for   pseudo-recursion   calling:   setting  
                lo   and   hi   and   jumping   to   here   is   like   recursion,   but   stkptr   is  
                prserved,   locals   aren't,   so   we   preserve   stuff   on   the   stack   */  
  recurse:  
   
          size   =   (hi   -   lo)   /   width   +   1;                 /*   number   of   el's   to   sort   */  
   
          /*   below   a   certain   size,   it   is   faster   to   use   a   O(n^2)   sorting   method   */  
          if   (size   <=   CUTOFF)   {  
                    shortsort(lo,   hi,   width,   comp);  
          }  
          else   {  
                  /*   First   we   pick   a   partititioning   element.     The   efficiency   of   the  
                        algorithm   demands   that   we   find   one   that   is   approximately   the  
                        median   of   the   values,   but   also   that   we   select   one   fast.     Using  
                        the   first   one   produces   bad   performace   if   the   array   is   already  
                        sorted,   so   we   use   the   middle   one,   which   would   require   a   very  
                        wierdly   arranged   array   for   worst   case   performance.     Testing   shows  
                        that   a   median-of-three   algorithm   does   not,   in   general,   increase  
                        performance.   */  
   
                  mid   =   lo   +   (size   /   2)   *   width;             /*   find   middle   element   */  
                  swap(mid,   lo,   width);                               /*   swap   it   to   beginning   of   array   */  
   
                  /*   We   now   wish   to   partition   the   array   into   three   pieces,   one  
                        consisiting   of   elements   <=   partition   element,   one   of   elements  
                        equal   to   the   parition   element,   and   one   of   element   >=   to   it.     This  
                        is   done   below;   comments   indicate   conditions   established   at   every  
                        step.   */  
   
                  loguy   =   lo;  
                  higuy   =   hi   +   width;  
   
                  /*   Note   that   higuy   decreases   and   loguy   increases   on   every   iteration,  
                        so   loop   must   terminate.   */  
                  for   (;;)   {  
                          /*   lo   <=   loguy   <   hi,   lo   <   higuy   <=   hi   +   1,  
                                A[i]   <=   A[lo]   for   lo   <=   i   <=   loguy,  
                                A[i]   >=   A[lo]   for   higuy   <=   i   <=   hi   */  
   
                          do     {  
                                  loguy   +=   width;  
                          }   while   (loguy   <=   hi   &&   comp(loguy,   lo)   <=   0);  
   
                          /*   lo   <   loguy   <=   hi+1,   A[i]   <=   A[lo]   for   lo   <=   i   <   loguy,  
                                either   loguy   >   hi   or   A[loguy]   >   A[lo]   */  
   
                          do     {  
                                  higuy   -=   width;  
                          }   while   (higuy   >   lo   &&   comp(higuy,   lo)   >=   0);  
   
                          /*   lo-1   <=   higuy   <=   hi,   A[i]   >=   A[lo]   for   higuy   <   i   <=   hi,  
                                either   higuy   <=   lo   or   A[higuy]   <   A[lo]   */  
   
                          if   (higuy   <   loguy)  
                                  break;  
   
                          /*   if   loguy   >   hi   or   higuy   <=   lo,   then   we   would   have   exited,   so  
                                A[loguy]   >   A[lo],   A[higuy]   <   A[lo],  
                                loguy   <   hi,   highy   >   lo   */  
   
                          swap(loguy,   higuy,   width);  
   
                          /*   A[loguy]   <   A[lo],   A[higuy]   >   A[lo];   so   condition   at   top  
                                of   loop   is   re-established   */  
                  }  
   
                  /*           A[i]   >=   A[lo]   for   higuy   <   i   <=   hi,  
                                A[i]   <=   A[lo]   for   lo   <=   i   <   loguy,  
                                higuy   <   loguy,   lo   <=   higuy   <=   hi  
                        implying:  
                                A[i]   >=   A[lo]   for   loguy   <=   i   <=   hi,  
                                A[i]   <=   A[lo]   for   lo   <=   i   <=   higuy,  
                                A[i]   =   A[lo]   for   higuy   <   i   <   loguy   */  
   
                  swap(lo,   higuy,   width);           /*   put   partition   element   in   place   */  
   
                  /*   OK,   now   we   have   the   following:  
                              A[i]   >=   A[higuy]   for   loguy   <=   i   <=   hi,  
                              A[i]   <=   A[higuy]   for   lo   <=   i   <   higuy  
                              A[i]   =   A[lo]   for   higuy   <=   i   <   loguy         */  
   
                  /*   We've   finished   the   partition,   now   we   want   to   sort   the   subarrays  
                        [lo,   higuy-1]   and   [loguy,   hi].  
                        We   do   the   smaller   one   first   to   minimize   stack   usage.  
                        We   only   sort   arrays   of   length   2   or   more.*/  
   
                  if   (   higuy   -   1   -   lo   >=   hi   -   loguy   )   {  
                          if   (lo   +   width   <   higuy)   {  
                                  lostk[stkptr]   =   lo;  
                                  histk[stkptr]   =   higuy   -   width;  
                                  ++stkptr;  
                          }                                                       /*   save   big   recursion   for   later   */  
   
                          if   (loguy   <   hi)   {  
                                  lo   =   loguy;  
                                  goto   recurse;                       /*   do   small   recursion   */  
                          }  
                  }  
                  else   {  
                          if   (loguy   <   hi)   {  
                                  lostk[stkptr]   =   loguy;  
                                  histk[stkptr]   =   hi;  
                                  ++stkptr;                               /*   save   big   recursion   for   later   */  
                          }  
   
                          if   (lo   +   width   <   higuy)   {  
                                  hi   =   higuy   -   width;  
                                  goto   recurse;                       /*   do   small   recursion   */  
                          }  
                  }  
          }  
   
          /*   We   have   sorted   the   array,   except   for   any   pending   sorts   on   the   stack.  
                Check   if   there   are   any,   and   do   them.   */  
   
          --stkptr;  
          if   (stkptr   >=   0)   {  
                  lo   =   lostk[stkptr];  
                  hi   =   histk[stkptr];  
                  goto   recurse;                       /*   pop   subarray   from   stack   */  
          }  
          else  
                  return;                                   /*   all   subarrays   done   */  
  }
 
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值