目录
1.排序的稳定性
如果ki = kj,且在排序前的序列中ri 领先于rj。如果排序之后,ri仍然领先于rj,则称所用的排序算法是稳定的,否则就是不稳定的。例如:下图中,对总分进行排序,令狐冲和分数和张无忌的分数是一样的,排序之前令狐冲 在 张无忌之前,如果排序之后,令狐冲仍然在张无忌之前,那就是稳定的;否则就是不稳定的。
2.内排序与外排序
根据排序过程中待排序的记录是否全部被放置在内存中,分为内排序和外排序。
对于内排序,排序算法的性能主要受3个方面的影响:时间性能,辅助空间,算法复杂性
- 时间性能:在内排序中,主要进行两种操作:比较和移动。高效率的内排序算法应该尽可能少的对关键字进行比较和移动。
- 辅助空间:除了存放待排序所占用的存储空间之外,执行算法所需要的其他存储空间。
- 算法复杂性:算法本身的复杂度。
按照算法的复杂度一般分为两大类:简单算法,改进算法。
简单算法:冒泡,简单选择排序,直接插入
改进算法:希尔排序,堆排序,归并排序,快速排序
3.冒泡
时间复杂度:O(n^2),是稳定排序
/**
* 冒泡排序 1
* 并不算严格意义上的冒泡排序,只是简单的交换排序,让每一个数字和它后面的数字进行比较,如果大则交换
* @param arr
*/
public void bubbleSort(int[] arr) {
for(int i = 0; i < arr.length; i++) {
for (int j = i + 1; j < arr.length; j++) {
if (arr[i] > arr[j]) {
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
}
}
/**
* 冒泡排序 1
* 从数组尾部开始两两比较,如果前面的元素大于后面的元素,则交换位置
* @param arr
*/
public void bubbleSort2(int[] arr) {
for(int i = 1; i < arr.length; i++) {
for (int j = arr.length - 1; j >= i; j--) {
if (arr[j -1] > arr[j]) {
int temp = arr[j - 1];
arr[j - 1] = arr[j];
arr[j] = temp;
}
}
}
}
/**
* 冒泡排序 3
* 如果 arr = {2,1,3,4,5,6,7,8,9};经过第一次比较之后,{1,2,3,4,5,6,7,8,9},就已经变成了有序的数组,没必要在进行排序,添加flag
* @param arr
*/
public void bubbleSort3(int[] arr) {
boolean flag = true;
for(int i = 1; i < arr.length && flag; i++) {
flag = false;
for (int j = arr.length - 1; j >= i; j--) {
if (arr[j -1] > arr[j]) {
int temp = arr[j - 1];
arr[j - 1] = arr[j];
arr[j] = temp;
flag = true;
}
}
}
}
4.简单选择排序
时间复杂度:O(n^2),是稳定排序
/**
* 这个算法的思想是,每一次找到最小元素的位置,如果最小元素的位置与一开始初始化的位置不一样,则交换位置
* 虽然时间复杂度还是O(n^2),但是减少了交换元素的次数,性能上要优于冒泡
* @param arr
*/
public void selectSort1(int[] arr) {
for(int i = 0; i < arr.length; i++) {
int min = i;
for (int j = i + 1; j < arr.length; j++) {
if (arr[min] > arr[j]) {
min = j;
}
}
if (i != min) {
swap(arr,i,min);
}
}
}
5.直接插入排序
将0位置的元素作为哨兵,对(1,i-1)的元素进行倒序比较,如果大于arr[0],就将元素后移,最后将哨兵元素放入腾出来的位置。
平均比较和移动的次数为n^2/4,因此它的时间复杂度为O(n^2)。它的性能优于冒泡和选择排序。
public void insertSortTest() {
int[] arr = {0,9,1,5,8,3,7,4,6,2};
sort.insertSort(arr);
}
public void insertSort(int[] arr) {
int i,j;
for(i = 2; i < arr.length; i++) {
if (arr[i-1] > arr[i]) {
arr[0] = arr[i];
for (j = i-1; arr[j] > arr[0]; j--) {
arr[j+1] = arr[j];
}
arr[j+1] = arr[0];
}
}
}
6.希尔排序
7.堆排序
堆排序是对 简单选择排序 的一种改进。
堆是具有下列性质的完全二叉树:每个结点的值都大于或等于其左右孩子结点的值,称为大顶堆;如果每个结点的值都小于或等于其左右孩子结点的值,称为小顶堆。
8.归并排序
9.快速排序