排序算法

来源:互联网 发布:java图书借阅管理系统 编辑:程序博客网 时间:2024/06/05 06:30
递归都可以用栈或队列解决,因为递归就是利用函数栈来解决问题的。
队列同栈一样都是一种遍历方式,栈是深度优先遍历,队列是广度优先遍历。

归并排序
=>
原理:将整个序列不断地一分为二(总共可以分log(n)次),直到子序列只有一个元素,开始按照从小到1大的顺序归并两个子序列,
归并的结果就是形成了一个新的大一点的有序的子序列,这样逐层向上归并,最终将两个最大的子序列归并完成,整个排序工作也就
完成了,每2个子序列归并完成的工作就是按照从小到大顺序,把它们的元素复制到一个新的存储地方,所以,每一层归并完成的工作
实际上就是将n个元素复制一遍。

时间复杂度主要就消耗在merge上,因此时间复杂度计算公式:
每层复制元素个数 * 层数 = n * log(n) => O(nlog(n))

插入排序
=> 从第2个元素开始,到它之前的子序列中,找到自己的位置(通过向后移动比自己大的元素空出这个位置),最后一个元素也找到位置时,整个序列有序了。
原理:从第2个元素开始,直到第n-1个元素,循环同它前面的元素比较并找到插入位置。我们用i来表示当前在处理元素,如果第i-1个
元素比i小,那么i就不进行其他操作,如果第i-1个元素比i大,则要在(0, i-1)范围内找到i的合适位置(可以用二分查找),目的就是将i插入到那。
例如在(0, i-1)中找到其中的m,第m个元素比i小,而第m+1个元素就比i大,则将(m+1, i-1)以此向后移动一个位置,i-1占用i原来的
位置,而将i复制到m+1这个位置去,这样,前i个元素排好序了。

时间复杂度主要消耗在移动i之前的元素上,加入整个序列是倒序的(最差情况),则时间复杂度计算公式:
移动次数之和 = 1 + 2 + ... + n-1 = n(n-1) / 2 => O(n*n)

快速排序
=> 通过多次交换为1个元素找到自己的位置,使自己前面的元素比自己小,自己后面的元素比自己大,当所有元素都找到位置时,则整个序列就有序了。
原理:选定一个元素,通过不停地同其他元素交换位置或其他元素之间交换位置,最终达到这个元素所处位置之前的元素都比它小,这个元素所处位置之后的元素都比它大。这样在它又前后形成两个子序列,递归在两个子序列中执行同样操作,同归并排序一样递归log(n)层,这样最终所有选素都找到自己的位置,使自己前面的元素比自己小,自己后面的元素比自己大,则整个序列就有序了。

操作过程:
如果选定中间位置的元素,则从前后两个方向向中间(i=0,j=Length; i++,j--;)推进:
1).如果从前面向中间走遇到比31大的元素,从后面向31走遇到比31小的元素,就将它们俩交换位置;
2).如果只有一个方向找到比31大或小的元素,就把这个元素同31交换.
达到31之前的元素比它小,31后的元素比它大的目的。


但是如果选定第一个元素,则是固定把31同其他元素多次交换,
j--过程中找到比31小的元素同31交换;
i++过程中找到比31大的元素同31交换。
例:
“31” 435 42 54 23 53 7 2341 532 62

7 435 42 54 23 53 “31“ 2341 532 62

7 “31” 42 54 23 53 435 2341 532 62

7 23 42 54 “31” 53 435 2341 532 62

7 23 “31” 54 42 53 435 2341 532 62
达到31之前的元素比它小,31之后的元素比它大的目的了。