前言
开发过程中经常会遇到各种对数据进行排序的事情,在平常使用中数据量小对于排序性能要求不高,但是在数据量以百万为单位的数据排序时就是对你排序算法的考验了,以下总结几种常用的排序算法,记住,算法没有绝对只有因地制宜。
- 冒泡排序
- 选择排序
- 插入排序
- 归并排序
冒泡排序
一:介绍
冒泡排序算法运行起来非常慢,但是在概念上他是排序算法中最简单的,因此冒泡排序在刚开始研究排序算法时是一个非常好的算法。
二:概念
从左往右开始,比较两个数大(小)时交换位置,依次便利序列中的数,每执行一次最右边的数字都是最大(最小)的,执行完后即可排序好。
三:O复杂度
O(N2)
四:代码
public static void bubbleSort() {// 冒泡排序
int[] arr = random();
int count = 0;
int temp = 0;
for (int i = 0; i < arr.length; i++) {
for (int j = i + 1; j < arr.length; j++) {
count++;
if (arr[i] > arr[j]) {
temp = arr[j];
arr[j] = arr[i];
arr[i] = temp;
}
}
}
for (int i = 0; i < arr.length; i++) {
System.out.print(", " + arr[i]);
}
System.out.println(" :Count = " + count);
}
选择排序
一:介绍
选择排序是冒泡排序的一个改进,他们都进行了相同次数的比较,但是选择排序要比冒泡排序少的交换次数,所以选择排序的效率是要高于冒泡排序的。
二:概念
首先选择序列中最大(最小)的数与序列最左0位置替换,下标加1,继续选择右边序列最大(最小)数与最左位置对比,依次执行这样左边的数永远都是排序好的,执行完后序列排序好。
三:O复杂度
比较次数O(N2),交换次数要少得多
四:代码
public static void selectSort() {// 选择排序
int[] arr = random();
int count = 0;
for (int i = 0; i < arr.length; i++) {
int max = arr[i], temp = -1, tmp;
for (int j = i + 1; j < arr.length; j++) {
count++;
if (arr[j] > max) {
max = arr[j];
temp = j;
}
}
if (temp >= 0) {
tmp = arr[temp];
arr[temp] = arr[i];
arr[i] = tmp;
}
}
for (int i = 0; i < arr.length; i++) {
System.out.print(", " + arr[i]);
}
System.out.println(" :Count = " + count);
}
插入排序
一:介绍
大多数情况下插入排序是简单排序中最好的一种,虽然插入排序仍然需要O(N2)的时间,但是在一般情况下他比冒泡排序快一倍,比选择排序还要快一点。
二:概念
首先从位置1开始,将当前位置数插入到左侧序列中保持左侧序列排序不变,依次循环下标位置,执行完后排序完成。
三:O复杂度
比较次数O(N2),交换次数要更少
四:代码
public static void insertSort() {// 插入排序
int[] arr = random();
int count = 0;
int j = 0;
int target = 0;
for (int i = 1; i < arr.length; i++) {
j = i;
target = arr[i];
while (j > 0 && target > arr[j - 1]) {
count++;
arr[j] = arr[j - 1];
j--;
}
arr[j] = target;
}
for (int i = 0; i < arr.length; i++) {
System.out.print(", " + arr[i]);
}
System.out.println(" :Count = " + count);
}
归并排序
一:介绍
归并排序大多用于两个有序序列合并排序,他与上面几种排序具有明显的优势,冒泡,插入,选择要用O(N2)时间,而归并排序只需要O(N*logN)时间,比如:N如果是10000,N平方就是100000000,而N(N*logN)只是40000,如果为这么多数据排序归并需要40s的话,插入则会需要将近28小时,归并排序的劣势是需要额外创建一个总大小的序列集合来存储排序好后的数据。
二:概念
两个集合序列循环比较,大(小)的数据先填充到新序列中,循环完毕后继续循环多余未比较的数据填充到新序列后面的位置中,需要注意的是归并排序只适用与两个有序的序列集合,否则会排序失败。
三:O复杂度
O(N*logN)
四:代码
public static void guibinSort() {
int[] arrayA = { 23, 47, 81, 95 };
int[] arrayB = { 7, 14, 39, 55, 62, 74 };
int[] arrayC = new int[10];
int indexA = 0, indexB = 0, indexC = 0;
while (indexA < arrayA.length && indexB < arrayB.length) {
if (arrayA[indexA] < arrayB[indexB]) {
arrayC[indexC++] = arrayA[indexA++];
} else {
arrayC[indexC++] = arrayB[indexB++];
}
}
while (indexA < arrayA.length) {
arrayC[indexC++] = arrayA[indexA++];
}
while (indexB < arrayB.length) {
arrayC[indexC++] = arrayB[indexB++];
}
for (int k = 0; k < arrayC.length; k++) {
System.out.print(", " + arrayC[k]);
}
}
未完待续