Java 排序算法
冒泡排序
比较相邻的元素。
如果第一个比第二个大,就交换他们两个。
对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。
这步做完后,最后的元素会是最大的数。
编码思路:要两层循环,第一层循环i表示排序的轮数,第二层循环j表示比较的次数。
选择排序
选择排序是一种简单直观的排序算法,所以用到它的时候,数据规模越小越好。唯一的好处可能就是不占用额外的内存空间。
首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置。
再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。
重复第二步,直到所有元素均排序完毕。
插入排序
- 以数组的某一位作为分隔位,比如
index = 1
,假设左面的都是有序的。 - 将index位的数据拿出来,放到临时变量里,这时index位置就空出来了。
- 从
leftindex = index - 1
开始将左面的数据与当前index
位的数据(即temp
)进行比较,如array[leftindex]>temp
,
将array[leftindex]
后移一位,即array[leftindex + 1] = array[leftindex]
,此时leftindex
就空出来了。 - 再用
index-2
(即leftindex = leftindex -1
)位的数据和temp
比,
重复步骤 3,直到找到<= temp
的数据或者比到了最左面(说明temp
最小),停止比较,将temp
放在当前空的位置上。 index
向后挪1
,即index = index + 1
,temp = array[index]
,重复步骤 2-4,直到index = array.length
,排序结束,
此时数组中的数据即为从小到大的顺序.
希尔排序
希尔排序(Shell Sort)是插入排序的一种,它是针对直接插入排序算法的改进。
希尔排序又称缩小增量排序,因 DL.Shell 于 1959 年提出而得名。
它通过比较相距一定间隔的元素来进行,各趟比较所用的距离随着算法的进行而减小,直到只比较相邻元素的最后一趟排序为止。
归并排序希尔排序时间复杂度是 O(n^(1.3-2)),空间复杂度为常数阶 O(1)。希尔排序没有时间复杂度为 O(n(logn)) 的快速排序算法快 ,因此对中等大小规模表现良好,但对规模非常大的数据排序不是最优选择,总之比一般 O(n^2 ) 复杂度的算法快得多。
快速排序
归并排序(Merge sort)是建立在归并操作上的一种有效、稳定的排序算法,该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为二路归并。
当有 n 个记录时,需进行 logn 轮归并排序,每一轮归并,其比较次数不超过 n,元素移动次数都是 n,因此,归并排序的时间复杂度为 O(nlogn)。归并排序时需要和待排序记录个数相等的存储空间,所以空间复杂度为 O(n)。
归并排序适用于数据量大,并且对稳定性有要求的场景。
堆排序
堆(Heap)是计算机科学中一类特殊的数据结构的统称。
堆通常是一个可以被看做一棵完全二叉树的数组对象
堆满足下列性质:堆中某个节点的值总是不大于或不小于其父节点的值。堆总是一棵完全二叉树。
堆是利用完全二叉树的结构来维护一组数据,然后进行相关操作,一般的操作进行一次的时间复杂度在 O(1)~O(logn) 之间,堆通常用于动态分配和释放程序所使用的对象。
若为优先队列的使用场景,普通数组或者顺序数组,最差情况为 O(n^2),堆这种数据结构也可以提高入队和出队的效率。
Java 排序算法中数据对象都可以为数组,部分数据对象可以为链表。