文章目录
零、写在前面
- 稳定性是指相等的元素经过排序之后相对顺序是否发生了改变
一、冒泡排序(稳定)
- 时间复杂度(平均):O( n 2 n^2 n2)
- 时间复杂度(最优):O(n)
- 时间复杂度(最差):O( n 2 n^2 n2)
- 空间复杂度:O(1)
package cn.edu.neu.argorithm.sorter;
import java.util.Arrays;
/**
* @author 32098
*
* 冒泡排序
*/
public class BubbleSorter {
/**
* 升序排序
* @param a a
* @param <T> T
*/
public static <T extends Comparable<? super T>> void bubbleSort (T[] a) {
int pass = 1;
boolean exchange = true;
while(pass < a.length && exchange) {
exchange = bubbleExchange(a, pass);
pass++;
}
}
/**
*
* @param a a
* @param i i
* @param <T> T
* @return exchange
*/
private static <T extends Comparable<? super T>> boolean bubbleExchange(T[] a, int i){
// 交换标志置为 false 表示未交换
boolean exchange = false;
for ( int j = 0; j<a.length-i; j++ ) {
if (a[j].compareTo(a[j+1])>0){
T temp = a[j];
a[j] = a[j+1];
a[j+1] = temp;
exchange = true;
}
}
return exchange;
}
/**
* 降序排序
* @param a a
* @param <T> T
*/
public static <T extends Comparable<? super T>> void bubbleSortDesc (T[] a) {
T tmp;
for(int i=0; i<a.length; i++){
boolean exchange = false;
for(int j=1; j<a.length-i; j++){
if(a[j].compareTo(a[j-1])>0){
tmp = a[j-1];
a[j-1] = a[j];
a[j] = tmp;
exchange = true;
}
}
// 未交换直接退出排序
if(!exchange){
break;
}
}
}
public static void main(String[] args) {
Integer[] a={49, 38, 65, 97, 76, 13, 27, 49};
bubbleSort(a);
System.out.println(Arrays.asList(a));
a= new Integer[]{49, 38, 65, 97, 76, 13, 27, 49};
bubbleSortDesc(a);
System.out.println(Arrays.asList(a));
}
}
二、插入排序(稳定)
-
时间复杂度(平均):O( n 2 n^2 n2)
-
时间复杂度(最优):O(n)
-
时间复杂度(最差):O( n 2 n^2 n2)
-
空间复杂度:O(1)
package cn.edu.neu.argorithm.sorter;
/**
* @author 32098
*
* 简单插入排序
*/
public class InsertionSorter {
public static <T extends Comparable<? super T>> void insertionSort(T[] a){
// i 初始为 1 是默认数组 a 的 第一个元素 a[0] 已插入
for (int i = 1; i < a.length; i++) {
insert(a, i);
}
}
private static <T extends Comparable<? super T>> void insert(T[] a, int i) {
T insertItem = a[i];
// 从后向前比较
int j = i;
while(j-1>=0 && insertItem.compareTo(a[j-1])<0){
a[j] = a[j-1];
j--;
}
a[j] = insertItem;
}
public static void main(String[] args) {
Integer[] a={49, 38, 65, 97, 76, 13, 27, 49};
insertionSort(a);
for (Integer integer : a) {
System.out.println(integer);
}
}
}
三、希尔排序-增量递减排序(不稳定)
增量+插入排序
- 时间复杂度(平均):O( n 3 / 2 n^{3/2} n3/2) \ O( n l o g 2 n n log^2 n nlog2n) (取决于间距序列的选取)
- 时间复杂度(最优):O(n)
- 时间复杂度(最差):O( n 3 / 2 n^{3/2} n3/2) \ O( n l o g 2 n n log^2 n nlog2n) (取决于间距序列的选取)
- 空间复杂度:O(1)
2.
package cn.edu.neu.argorithm.sorter;
/**
* @author 32098
*
* 希尔排序
*/
public class ShellSorter {
public static <T extends Comparable<? super T>> void shellSort (T[] a) {
int gap = a.length/2;
// gap 是子序列间隔
while (gap!=0) {
// 插入排序
shellInsert(a, gap);
// gap=gap/2
gap = (gap == 2) ? 1 : (int) ( gap/2.2 );
}
}
private static <T extends Comparable<? super T>> void shellInsert (T[] a, int gap ) {
for (int i = gap; i < a.length; i++) {
T insertItem = a[i];
int j = i;
while(j-gap>=0 && insertItem.compareTo(a[j-gap])<0){
a[j] = a[j-gap];
j = j-gap;
}
a[j] = insertItem;
}
}
public static void main(String[] args) {
Integer[] a={91, 67, 35, 62, 29, 72, 46, 57};
shellSort(a);
for (Integer integer : a) {
System.out.println(integer);
}
}
}
四、快速排序(不稳定)
-
时间复杂度(平均):O(n logn)
-
时间复杂度(最优):O(n logn)
-
时间复杂度(最差):O( n 2 n^2 n2)
-
空间复杂度:O(logn)
-
选择基准点
-
与第一个元素交换
-
遍历数组,交换小的数到swapPos
package cn.edu.neu.argorithm.sorter;
import java.util.Arrays;
/**
* @author 32098
*
* 快速排序:
* 1. pivot
*/
public class QuickSorter {
public static<T extends Comparable<? super T>> void quickSort(T[] a) {
quickSort(a,0,a.length-1);
}
private static<T extends Comparable<? super T>> void quickSort(T[] a, int left, int right) {
if(left<right) {
int pivotPos = partition(a, left, right);
// 左子区间递归快排
quickSort(a, left, pivotPos-1);
// 右子区间递归快排
quickSort(a, pivotPos+1, right);
}
}
private static<T extends Comparable<? super T>> int partition(T[] a, int low, int high) {
int swapPos=low;
// 交换数组中间的元素到第一个元素,并作为基准点
swap(a, low, (low+high)/2);
T pivot=a[low];
// 小于基准点的元素放到左边、大于基准点的元素放到右边
for(int i=low+1; i<=high; i++) {
if(a[i].compareTo(pivot)<0) {
swapPos++;
swap(a, swapPos, i);
}
}
swap(a, low, swapPos);
return swapPos;
}
private static<T extends Comparable<? super T>> void swap(T[] a, int swapA, int swapB) {
T temp=a[swapA];
a[swapA]=a[swapB];
a[swapB]=temp;
}
public static void main(String[] args) {
Integer[] a={5,11,4,25,10,3,9,15,12};
QuickSorter.quickSort(a);
System.out.println(Arrays.asList(a));
a = new Integer[]{5, 11, 4, 25, 10, 3, 9, 15, 12};
}
}
五、归并排序(稳定)
- 时间复杂度(平均):O(n logn)
- 时间复杂度(最优):O(n logn)
- 时间复杂度(最差):O(n logn)
- 空间复杂度:O(n)
package cn.edu.neu.argorithm.sorter;
import java.util.Arrays;
/**
* @author 32098
*/
public class MergeSorter {
private static <T extends Comparable<? super T>> void merge (T[] initList, T[] mergedList, int l, int m, int n ) {
int i = l, j = m + 1, k = l;
while (i <= m && j <= n) {
if (initList[i].compareTo(initList[j]) <= 0) {
mergedList[k] = initList[i];
i++;
k++;
} else {
mergedList[k] = initList[j];
j++;
k++;
}
}
if (i <= m) {
while (i <= m) {
mergedList[k++] = initList[i++];
}
} else {
while (j <= n) {
mergedList[k++] = initList[j++];
}
}
}
private static <T extends Comparable<? super T>> void mergePass (T[] initList, T[] mergedList, int len ) {
int i =0;
while ( i+2*len <= initList.length) {
merge(initList, mergedList, i, i+len-1,
i+2*len-1);
i = i + 2*len;
}
if ( i+len <= initList.length-1 ) {
merge ( initList, mergedList, i, i+len-1,
initList.length-1 );
} else {
for (int j = i; j <= initList.length-1; j++ ) {
mergedList[j] = initList[j];
}
}
}
public static <T extends Comparable<? super T>> void mergeSort(T[] list) {
T[] tempList = Arrays.copyOf(list, list.length);
int len = 1;
while ( len < list.length ) {
mergePass ( list, tempList, len ); len *= 2;
mergePass ( tempList, list, len ); len *= 2;
}
}
public static void main(String[] args) {
Integer[] a={5,11,4,25,10,3,9,15,12};
MergeSorter.mergeSort(a);
System.out.println(Arrays.asList(a));
}
}
六、选择排序(不稳定)
- 时间复杂度(平均):O( n 2 n^2 n2)
- 时间复杂度(最优):O( n 2 n^2 n2)
- 时间复杂度(最差):O( n 2 n^2 n2)
- 空间复杂度:O(1)
package cn.edu.neu.argorithm.sorter;
/**
* @author 32098
*/
public class SelectionSorter {
private static <T extends Comparable<? super T>> void selectSort (T[] a) {
for(int i = 0; i < a.length-1; i++) {
selectExchange (a, i);
}
}
private static <T extends Comparable<? super T>> void selectExchange (T[] a, int i) {
// k: min index
int k = i;
for ( int j = i+1; j < a.length; j++) {
if (a[j].compareTo(a[k])<0) {
k = j;
}
}
if (k != i) {
T temp = a[i];
a[i] = a[k];
a[k] = temp;
}
}
public static void main(String[] args) {
Integer[] a={91, 67, 35, 62, 29, 72, 46, 57};
selectSort(a);
for (Integer integer : a) {
System.out.println(integer);
}
}
}
七、堆排序(不稳定)***:略
优先权队列
- 降序使用小堆
- 升序使用大堆