数组的排序算法(JDK1.8)
数组
数组与其他容器的区别有三大方面:效率,类型和保存基本类型的能力。在Java中,数组是一种效率最高的存储和随机访问对象引用序列的方式。数组是一个简单的线序序列。数组的优点是访问元素的速度会非常快,但代价是一旦确定了容器的大小,便不可再改变。可能有人会建议使用ArrayList,因为它可以通过创建新的实例然后把旧的实例传进去,从而达到扩容。就像本人上一篇文章关于StringBuilder数据结构一样,但我们要知道它们的底层都是基于数组的。所以说List之前我们会先说到数组。
无论使用哪种类型的数组,数组标识符其实只是一个引用,指向堆中创建的一个真实对象。这个对象用于保存指向其他对象的引用。可以作为数组初始化语法一部分隐式地创建此对象,或者用new表达式显式的创建。不管是基本数据类型的数组还是引用数据类型的数组在使用上基本都相同
在C/C++中,你无法返回一个数组,只能返回指向数组的指针,但是这样子会造成数组的生命周期变得困难。容易产生内存泄漏问题。而在Java中却可以直接返回一个数组。需要的时候它存在,不需要时垃圾处理器会清理掉它
Arrays
Arrays是专门用来操作数组的一个工具类。由于我们使用数组的时候,会经常需要一些对里面元素产生变更的操作。为了省的程序员去重复写算法,所以Java里面已经提供好了工具类。在Arrays类中的方法基本上都是静态的,因此我们不需要去new一个对象。
sort方法
byte型数组
Arrays.sort方法可以根据数组的大小和类型从而实现不同的排序。当数组的类型为byte数组时的长度小于29的时候,则会使用插入排序
for (int i = left, j = i; i < right; j = ++i) {
byte ai = a[i + 1];
while (ai < a[j]) {
a[j + 1] = a[j];
if (j-- == left) {
break;
}
}
a[j + 1] = ai;
}
大于29的时候则使用计数排序
int[] count = new int[NUM_BYTE_VALUES];
for (int i = left - 1; ++i <= right;
count[a[i] - Byte.MIN_VALUE]++
);
for (int i = NUM_BYTE_VALUES, k = right + 1; k > left; ) {
while (count[--i] == 0);
byte value = (byte) (i + Byte.MIN_VALUE);
int s = count[i];
do {
a[--k] = value;
} while (--s > 0);
}
int型数组
当数组的类型是int的时候,如果数组的长度小于47则会使用插入排序
if (leftmost) {
for (int i = left, j = i; i < right; j = ++i) {
int ai = a[i + 1];
while (ai < a[j]) {
a[j + 1] = a[j];
if (j-- == left) {
break;
}
}
a[j + 1] = ai;
}
如果大于47小于286,则会使用快速排序
do {
if (left >= right) {
return;
}
} while (a[++left] >= a[left - 1]);
for (int k = left; ++left <= right; k = ++left) {
int a1 = a[k], a2 = a[left];
if (a1 < a2) {
a2 = a1; a1 = a[left];
}
while (a1 < a[--k]) {
a[k + 2] = a[k];
}
a[++k + 1] = a1;
while (a2 < a[--k]) {
a[k + 1] = a[k];
}
a[k + 1] = a2;
}
int last = a[right];
while (last < a[--right]) {
a[right + 1] = a[right];
}
a[right + 1] = last;
}
当长度大于286的时候则会使用归并排序
int[] run = new int[MAX_RUN_COUNT + 1];
int count = 0; run[0] = left;
for (int k = left; k < right; run[count]<