冒泡排序、插入排序、选择排序
/**
* 冒泡排序
*
* @param a 表示数组
* @param n 表示数组大小
*/
public void bubbleSort(int[] a, int n) {
if (n <= 1) {
return;
}
for (int i = 0; i < n - 1; ++i) {
// 提前退出冒泡循环的标志位
boolean flag = false;
for (int j = 0; j < n - i - 1; ++j) {
if (a[j] > a[j + 1]) {
// 交换
int tmp = a[j];
a[j] = a[j + 1];
a[j + 1] = tmp;
// 表示有数据交换
flag = true;
}
}
if (!flag) {
// 没有数据交换,提前退出
break;
}
}
}
/**
* 插入排序
*
* @param a 表示数组
* @param n 表示数组大小
*/
public void insertionSort(int[] a, int n) {
if (n <= 1) {
return;
}
// 从尾到头查找插入的位置
for (int i = 1; i < n; ++i) {
int value = a[i];
int j = i - 1;
for (; j >= 0; --j) {
if (a[j] > value) {
// 数据移动
a[j + 1] = a[j];
} else {
break;
}
}
// 插入数据
a[j + 1] = value;
}
}
/**
* 选择排序
*
* @param a 表示数组
* @param n 表示数组大小
*/
public void selectionSort(int[] a, int n) {
if (n <= 1) {
return;
}
for (int i = 0; i < n - 1; ++i) {
// 从未排序区间中找到最小的元素,并将其放到已排序区间的末尾
int min = i;
for (int j = i + 1; j < n; ++j) {
if (a[j] < a[min]) {
min = j;
}
}
// 交换
int tmp = a[i];
a[i] = a[min];
a[min] = tmp;
}
}
}
如何分析一个排序算法?
<1>算法的执行效率
1.最好、最坏、平均情况时间复杂度。
2.时间复杂度的系数、常数和低阶。
3.比较次数,交换(或移动)次数。
<2>排序算法的稳定性
1.稳定性概念:如果待排序的序列中存在值相等的元素,经过排序之后,相等元素之间原有的先后顺序不变。
2.稳定性重要性:可针对对象的多种属性进行有优先级的排序。
3.举例:给电商交易系统中的“订单”排序,按照金额大小对订单数据排序,对于相同金额的订单以下单时间早晚排序。用稳定排序算法可简洁地解决。先按照下单时间给订单排序,排序完成后用稳定排序算法按照订单金额重新排序。
<3>排序算法的内存损耗
原地排序算法:特指空间复杂度是O(1)的排序算法。
实际开发中,若想性能优化做到极致,这三个排序中首选插入排序!冒泡排序需要 3 个赋值操作,而插入排序只需要 1 个!