2022年 11月 16日

算法—快排(python)

快排应该算是比较有趣的一种排序算法了。

#Ps:反正我觉的蛮有趣的

        话不多说,还是先上代码:

  1. # 升序
  2. def quitSort(arr,left,right):
  3. if left >= right:
  4. return arr
  5. init_left = left
  6. init_right = right
  7. key = arr[left]
  8. while left < right:
  9. while left < right and arr[right] >= key:
  10. right -= 1
  11. arr[left] = arr[right]
  12. while left < right and arr[left] <= key:
  13. left += 1
  14. arr[right] = arr[left]
  15. arr[left]=key
  16. quitSort(arr,init_left,left-1)
  17. quitSort(arr,left+1,init_right)
  18. return arr
  19. # 降序
  20. def quitSort(arr,left,right):
  21. if left >= right:
  22. return arr
  23. init_left = left
  24. init_right = right
  25. key = arr[right]
  26. while left < right:
  27. while left < right and arr[left]>=key:
  28. left+=1
  29. arr[right]=arr[left]
  30. while left < right and arr[right]<=key:
  31. right -= 1
  32. arr[left] = arr[right]
  33. arr[right] = key
  34. quitSort(arr,init_left,left-1)
  35. quitSort(arr,right+1,init_right)
  36. return arr

e,先放上菜鸟教程的快排gif:

 快排的原理就在于 设定一个中间值 ,在我的代码中,key 就是中间值(下面都用 key 来代替中间值)

快排过程:

  • 快排的本质就是 分而治之 ,也就是说以 key 为准,对两边的数据进行一个整理,比如:大于 key 的值往 key 的右边扔,小于 key 的往左边挪,至于等于 key 的值往左往右都行。(如上图)
  • 接着我们确定一个 key ,一般是数组最左或最右边的值(这里我们设置为最左边的值,也就是 key = arr[ left ] )
  • 既然 key 是最左边的值,那么我们要先判断右边(以升序为例):
    • 右边的指针(right)一开始指向最右边( len(arr-1) ),只要指针指向的值大于 key ,指针就向左挪一个位置(因为要让 key 左边的值都比 key 大),这样,我们就能找到第一个 小于 key 的值,并将值赋给 left 指向的位置,如下图与下下图。

  #Ps:这是原始数组: left 指向 5 ,right 指向 4

 #Ps:这是左边第一次循环结束后的数组: left 指向 4 ,right 指向 4

  •  同时,由于我们在函数开始就存储了 arr[left] 的值,也就是 key ,所以我们并不用担心会出现数据丢失的情况。
  • 因为左边第一次循环已经结束了,接下来就是右边的第一次循环,第一次判断:4 < 5( arr[left]<key ),满足条件,left 指针向右挪一位 指向8,8> key ,将 8 赋值给 right 指向的位置

 #Ps:left 指向 8(第二位) ,right 指向 8(最后一位)

  •  第二轮大循环开始:
    • 还是右边先判断:8 > key ,满足条件,right 指针往左走一格 指向 3 ,3<key ,将3 赋值给 left 指向的位置

 #Ps:left 指向 3 (第二位),right 指向 3(倒数第二位)

  •  左边开始判断:一直到 6 停下来,left 指向 6,将 6 赋值给 right 指向的位置

 #Ps:left 指向 6 (第五位),right 指向 6(第六位)

  •  第三轮大循环开始:
    • arr[ right] >key ,right 指针向左走,此时 left ,right 指向同一个位置,大循环结束。将 key 赋值给 left 和 right 指向的位置

 #Ps:left 指向 5 ,right 指向 5

  •  接着,我们以 key 为节点 分为 key 的左边 和 key 的右边 再进行以上的步骤。

最后附上 每一轮大循环结束后的数组 arr :

        


本文到此结束,手动分割线。