八种排序算法
8中排序算法总结:
冒泡排序 不管序列是怎样,都是要比较n(n-1)/2次的,最好、最坏、平均时间复杂度都是O(n^2),需要一个临时变量用来交换数组内数据位置,所以空间复杂度为O(1)。选择排序 是冒泡排序的改进,同样选择排序无论序列是怎样的都是要比较n(n-1)/2次的,最好、最坏、平均时间复杂度也都为O(n^2),需要一个临时变量用来交换数组内数据位置,所以空间复杂度为O(1)。插入排序 不同,如果序列是完全有序的,插入排序只要比较n次无需移动时间复杂度为O(n),如果序列是逆序的,插入排序要比较O(n2)和移动O(n 2),所以平均复杂度为O(n2),最好为O(n),最坏为O(n 2),排序过程中只要一个辅助空间,所以空间复杂度为O(1)。快速排序 的时间复杂度最好是O(nlogn),平均也是O(nlogn),最坏情况是序列本来就是有序的,此时时间复杂度为O(n^2),快速排序的空间复杂度可以理解为递归的深度,而递归的实现依靠栈,平均需要递归logn次,所以平均空间复杂度为O(logn)。归并排序 需要一个临时temp[]来储存归并的结果,空间复杂度为O(n),时间复杂度为O(nlogn),可以将空间复杂度由O(n)降低至O(1),然而相对的时间复杂度则由O(nlogn)升至O(n^2)。希尔排序 的时间复杂度分析极其复杂,只需要记住结论就行。堆排序 的时间复杂度,主要在初始化堆过程和每次选取最大数后重新建堆的过程,初始化建堆时的时间复杂度为O(n),更改堆元素后重建堆的时间复杂度为O(nlogn),所以堆排序的平均、最好、最坏时间复杂度都为O(nlogn),堆排序时就地排序,空间复杂度为常数O(1)。基数排序 对于n个记录,执行一次分配和收集的时间为O(n+r),如果关键字有d位,则要执行d遍,所以总的时间复杂度为O(d(n+r))。该算法的空间复杂度就是在分配元素时,使用的桶空间,空间复杂度为O(r+n)=O(n)。
冒泡排序
public static void sort ( int [ ] a) {
int temp = 0 ;
boolean flag = false ;
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 ] ) {
flag = true ;
temp = a[ j] ;
a[ j] = a[ j+ 1 ] ;
a[ j+ 1 ] = temp;
}
}
if ( flag = false ) {
break ;
} else {
flag = false ;
}
}
}
选择排序
public static void sort ( int [ ] a) {
for ( int i= 0 ; i< a. length- 1 ; i++ ) {
int minIndex = i;
int min = a[ i] ;
for ( int j= i; j< a. length; j++ ) {
if ( min> a[ j] ) {
min = a[ j] ;
minIndex = j;
}
}
if ( minIndex != i) {
a[ minIndex] = a[ i] ;
a[ i] = min;
}
}
}
插入排序
public static void sort ( int [ ] arr) {
int insertIndex = 0 ;
int insertValue = 0 ;
for ( int i= 1 ; i< arr. length; i++ ) {
insertIndex = i- 1 ;
insertValue = arr[ i] ;
while ( insertIndex>= 0 && insertValue < arr[ insertIndex] ) {
arr[ insertIndex+ 1 ] = arr[ insertIndex] ;
insertIndex-- ;
}
arr[ insertIndex+ 1 ] = insertValue;
}
}
快速排序
public static void sort ( int [ ] arr, int left, int right) {
int l = left;
int r = right;
int pivot = arr[ ( left+ right) / 2 ] ;
int temp = 0 ;
while ( true ) {
while ( arr[ l] < pivot) {
l++ ;
}
while ( arr[ r] > pivot) {
r-- ;
}
if ( l >= r) {
break ;
}
temp = arr[ l] ;
arr[ l] = arr[ r] ;
arr[ r] = temp;
if ( arr[ l] == pivot) {
r-- ;
}
if ( arr[ r] == pivot) {
l++ ;
}
}
if ( l == r) {
l++ ;
r-- ;
}
if ( left < r) {
sort ( arr, left, r) ;
}
if ( right > l) {
sort ( arr, l, right) ;
}
}
归并排序
public static void merge ( int [ ] arr, int left, int right, int [ ] temp) {
int mid = ( left+ right) / 2 ;
int i = left;
int j = mid + 1 ;
int t = 0 ;
while ( i <= mid && j <= right) {
if ( arr[ i] < arr[ j] ) {
temp[ t] = arr[ i] ;
i++ ;
t++ ;
} else {
temp[ t] = arr[ j] ;
j++ ;
t++ ;
}
}
while ( i <= mid) {
temp[ t] = arr[ i] ;
i++ ;
t++ ;
}
while ( j <= right) {
temp[ t] = arr[ j] ;
j++ ;
t++ ;
}
t= 0 ;
int templeft = left;
while ( templeft <= right) {
arr[ templeft] = temp[ t] ;
templeft++ ;
t++ ;
}
}
希尔排序
public static void sort ( int [ ] arr) {
int value = 0 ;
int index = 0 ;
for ( int gap= arr. length/ 2 ; gap> 0 ; gap/= 2 ) {
for ( int i= gap; i< arr. length; i++ ) {
index = i- gap;
value = arr[ i] ;
while ( index>= 0 && value < arr[ index] ) {
arr[ index + gap] = arr[ index] ;
index -= gap;
}
arr[ index + gap] = value;
}
}
}
基数排序
public static void sort ( int [ ] arr) {
int max = arr[ 0 ] ;
for ( int i= 0 ; i< arr. length; i++ ) {
if ( arr[ i] > max) {
max = arr[ i] ;
}
}
int maxlength = ( max+ "" ) . length ( ) ;
int [ ] [ ] arrs = new int [ 10 ] [ arr. length] ;
int [ ] arrCount = new int [ 10 ] ;
for ( int i= 0 , n= 1 ; i< maxlength; i++ , n*= 10 ) {
int index = 0 ;
for ( int j= 0 ; j< arr. length; j++ ) {
int k = arr[ j] / n % 10 ;
arrs[ k] [ arrCount[ k] ] = arr[ j] ;
arrCount[ k] ++ ;
}
for ( int j= 0 ; j< 10 ; j++ ) {
for ( int k= 0 ; k< arrCount[ j] ; k++ ) {
arr[ index] = arrs[ j] [ k] ;
index++ ;
}
arrCount[ j] = 0 ;
}
}
}