排序算法总结:
快速排序的思想是分治法,即分而治之。
快排算法的思想非常简单,在待排序的数列中,我们首先要找一个数字作为基准数。为了方便,我们一般选择第 1 个数字作为基准数。接下来我们需要把这个待排序的数列中小于基准数的元素移动到待排序的数列的左边,把大于基准数的元素移动到待排序的数列的右边。这时,左右两个分区的元素就相对有序了;接着把两个分区的元素分别按照上面两种方法继续对每个分区找出基准数,然后移动,直到各个分区只有一个数时为止。
快速排序的操作是这样的:首先从数列的右边开始往左边找,我们设这个下标为 j,也就是进行减减操作(j–),找到第 1 个比基准数小的值,把它的值赋给i;接着从左边开始往右边找,下标为 i,然后执行加加操作(i++),找到第 1 个比基准数大的值,把他赋给j;然后继续寻找,直到 i 与 j 相遇时结束,最后基准值所在的位置即 k 的位置,也就是说 k 左边的值均比 k 上的值小,而 k 右边的值都比 k 上的值大。
数组:[8,20,9,1,34,27,1,10]快排如下:第一次,索引为0的8是基准书,这一趟的任务是把比8小的数移到8的左边,比8大的数移到8的右边。
具体实现的方式并不是直接移动数字到8的左边,因为8是最开头的数字呀,它前面的索引为负。i指向数组第一个元素8,j指向最后一个数字10,要保证j指向的数字比8大,而i指向的数字比8小。10是满足的,因此j–来到1,1比8小,所以这里要操作。记住,是i指向的数比基准书8小,j指向的数比基准数8大,这是核心条件。现在,j指向1了,1比8小,比8小的数应该谁指?操作权给到i,直接送给i,这里执行操作arr[i] = arr[j],数组变成:[1,20,9,1,34,27,1,10]。i++后移一位。
i掌握了操作权,本应继续走下去,但是刚走到20这里就碰壁了,20比8大,比8大的数应该j指向呀!好了,操作权给到j,arr[j] = arr[i],j–来到27.
一直进行到这个操作,一直到i和j相遇
箭头逐渐画残。。。
i和j终于相遇了,他们相遇的这个地方很有纪念意义,这个9就是中枢数,它代表9之前的数字比基准书8小,而9之后的数字比基准数8大,已经介绍到这里了,感觉不操作一下不太人性啊,是和你8比较的,为啥把我9放到这里,这是只需要把中枢数改成基准书8就好了
不知道大家看到这里有没有发现哦,之前带下标的1是排在后面的,经过这一趟,跑到前面了,也就是说,快排是不稳定的,不稳定发生在i和j指向的数相互赋值的时候。
这只是一趟,快排是分治法,8之前的数组和8之后的数组还要继续执行相同的操作,其基准书分别为1和9,用递归算法实现,直到待排数组长度只有1.
python实现:
def qsort(arr, begin, end):
if end<=begin:
return
base = arr[begin]
i, j = begin, end
while i < j:
while arr[j]>=base and i<j:
j -= 1
if i<j:
arr[i] = arr[j]
i += 1
while arr[i]<=base and i<j:
i += 1
if i<j:
arr[j] = arr[i]
j -= 1
arr[i] = base # 中枢元素
qsort(arr, begin, i-1)
qsort(arr, i+1, end)