排序算法(2)
时间复杂度为O(N*logN)的三个算法,归并排序、快速排序、堆排序、希尔排序
归并排序:
将数组分为若干个步长为1的区间,把两个相邻的区间合并,成为一个步长为2的有序区间 ,然后把两个相邻的步长为2的区间合并,成为一个步长为4的有序区间,以此类推,直到最后所有都有序
新建一个数组,将需要合并的区间A、区间B从第一个开始比较,如果A中当前指向的数和B指向的比较,更小,在新建的数组放入A中指向的数,A中的指针向前移一位,数组中指针向前移一位。若B中指向的数小,同理。直到A或B的全部数都放进新建数组中,将另一个数组剩下的值接在后面。新数组为合并后的新的有序区间。递归调用分解方法,分解后调用合并方法。
快速排序:
将数组最左、中间、最右的数大小排序,最小的放在最左,第二大的放在中间,最大的放在最右
将中间的数放在数组倒数第二个位置,以这个数作为标准排序。设置指针i、j,判断 i 指向的数是否比倒数第二个数大,不是则 i 向右移动一位 ,直到找到比倒数第二个数大或者 i == j 时;i 停下后,判断 j 指向的数是否比倒数第二个数小,如果是则和 i 指向的数交换,否则向左移动一位继续寻找,找到则交换。i 最终停下的位置和倒数第二个数交换。此时数组分为比排序标准的数小和比排序标准数大两部分。在这两部分中再分别进行刚才的快速排序。
堆排序:
大顶堆 的定义:array[ i ] >= array[2i + 1] && array[ i ] >= array[2i +2]
先将传入的长度为 n 的数组整理成一个大顶堆,将堆顶的元素即array[ 0 ] 和 array[ n - 1 ]上的数交换,移出堆;调整长度为 n -1 的大顶堆(在第一次已经整理好的基础上,只需要将位置0上的数找到合适的位置放好即可,不需要整理所有数的位置),然后再次将堆顶和队尾元素互换。直到堆的长度为 1 时,数组整理完毕。
整理出大顶堆的过程:从最后一个非叶子节点(位置在array.length/2 -1)开始,从右到左,从下到上调整节点位置(节点、节点的左孩子和右孩子三个数进行比较,最大的和节点进行交换)。