3-5 回顾,快速二分法的疑点解惑:为啥先右j移动?因为设定a[left]为基准点

Posted Mr-chen

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了3-5 回顾,快速二分法的疑点解惑:为啥先右j移动?因为设定a[left]为基准点相关的知识,希望对你有一定的参考价值。

快速二分法的疑点解惑:为啥先右j移动?因为设定a[left]为基准数

思路:(查看了网上的2篇文章,关键点就是谁为基准数,我自己又尝试了不同排序,不同基准数left,right。得出??的结论)

步骤:

1. 在序列中设a[left]为基准数。最左边设i,最右边设j(目标是从大到小排列)

2. 先从右往左找大于基准数的数,再从左往右找小于基准数的数,找到后两数交换位置

3. 然后重复2和3步骤。直到i和j最终相遇,结束本次循环。 

4. 把基准数和最终相遇的数交换,结束。此步骤定位了一个数。

5. 原基准数左边和右边的序列再分别重复1-4的步骤。继续定位新的基准数。直到全部数字定位结束。

 

      第2步,先右移动,是因为基准点设为a[left]。如果先左边i移动的话得到的a[i]必然比a[left]小。

     在第4步交换a[i]和a[left]的时候导致了基准点a[left]右边竟然有比它小的数字。不符合每次循环定位1个基准点的原则,从大到小排序就失败了。(当然如果是从小往大排序也一样,会导致类似的问题出现。)

      所以如果基准点定位到最左边的话,j就要先移动。当然基准点定位到最右边的话,i就先移动了。

def quicksort(a,left,right)
  if left > right                # 设定何时停止该方法的调用。
    return
  end

 

  temp = a[left]              #设定最左边的为基准数
  i = left
  j= right
  while i != j                   # i和j从两边向中间靠拢,直到i和j重合,结束本轮循环。

    #  根据是升序还是降序来选择 比较运算符号。

    while a[j] <= temp && i < j  #根据基准点是a[left],要先从右往左找。
      j -= 1
    end
    while a[i] >= temp && i < j  #再从左向右找,这里找小于基准数的数。
      i += 1
    end
    if i < j                    #当i 和 j 没有相遇的时候,交换数据
      t = a[i]
      a[i] = a[j]
      a[j] = t
    end
  end
  a[left] = a[i]              #将基准数归位。
  a[i] = temp

  print a.to_s + "\n"      #打印每次交换的结果

  quicksort(a,left,i-1)       # 在quciksort的方法中,再次调用本方法,形成递归的过程。这个是处理i左边。                                       # 直到穷尽,即当left>right时停止调用该方法。
  quicksort(a,i+1,right)    # 这个处理i右边
end

 

a =  [7, 68, 42, 46, 9, 91, 77, 46, 86, 1]
quicksort(a,0,9)
# 0和9 代表数组最左边和最右边的key 
print a

 

结果:

[86, 68, 42, 46, 9, 91, 77, 46, 7, 1]
[91, 86, 42, 46, 9, 68, 77, 46, 7, 1]
[91, 86, 42, 46, 9, 68, 77, 46, 7, 1]
[91, 86, 77, 46, 46, 68, 42, 9, 7, 1]
[91, 86, 77, 46, 46, 68, 42, 9, 7, 1]
[91, 86, 77, 68, 46, 46, 42, 9, 7, 1]
[91, 86, 77, 68, 46, 46, 42, 9, 7, 1]
[91, 86, 77, 68, 46, 46, 42, 9, 7, 1]
[91, 86, 77, 68, 46, 46, 42, 9, 7, 1]
[91, 86, 77, 68, 46, 46, 42, 9, 7, 1]
[91, 86, 77, 68, 46, 46, 42, 9, 7, 1] #最终结果

 

以上是关于3-5 回顾,快速二分法的疑点解惑:为啥先右j移动?因为设定a[left]为基准点的主要内容,如果未能解决你的问题,请参考以下文章

HBase之disable+drop删除表疑点解惑

HBase之disable+drop删除表疑点解惑

快速排序函数及二分法匹配

Java中的几种排序算法:冒泡排序,插入排序,二分法排序,简单排序,快速排序

python MultiProcessing模块进程间通信的解惑与回顾

各种排序方法(冒泡,快速,插入,选择),二分查找