1、冒泡排序
思想 遍历数组,对当前尚未排好序的范围内的全部数,从前往后对相邻的两个数依次进行比较和调整,较大的数往后沉,较小的数往前冒,每一趟遍历,都会沉下一个最大的数,已沉下的数无需再参与比较,所以每一轮比较的次数也逐渐减少。实现
public class Demo {
public static void main ( String [ ] args) {
int [ ] a = { 3 , - 1 , 9 , 7 , - 5 , 4 , 13 , 6 , 2 } ;
System . out. println ( Arrays . toString ( a) ) ;
bubble2 ( a) ;
System . out. println ( Arrays . toString ( a) ) ;
}
private static void bubble ( int [ ] a) {
for ( int i= 0 ; i< a. length- 1 ; i++ ) {
for ( int j= 0 ; j< a. length- 1 - i; j++ ) {
if ( a[ j] > a[ j+ 1 ] ) {
swap ( a, j, j+ 1 ) ;
}
}
}
}
private static void bubble2 ( int [ ] a) {
for ( int i= 0 ; i< a. length- 1 ; i++ ) {
for ( int j= a. length- 1 ; j> i; j-- ) {
if ( a[ j] < a[ j- 1 ] ) {
swap ( a, j, j- 1 ) ;
}
}
}
}
private static void swap ( int [ ] a, int m, int n) {
int t = a[ m] ;
a[ m] = a[ n] ;
a[ n] = t;
}
}
性能
比较次数 :n(n-1)/2 时间复杂度:O(n^2) 平方级
2、选择排序
思想 首先,找到数组中最小的元素,将它与数组中第一个元素交换位置;再次,在剩下的元素中找到最小的元素,将它与数组中第二个元素交换位置,如此重复,直至整个数组有序。实现
public class Demo {
public static void main ( String [ ] args) {
int [ ] a = { 3 , - 1 , 9 , 7 , - 5 , 4 , 13 , 6 , 2 } ;
System . out. println ( Arrays . toString ( a) ) ;
selection ( a) ;
System . out. println ( Arrays . toString ( a) ) ;
}
private static void selection ( int [ ] a) {
for ( int i= 0 ; i< a. length- 1 ; i++ ) {
int min = i;
for ( int j= i+ 1 ; j< a. length; j++ ) {
if ( a[ j] < a[ min] )
min = j;
}
if ( min!= i)
swap ( a, min, i) ;
}
}
private static void swap ( int [ ] a, int m, int n) {
int t = a[ m] ;
a[ m] = a[ n] ;
a[ n] = t;
}
}
性能
交换 N 次 比较 n(n-1)/2 次 时间复杂度 O(n^2) 平方级
3、插入排序
思想 在待排的元素中,假设前面 n-1 个数已经是有序的,现将第 n 个数插入排好序的序列中,调整位置,使得插入第 n 个数的序列也是有序的。实现
public class Demo {
public static void main ( String [ ] args) {
int [ ] a = { 3 , - 1 , 9 , 7 , - 5 , 4 , 13 , 6 , 2 } ;
System . out. println ( Arrays . toString ( a) ) ;
insertion ( a) ;
System . out. println ( Arrays . toString ( a) ) ;
}
private static void insertion ( int [ ] a) {
for ( int i= 1 ; i< a. length; i++ ) {
int index = i;
for ( int j= i- 1 ; j>= 0 ; j-- ) {
if ( a[ index] >= a[ j] )
break ;
else {
swap ( a, j, index) ;
index = j;
}
}
}
}
private static void swap ( int [ ] a, int m, int n) {
int t = a[ m] ;
a[ m] = a[ n] ;
a[ n] = t;
}
}
性能
数组有序的情况:比较 n-1 次,交换 0 次,时间复杂度 O(n) 数组杂乱的情况:O(n^2) 时间复杂度:O(n)~ O(n^2)
4、快速排序
思想 分治 的排序算法,先取一个切分元素(一般取第一个或最后一个元素),然后从数组的左端向右扫描直至找到一个大于等于它的元素,再从数组的右端开始向左扫描,直至找到一个小于等于它的元素,交换左右指针位置的元素,继续两端扫描,直至左右指针相遇,把切分元素放至该位置,递归 进行切分元素两边的数组,重复以上步骤。实现
public class Demo {
public static void main ( String [ ] args) {
int [ ] a = { 3 , - 1 , 9 , 7 , - 5 , 4 , 13 , 6 , 2 } ;
System . out. println ( Arrays . toString ( a) ) ;
quick ( a) ;
System . out. println ( Arrays . toString ( a) ) ;
}
private static void quick ( int [ ] a) {
quick ( a, 0 , a. length- 1 ) ;
}
private static void quick ( int [ ] a, int start, int end) {
if ( start>= end)
return ;
int left = start;
int right = end;
int p = a[ end] ;
while ( left< right) {
while ( left< right && a[ left] < p)
left++ ;
while ( left< right && a[ right] >= p)
right-- ;
swap ( a, left, right) ;
}
int pIndex = left;
swap ( a, pIndex, end) ;
quick ( a, 0 , pIndex- 1 ) ;
quick ( a, pIndex+ 1 , end) ;
}
private static void swap ( int [ ] a, int i, int j) {
int tmp = a[ i] ;
a[ i] = a[ j] ;
a[ j] = tmp;
}
}
5、归并排序
思想 归并排序就是将两个或两个以上有序表合并成一个新的有序表,即把待排序的序列分为若干个子序列,每个子序列都是有序的,然后再把有序子序列合并为整体有序序列。实现
public class Demo {
public static void main ( String [ ] args) {
int [ ] a = { 3 , - 1 , 9 , 7 , - 5 , 4 , 13 , 6 , 2 } ;
System . out. println ( Arrays . toString ( a) ) ;
merge ( a) ;
System . out. println ( Arrays . toString ( a) ) ;
}
private static int [ ] tempArr;
private static void merge ( int [ ] a) {
tempArr = new int [ a. length] ;
merge ( a, 0 , a. length- 1 ) ;
}
private static void merge ( int [ ] a, int start, int end) {
while ( end<= start)
return ;
int mid = start + ( end- start) / 2 ;
merge ( a, start, mid) ;
merge ( a, mid+ 1 , end) ;
merge ( a, start, mid, end) ;
}
private static void merge ( int [ ] a, int start, int mid, int end) {
int i = start;
int j = mid+ 1 ;
for ( int k= start; k<= end; k++ ) {
tempArr[ k] = a[ k] ;
}
for ( int k= start; k<= end; k++ ) {
if ( i> mid)
a[ k] = tempArr[ j++ ] ;
else if ( j> end)
a[ k] = tempArr[ i++ ] ;
else if ( tempArr[ j] < tempArr[ i] )
a[ k] = tempArr[ j++ ] ;
else
a[ k] = tempArr[ i++ ] ;
}
}
}
性能
递归深度 :logN 每次归并的平均时间复杂度:O(n) 时间复杂度:O(nlogN) 线性对数级