您的位置:首页 > 编程语言 > Java开发

算法在JDK中的使用一

2014-01-17 09:46 120 查看
参考算法导论第三版,JDK1.6

排序

插入排序

在下面的快速排序中,当数组大小小于7时,使用的就是插入排序,代码好简洁。

归并排序

java.util包中Arrays工具类对Object类型的数组进行排序时,使用的是归并排序,原文是这样说的:"This sort is guaranteed to be stable: equal elements will not be reordered as a result of the sort.The sorting algorithm is a
modified mergesort (in which the merge is omitted if the highest element in the low sublist is less than the lowest element in the high sublist). This algorithm offers guaranteed n*log(n) performance. "此算法被认为是稳定的,相等的元素在排序后的结果中不会改变原来的顺序。这是一个修改过的归并排序算法(如果在低序列中的最大元素小于高序列中的最小元素则归并过程会被略去),此算法的性能为nlogn。
以mergeSort(aux, a, 0, a.length, 0)进行分析,aux是a数组的克隆数组,原码如下,分析在代码注释中:
private static void mergeSort(Object[] src, Object[] dest, int low, int high, int off) {
int length = high - low;
// Insertion sort on smallest arrays
//同样的,当数组长度小于7时,使用插入排序
//有一个有趣的现象 :) 即使在JDK中也有风格不统一的地方
//如1 快速排序中变量是len 这里的是length
//如2 快速排序中直接使用的是7,这里使用的是静态变量
if (length < INSERTIONSORT_THRESHOLD) {
for (int i = low; i < high; i++)
for (int j = i; j > low && ((Comparable) dest[j - 1]).compareTo(dest[j]) > 0; j--)
swap(dest, j, j - 1);
return;
}
// Recursively sort halves of dest into src
//递归把dest排序放入src
int destLow = low;
int destHigh = high;
low += off;
high += off;
int mid = (low + high) >>> 1;
mergeSort(dest, src, low, mid, -off);
mergeSort(dest, src, mid, high, -off);
// If list is already sorted, just copy from src to dest.  This is an
// optimization that results in faster sorts for nearly ordered lists.
// 如果列表已经排序好了,仅把src拷贝到dest里,在列表已经排序好的情
//况下这会加快排序
if (((Comparable) src[mid - 1]).compareTo(src[mid]) <= 0) {
System.arraycopy(src, low, dest, destLow, length);
return;
}
// Merge sorted halves (now in src) into dest
//归并过程
for (int i = destLow, p = low, q = mid; i < destHigh; i++) {
if (q >= high || p < mid && ((Comparable) src[p]).compareTo(src[q]) <= 0)
dest[i] = src[p++];
else
dest[i] = src[q++];
}
}

堆排序


快速排序

java.util包中的Arrays工具类用来对非Object类型的数组排序用的是快速排序,原文是这样说的:"The sorting algorithm is a tuned quicksort.This algorithm offers n*log(n) performance on many data sets ,that cause other quicksorts
to degrade to quadratic performance." 这是一个调整过的快速排序,对许多输入数据都能达到nlogn的性能,在一些性况下性能会降到n^2(输入数据为已排好的情况), 以sort1(long x[], int 0, int x.lenth)为例进行说明,原码如下,分析在代码的注释中:
private static void sort1(long x[], int off, int len) {
// Insertion sort on smallest arrays
//算法导论中也讲过,在进行排序递归的过程中,如果要排序的数据量已经很小了
//可以使用插入排序来提高性能,虽然没有测试过,但在JAVA中这个限度值给的是7
if (len < 7) {
for (int i = off; i < len + off; i++)
for (int j = i; j > off && x[j - 1] > x[j]; j--)
swap(x, j, j - 1);
return;
}
// Choose a partition element, v
//选择一个分区元素pivot,原则是能将原序列划分为长度并不多相等的两个子序列
//如果数组长度大于40,则选x[0],x[len/8],x[2*len/8],x[3*len/8],x[4*len/8],
//x[5*len/8],x[6*len/8],x[7*len/8],x[8*len/8]的中间值作为pivot
//如果数组长度小于40,则选x[0],x[len/2],x[len-1]的中间值作为pivot
int m = off + (len >> 1); // Small arrays, middle element
if (len > 7) {
int l = off;
int n = off + len - 1;
if (len > 40) { // Big arrays, pseudomedian of 9
int s = len / 8;
l = med3(x, l, l + s, l + 2 * s);
m = med3(x, m - s, m, m + s);
n = med3(x, n - 2 * s, n - s, n);
}
m = med3(x, l, m, n); // Mid-size, med of 3
}
long v = x[m];
// 余下的部分便是对数据进行划分,然后递归
int a = off, b = a, c = off + len - 1, d = c;
while (true) {
while (b <= c && x[b] <= v) {
if (x[b] == v)
swap(x, a++, b);
b++;
}
while (c >= b && x[c] >= v) {
if (x[c] == v)
swap(x, c, d--);
c--;
}
if (b > c)
break;
swap(x, b++, c--);
}
// Swap partition elements back to middle
int s, n = off + len;
s = Math.min(a - off, b - a);
vecswap(x, off, b - s, s);
s = Math.min(d - c, n - d - 1);
vecswap(x, b, n - s, s);
// Recursively sort non-partition-elements
if ((s = b - a) > 1)
sort1(x, off, s);
if ((s = d - c) > 1)
sort1(x, n - s, s);
}

数据结构

哈希表

二叉查找树

红黑树

这是一棵平衡的二叉查找树,在TreeMap有对红黑树算法的完整实现。如果不用考虑红黑状态,这也是一个很好的二叉查找树的实现。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: