快排算法的非递归实现

怎甘沉沦 提交于 2020-01-28 02:26:10

我的Partition(),功能是以传入的finish序号的数的数值为分界线,把数组分成两部分,前半的数值都比他小,其余的都比那个值大,并返回分界的序号。这个过程中就操作数组换位,具体见算法注释。

而sort函数的工作就是反复的利用Partition函数查找那个中间值,在这个过程中就对数组进行操作,将其分成两段。把一个大的数列改为一个个小的,甚至长度为一的序列,当达到这个条件时,实际上已经排好序了。

这一点上和递归函数没区别,因为算法一样。建议按序看我的注释,并且自己举个数列的例子来操作。可以先看Partition()的,因为两个函数是独立的。


可以,我就写写算法了。因为这个代码是算法代码而其年久失修,你自己人工序列试试就知道了。关键在后面的交换顺序并找到分界点的地方
Sort()
{
stack  s;//构造栈
start =arr;//arr为要排序的序列
finish = m_arr + m_len - 1;
pivot = Partition(start, finish);//找到一个位置,使其前面的比他小,后面的比他大
s.push(pivot+1); // 后半段首尾存储仅存储序列号
s.push(finish);

s.push(start); // 前半段首尾存储仅存储序列号
s.push(pivot-1);
while (!s.empty())//s为空时说明所有的分组start=finish,都是单元素数组已经结束
{
  finish =s.pop();//取出一对首尾值,作为新的数组来排序
  start = s.pop();

  if (start < finish)
  {
   pivot = Partition(start, finish); //同上循环处理
   s.push(pivot+1); // 后半段
   s.push(finish);
   s.push(start); // 前半段
   s.push(pivot-1);
  }
}  //每次的if判断成功都会把一个长数组改成短的两个并存入栈中
}//所以最终会变成全为长度一的数组
////////////////////////////////////////////////////////////////
Partition(start,finish)//传入数组的第一个和最后一个的序号start,finish
{
pivot = finish;//以最后一个为分水岭
elem = *pivot;//取最后一个的值

while (start < finish)
{
  // 从最左端开始,看start的值和分界值elem的大小关系
   while (*start < elem)
  { // 该循环退出的条件是*start >= elem, 此时start序号要么等于finish,要么小于finish,而Start扫过的序号的数值都确定比elem小。
   start++;
  }  
//此时 *start>=elem,而start-1所指向的元素(*(start-1))要小于elem

while (start < finish && *finish >= elem)
{//这和前者正好是逆向的从最后一个开始找比elem小的值,之后再finish之后的数值都大于elem
  finish--;
}
//这时的情况 *finish < elem 
//而Start和finish有两种关系,start=finish或者start<finish
if (start < finish)
{
// 交换start和finish所指向的元素,交换后 *start<elem, *finish >=elem
  temp = *finish;
  *finish = *start;
  *start = temp;//然后重复while循环,直到start=finish
}
else
{
// start=finish时,共同指向的值属于后一个集合,即比elem大
*pivot = *start;//把这个值放到最后
  *start = elem;//共同指向的位置赋值分水岭值
  pivot = start;//分水岭序号
  break;
  }
}
return pivot;//返回分水岭序号
}
//这样一来,就得出了一个以分水岭为界的,两组数列,一边比他大,一边比他小

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!