JAVA的六大经典算法,代码案例简化分析

Posted y_keven

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JAVA的六大经典算法,代码案例简化分析相关的知识,希望对你有一定的参考价值。

   java八大经典算法:冒泡、选择、快速、插入、希尔、堆、归并、基数

1.算法实现类

package com.algorithm;

/**
 * 
 * @Title: BubbleSort.java
 * @Copyright: Copyright (c) 2005
 * @Description: <br>
 * <br>
 *               JAVA六大经典算法<br>
 *               冒泡、选择、快速、插入、希尔、堆
 * @Created on 2015年6月29日 下午12:48:14
 * @author yangkai
 */
public class AlgorithmClassic 

    /**
     * 冒泡排序
     * 
     * @return
     */
    public static int[] sortBubble(int[] datas) 
        for (int i = 0; i < datas.length - 1; i++) 
            for (int j = 0; j < datas.length - 1 - i; j++) 
                if (datas[j] > datas[j + 1])
                    AlgorithmUtil.swap(datas, j, j + 1);
            
        
        return datas;
    

    /**
     * 选择排序
     * 
     * @return
     */
    public static int[] sortSelect(int[] datas) 
        for (int i = 0; i < datas.length; i++) 
            int index = i;
            for (int j = i + 1; j < datas.length; j++) 
                if (datas[j] < datas[index])
                    index = j;
            
            if (i != index)
                AlgorithmUtil.swap(datas, i, index);
        
        return datas;
    

    /**
     * 插入排序法
     * 
     * @param datas
     */
    public static int[] sortInsert(int[] datas) 
        for (int i = 1; i < datas.length; i++) 
            int j = i - 1;
            AlgorithmUtil.temp = datas[i];
            for (; j >= 0 && AlgorithmUtil.temp < datas[j]; j--) 
                datas[j + 1] = datas[j];
            
            datas[j + 1] = AlgorithmUtil.temp;
        
        return datas;
    

    /**
     * 快速排序;分割数组
     * 
     * @param datas
     */
    public static int QuickPartition(int[] datas, int left, int right) 
        int pivot = datas[left];
        while (left < right) 
            while (left < right && datas[right] >= pivot)
                --right;
            datas[left] = datas[right]; // 将比枢轴小的元素移到低端,此时right位相当于空,等待低位比pivotkey大的数补上
            while (left < right && datas[left] <= pivot)
                ++left;
            datas[right] = datas[left]; // 将比枢轴大的元素移到高端,此时left位相当于空,等待高位比pivotkey小的数补上
        
        datas[left] = pivot; // 当left == right,完成一趟快速排序,此时left位相当于空,等待pivotkey补上
        return left;
    

    /**
     * 快速排序;递归返回数组
     * 
     * @param datas
     */
    public static int[] sortQuick(int[] datas, int left, int right) 
        if (left < right) 
            int data = QuickPartition(datas, left, right);
            sortQuick(datas, left, data - 1);
            sortQuick(datas, data + 1, right);
        
        return datas;
    



2.算法工具类

package com.algorithm;

public class AlgorithmUtil 

    public static int temp,index = 0;

    /**
     * 临时值交换
     * 
     * @param datas
     *            数组
     * @param i
     * @param j
     */
    public static void swap(int[] datas, int i, int j) 
        temp = datas[i];
        datas[i] = datas[j];
        datas[j] = temp;
    

    /**
     * 扩充数组长度
     * 
     * @param datas
     * @param value
     * @return
     */
    public static int[] expandArray(int[] datas, int value) 
        if (datas.length <= index) 
            int[] arrays = new int[datas.length * 2];
            System.arraycopy(datas, 0, arrays, 0, datas.length);
            datas = arrays;
        
        datas[index] = value;
        index++;
        return datas;
    

3.重点算法介绍

   快速排序是所有排序算法中效率最高最快的算法,这里重点介绍一下他的实现原理;

  快速排序的基本思想

         通过一趟排序将待排序记录分割成独立的两部分,其中一部分记录的关键字均比另一部分关键字小,则分别对这两部分继续进行排序,直到整个序列有序。

资料一:

先看一下这幅图:


    把整个序列看做一个数组,把第零个位置看做中轴,和最后一个比,如果比它小交换,比它大不做任何处理;交换了以后再和小的那端比,比它小不交换,比他大交换。这样循环往复,一趟排序完成,左边就是比中轴小的,右边就是比中轴大的,然后再用分治法,分别对这两个独立的数组进行排序。

资料二:

  快速排序法事应用最广泛的排序算法之一,最佳情况下时间复杂度是 O(nlogn)。但是 最坏情况下可能达到 O(n^2)。说明快速排序达到最坏情况的原因。并提出改善方案并实现 之。

答:

改进方案:改进选取枢轴的方法

1、选取随机数作为枢轴。

但是随机数的生成本身是一种代价,根本减少不了算法其余部分的平均运行时间。

2、使用左端,右端和中心的中值做为枢轴元。

经验得知,选取左端,右端,中心元素的中值会减少了快排大约 14%的比较。

3、每次选取数据集中的中位数做枢轴。

选取中位数的可以在 O(n)时间内完成。(证明见《算法导论(第二版) 》) P111 第九章中位数

和顺序统计学:在平均情况下,任何顺序统计量(特别是中位数)都可以在线性时间内得到。

快排的分割策略:

第一步是通过将枢轴元与最后一个元素交换使得枢轴元离开要被分割的数据段;i 从第一个

元素开始而 j 从倒数第二个元素开始。当 i 在 j 左边时,我们将 i 右移,移过那些小于枢轴

元的元素,并将 j 左移,移过那些大于枢轴元的元素。当 i 和 j 停止时,i 指向的是大元素,

j指向的是小元素。如果 i 在 j 左边,那么将这两个元素互换。 如果此时 i 和 j 已经交错即 i>j

所以不交换。此时把枢轴元与 i 所指的元素交换。

实例演示:

 

 

 

4.网上一些关于java算法不错的文章

http://www.cnblogs.com/liuling/p/2013-7-24-01.html

http://android.blog.51cto.com/268543/130450/

http://blog.csdn.net/hguisu/article/details/7776068



以上是关于JAVA的六大经典算法,代码案例简化分析的主要内容,如果未能解决你的问题,请参考以下文章

Java经典算法案例

java贪心算法经典案例之项目利润最大问题

MapReduce经典案例—TopN

Java开发经典实战!java代码编译过程

MapReduce经典案例—数据去重

[架构之路-36]:目标系统 - 系统软件 - Linux OS硬件驱动程序架构中隐藏的六大“分离”的思想与主要的驱动程序框架案例分析