先来看看各种排序方式的区别
直接贴下代码
package com.panda.sort.bubble;
public class BubbleSort {
/**
* 冒泡排序
* @param args
*/
static void exchange(int[] array,int a,int b){
int c =array[a];
array[a] = array[b];
array[b] = c;
}
public static void main(String[] args) {
int[] array = new int[]{10,14,15,32,65,25,11,2,5,9,19,27};
for(int i = 0;i<array.length-1;i++){
for(int j=i+1;j<array.length;j++){
if(array[i] > array[j]){
BubbleSort.exchange(array,i,j);
}
}
}
for(int i=0;i<array.length;i++){
System.out.print(array[i]+",");
}
}
}
class DirectBubble{
/**
* 冒泡排序升级版,定向冒泡排序,也叫鸡尾酒排序
* @param args
*/
public static void main(String[] args) {
int[] array = new int[]{10,14,15,32,65,25,11,2,5,9,19,27};
int left = 0;
int right = array.length-1;
while(left < right){
for(int i = left;i<right;i++){
if(array[i]>array[i+1]){
BubbleSort.exchange(array, i, i+1);
}
}
right--;
for(int i = right;i>left;i--){
if(array[i-1]>array[i]){
BubbleSort.exchange(array, i-1, i);
}
}
left++;
}
for(int i=0;i<array.length;i++){
System.out.print(array[i]+",");
}
}
}
package com.sort;
/**
* 时间复杂度:O(n^2)
* 空间复杂度:O(1)
* 最少比较次数:(已排序的数组)n-1次
* 最多比较次数:(降序的数组)n(n-1)/2次
* 赋值操作次数:比较次数-(n-1)
* 插入排序不适合对大量数据排序,适合对接近排序的数据排序。
* 插入排序是稳定排序。
* @author Administrator
*
*/
public class InsertSort {
public static void main(String[] args) {
int[] array = new int[]{10,14,15,32,65,25,11,2,5,9,19,27};
for(int i = 1;i<array.length;i++){
int a = array[i];
int j = i-1;
while(j>=0 && array[j]>a){
array[j+1] = array[j];
j--;
}
array[j+1] = a;
}
for(int i=0;i<array.length;i++){
System.out.print(array[i]+",");
}
}
}
package com.sort;
/**
* 二分(折半)插入(Binary insert sort)排序是一种在直接插入排序算法上进行小改动的排序算法。
* 其与直接排序算法最大的区别在于查找插入位置时使用的是二分查找的方式,在速度上有一定提升。
* 但是,在查找二分点的时间上的时间损耗,导致了这个算法并不能比直接插入排序优秀多少,除非你有十分确切的数据大小和随机访问迭代器。
* @author Administrator
*
*/
public class MiddleSortt {
public static void main(String[] args) {
int[] array = new int[]{10,14,15,32,65,25,11,2,5,9,19,27};
int middle,i,j,a,left,right;
for(i = 1;i<array.length;i++){
a = array[i];
left = 0;
right = i-1;
while(left<=right){
middle = (left+right)/2;
if(array[middle] > a){
right = middle - 1;
}else{
left = middle + 1;
}
}
for (j = i - 1; j >= left; j--){
array[j + 1] = array[j];
}
array[left] = a;
}
for(int s=0;s<array.length;s++){
System.out.print(array[s]+",");
}
}
}
package com.sort;
/**
* 希尔排序
* 希尔排序,也称递减增量排序算法,是插入排序的一种高速而稳定的改进版本。
* 希尔排序是基于插入排序的以下两点性质而提出改进方法的:
* 1、插入排序在对几乎已经排好序的数据操作时, 效率高, 即可以达到线性排序的效率
* 2、但插入排序一般来说是低效的, 因为插入排序每次只能将数据移动一位>
* @author Administrator
*
*/
public class ShellSort {
public static void main(String[] args) {
int[] array = new int[]{10,14,15,32,65,25,11,2,5,9,19,27};
int i,j,a;
int h = 0;
while(h<=array.length){
h = 3*h+1;
}
while(h>=1){
for(i=h;i<array.length;i++){
j = i-h;
a = array[i];
while((j>=0)&&(array[j]>a)){
array[j+h] = array[j];
j = j-h;
}
array[j+h] = a;
}
h = (h-1)/3;
}
for(int s=0;s<array.length;s++){
System.out.print(array[s]+",");
}
}
}
package com.sort;
/**
* 选择排序,它的工作原理如下。首先在未排序序列中找到最小元素,存放到排序序列的起始位置,然后,再从剩余未排序元素中继续寻找最小元素,
* 然后放到排序序列末尾。以此类推,直到所有元素均排序完毕。
* @author Administrator
*
*/
public class SelectionSort {
static void exchange(int[] array,int a,int b){
int c =array[a];
array[a] = array[b];
array[b] = c;
}
public static void main(String[] args) {
int[] array = new int[]{10,14,15,32,65,25,11,2,5,9,19,27};
for(int i = 0;i<array.length-1;i++){
int min=i;
for(int j = i+1;j<array.length;j++){
if(array[j]<array[min]){
min = j;
}
}
if(min != i){
SelectionSort.exchange(array, min, i);
}
}
for(int i=0;i<array.length;i++){
System.out.print(array[i]+",");
}
}
}
package com.sort;
/**
*
* 快速排序是由东尼·霍尔所发展的一种排序算法。在平均状况下,排序 n 个项目要Ο(n log n)次比较。
* 在最坏状况下则需要Ο(n2)次比较,但这种状况并不常见。事实上,快速排序通常明显比其他Ο(n log n) 算法更快,
* 因为它的内部循环(inner loop)可以在大部分的架构上很有效率地被实现出来,且在大部分真实世界的数据,
* 可以决定设计的选择,减少所需时间的二次方项之可能性。
*步骤:
*1.从数列中挑出一个元素,称为 “基准”(pivot),
*2.重新排序数列,所有元素比基准值小的摆放在基准前面,所有元素比基准值大的摆在基准的后面(相同的数可以到任一边)。
*3.在这个分区退出之后,该基准就处于数列的中间位置。这个称为分区(partition)操作。
* 递归地(recursive)把小于基准值元素的子数列和大于基准值元素的子数列排序。
* @author Administrator
*
*/
public class QuickSort {
public static void main(String[] args) {
int[] array = new int[]{5,1,6,8,7,4,9,10,2,3};
QuickSort.quickSort(0, array.length-1, array);
for(int i=0;i<array.length;i++){
System.out.print(array[i]+",");
}
}
public static void quickSort(int a,int b,int[] array){
if(a<b){
int x = array[a];
int i = a;
int j = b;
while(i<j){
while(i < j && x<=array[j]){
j--;
}
if(i<j){
array[i] = array[j];
}
while(i<j && x>=array[i]){
i++;
}
if(i<j){
array[j] = array[i];
}
}
array[i] = x;
quickSort(a,i-1,array);
quickSort(i+1,b,array);
}
}
}
根据实测这几种排序方法效率高低依次为:快速排序>希尔排序>二分法排序>直接插入排序>选择排序>冒泡排序。
千万长度数组排序对比,快速排序用时 1 秒,希尔排序用时 2 秒。
十万长度数组排序对比,二分插入法排序用时 2 秒,直接插入排序用时 3 秒,选择排序用时 6 秒,冒泡排序用时 14 秒。