1.插入排序
假设第一个数已经是排好序的,把第二个根据大小关系插到第一个前面或维持不动,把第三个根据前面两个的大小关系插到对应位置,依次往后。
public class InsertSort { public static void main(String[] args){ int a[] = {49,38,65,97,76,13,27,49,78,34,12,64,5,4,62,99,98,54,56,17,18,23,34,15,35,25,53,51}; int temp = 0; for(int i = 1; i < a.length; i++) { int j = i - 1; temp = a[i]; for( ; j >= 0&&temp < a[j]; j--) //每次检查前一个 { a[j+1] = a[j]; //将大于temp的值整体后移一个单位 } a[j+1] = temp; //最后把当前位置的值恢复到对应位置 } for( int i = 0; i < a.length; i++) System.out.println(a[i]); } }
选择排序:最好情况时间复杂度O(n),最差情况时间复杂度为O(n2),平均时间复杂度为O(n2),稳定,空间复杂度为O(1)。
2.选择排序
选择排序就是选出最值与当前位置的元素交换位置,每次选出一个值,对所有未排序的走一遍。
public class SelectSort { public static void main(String[] args){ int a[] = {49,38,65,97,76,13,27,49,78,34,12,64,5,4,62,99,98,54,56,17,18,23,34,15,35,25,53,51}; int temp; int position = 0; for( int i = 0; i < a.length; i++) { temp = a[i]; for( int j = i + 1; j <a.length; j++) { if( a[j] < temp)//找出最小的,值放在temp,下标放在position { temp = a[j]; position = j; } } a[position] = a[i]; a[i] = temp;//最小的和当前下标为i的元素交换位置 } for( int i = 0; i < a.length; i++) System.out.println(a[i]); } }
选择排序:最好情况时间复杂度为O(n2),最差情况时间复杂度为O(n2),平均时间复杂度为O(n2),稳定,空间复杂度为O(1)
3.冒泡排序
冒泡排序是每当两相邻的数比较后发现它们的排序与排序要求相反时,就将它们互换,每一轮都会出一个最大的或者最小的去到对应的位置。
public class BubbleSort { public static void main(String[] args){ int a[] = {49,38,65,97,76,13,27,49,78,34,12,64,5,4,62,99,98,54,56,17,18,23,34,15,35,25,53,51}; int temp; for( int i = 0; i < a.length; i++) { for( int j = 0; j <a.length - i - 1; j++) { if(a[j+1]<a[j]) { temp=a[j]; a[j]=a[j+1]; a[j+1]=temp; } } } for( int i = 0; i < a.length; i++) System.out.println(a[i]); } }
冒泡排序:最好情况时间复杂度为O(n),最坏时间复杂度O(n2),平均时间复杂度为O(n2),稳定,空间复杂度为O(1)
4.希尔排序(shell sortion)
算法先将要排序的一组数按某个增量d(n/2,n为要排序数的个数)分成若干组,每组中记录的下标相差d.对每组中全部元素进行直接插入排序,然后再用一个较小的增量(d/2)对它进行分组,在每组中再进行直接插入排序。当增量减到1时,进行直接插入排序后,排序完成。
public class ShellSort { public static void main(String[] args){ int a[] = {49,38,65,97,76,13,27,49,78,34,12,64,5,4,62,99,98,54,56,17,18,23,34,15,35,25,53,51}; int temp; double d1 = a.length; while( true ) { d1 = Math.ceil( d1/2); int d = (int) d1; //分组 for( int x = 0; x < d; x++) { //按照插入排序进行排序 for( int i = x + d; i < a.length; i += d) { int j; temp = a[i]; for( j = i - d; j >= 0 && a[ j] > temp ; j -= d) { a[ j + d] = a[ j]; } a[ j + d] = temp; } } if(d==1)break; } for( int i = 0; i < a.length; i++) System.out.println(a[i]); } }
希尔排序:最好情况时间复杂度为O(n),最坏时间复杂度O(nlgn),平均时间复杂度为O(nlgn),不稳定,空间复杂度为O(1)
5.快速排列
选择一个基准元素,通常选择第一个元素或者最后一个元素,通过一趟扫描,将待排序列分成两部分,一部分比基准元素小,一部分大于等于基准元素,此时基准元素在其排好序后的正确位置,然后再用同样的方法递归地排序划分的两部分。
public class QuickSort { public static int getMiddle(int[] list, int low, int high) { int tmp = list[low]; //数组的第一个作为中轴 while (low < high) { while (low < high && list[high] >= tmp) { high--; } list[low] = list[high]; //比中轴小的记录移到低端 while (low < high && list[low] <= tmp) { low++; } list[high] = list[low]; //比中轴大的记录移到高端 } list[low] = tmp; //中轴记录到尾 return low; //返回中轴的位置 } public static void _quickSort(int[] list, int low, int high) { if (low < high) { int middle = getMiddle(list, low, high); //将list数组进行一分为二 _quickSort(list, low, middle - 1); //对低字表进行递归排序 _quickSort(list, middle + 1, high); //对高字表进行递归排序 } } public static void quick(int[] a2) { if (a2.length > 0) { //查看数组是否为空 _quickSort(a2, 0, a2.length - 1); } } public static void main(String[] args){ int a[] = {49,38,65,97,76,13,27,49,78,34,12,64,5,4,62,99,98,54,56,17,18,23,34,15,35,25,53,51}; quick(a); for( int i = 0; i < a.length; i++) System.out.println(a[i]); } }
快速排序:最好情况时间复杂度为O(nlgn),最坏时间复杂度O(nlgn),平均时间复杂度为O(nlgn),不稳定,空间复杂度为O(1)
6.归并排序