Java常用的八种排序算法,供参考:
插入排序:
public void insertSort(int [] a){
int len=a.length;//单独把数组长度拿出来,提高效率
int insertNum;//要插入的数
for(int i=1;i<len;i ){//因为第一次不用,所以从1开始
insertNum=a[i];
int j=i-1;//序列元素个数
while(j>0&&a[j]>insertNum){//从后往前循环,将大于insertNum的数向后移动
a[j 1]=a[j];//元素向后移动
j--;
}
a[j 1]=insertNum;//找到位置,插入当前元素
}
}
希尔排序:
public void sheelSort(int [] a){
int len=a.length;//单独把数组长度拿出来,提高效率
while(len!=0){
len=len/2;
for(int i=0;i<len;i ){//分组
for(int j=i len;j<a.length;j =len){//元素从第二个开始
int k=j-len;//k为有序序列最后一位的位数
int temp=a[j];//要插入的元素
/*for(;k>=0&&temp<a[k];k-=len){
a[k len]=a[k];
}*/
while(k>=0&&temp<a[k]){//从后往前遍历
a[k len]=a[k];
k-=len;//向后移动len位
}
a[k len]=temp;
}
}
}
}
简单选择排序:
public void selectSort(int[]a){
int len=a.length;
for(int i=0;i<len;i ){//循环次数
int value=a[i];
int position=i;
for(int j=i 1;j<len;j ){//找到最小的值和位置
if(a[j]<value){
value=a[j];
position=j;
}
}
a[position]=a[i];//进行交换
a[i]=value;
}
}
冒泡排序:
public void selectSort(int[]a){
int len=a.length;
for(int i=0;i<len;i ){//循环次数
int value=a[i];
int position=i;
for(int j=i 1;j<len;j ){//找到最小的值和位置
if(a[j]<value){
value=a[j];
position=j;
}
}
a[position]=a[i];//进行交换
a[i]=value;
}
}
快速排序:
public void quickSort(int[]a,int start,int end){
if(start<end){
int baseNum=a[start];//选基准值
int midNum;//记录中间值
int i=start;
int j=end;
do{
while((a[i]<baseNum)&&i<end){
i ;
}
while((a[j]>baseNum)&&j>start){
j--;
}
if(i<=j){
midNum=a[i];
a[i]=a[j];
a[j]=midNum;
i ;
j--;
}
}while(i<=j);
if(start<j){
quickSort(a,start,j);
}
if(end>i){
quickSort(a,i,end);
}
}
}
归并排序:
public void mergeSort(int[] a, int left, int right) {
int t = 1;// 每组元素个数
int size = right - left 1;
while (t < size) {
int s = t;// 本次循环每组元素个数
t = 2 * s;
int i = left;
while (i (t - 1) < size) {
merge(a, i, i (s - 1), i (t - 1));
i = t;
}
if (i (s - 1) < right)
merge(a, i, i (s - 1), right);
}
}
private static void merge(int[] data, int p, int q, int r) {
int[] B = new int[data.length];
int s = p;
int t = q 1;
int k = p;
while (s <= q && t <= r) {
if (data[s] <= data[t]) {
B[k] = data[s];
s ;
} else {
B[k] = data[t];
t ;
}
k ;
}
if (s == q 1)
B[k] = data[t];
else
B[k] = data[s];
for (int i = p; i <= r; i )
data[i] = B[i];
}
堆排序:
public void selectSort(int[]a){
int len=a.length;
for(int i=0;i<len;i ){//循环次数
int value=a[i];
int position=i;
for(int j=i 1;j<len;j ){//找到最小的值和位置
if(a[j]<value){
value=a[j];
position=j;
}
}
a[position]=a[i];//进行交换
a[i]=value;
}
}
基数排序:
public void baseSort(int[] a) {
//首先确定排序的趟数;
int max = a[0];
for (int i = 1; i < a.length; i ) {
if (a[i] > max) {
max = a[i];
}
}
int time = 0;
//判断位数;
while (max > 0) {
max /= 10;
time ;
}
//建立10个队列;
List<ArrayList<Integer>> queue = new ArrayList<ArrayList<Integer>>();
for (int i = 0; i < 10; i ) {
ArrayList<Integer> queue1 = new ArrayList<Integer>();
queue.add(queue1);
}
//进行time次分配和收集;
for (int i = 0; i < time; i ) {
//分配数组元素;
for (int j = 0; j < a.length; j ) {
//得到数字的第time 1位数;
int x = a[j] % (int) Math.pow(10, i 1) / (int) Math.pow(10, i);
ArrayList<Integer> queue2 = queue.get(x);
queue2.add(a[j]);
queue.set(x, queue2);
}
int count = 0;//元素计数器;
//收集队列元素;
for (int k = 0; k < 10; k ) {
while (queue.get(k).size() > 0) {
ArrayList<Integer> queue3 = queue.get(k);
a[count] = queue3.get(0);
queue3.remove(0);
count ;
}
}
}
}
总结:
一、稳定性:
稳定:冒泡排序、插入排序、归并排序和基数排序
不稳定:选择排序、快速排序、希尔排序、堆排序
二、平均时间复杂度
O(n^2):直接插入排序,简单选择排序,冒泡排序。
在数据规模较小时(9W内),直接插入排序,简单选择排序差不多。当数据较大时,冒泡排序算法的时间代价最高。性能为O(n^2)的算法基本上是相邻元素进行比较,基本上都是稳定的。
O(nlogn):快速排序,归并排序,希尔排序,堆排序。
其中,快排是最好的, 其次是归并和希尔,堆排序在数据量很大时效果明显。
三、排序算法的选择
1.数据规模较小
(1)待排序列基本序的情况下,可以选择直接插入排序;
(2)对稳定性不作要求宜用简单选择排序,对稳定性有要求宜用插入或冒泡
2.数据规模不是很大
(1)完全可以用内存空间,序列杂乱无序,对稳定性没有要求,快速排序,此时要付出log(N)的额外空间。
(2)序列本身可能有序,对稳定性有要求,空间允许下,宜用归并排序
3.数据规模很大
(1)对稳定性有求,则可考虑归并排序。
(2)对稳定性没要求,宜用堆排序
4.序列初始基本有序(正序),宜用直接插入,冒泡
赠人玫瑰
手留余香
我们曾如此渴望命运的波澜,到最后才发现:人生最曼妙的风景,竟是内心的淡定与从容……我们曾如此期盼外界的认可,到最后才知道:世界是自己的,与他人毫无关系!-杨绛先生