算法在JDK中的使用一

参考算法导论第三版,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有对红黑树算法的完整实现。 如果不用考虑红黑状态,这也是一个很好的二叉查找树的实现。



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值