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

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-11-06 18:37:25

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

Java中的经典算法之冒泡排序(Bubble Sort)

Java中的经典算法之冒泡排序(Bubble Sort) 原理:比较两个相邻的元素,将值大的元素交换至右端. 思路:依次比较相邻的两个数,将小数放在前面,大数放在后面.即在第一趟:首先比较第1个和第2个数,将小数放前,大数放后.然后比较第2个数和第3个数,将小数放前,大数放后,如此继续,直至比较最后两个数,将小数放前,大数放后.重复第一趟步骤,直至全部排序完成. 举例说明:要排序数组:int[] arr={6,3,8,2,9,1}; 第一趟排序: 第一次排序:6和3比较,6大于3,交换位置:  

Java中的经典算法之选择排序(SelectionSort)

Java中的经典算法之选择排序(SelectionSort) a) 原理:每一趟从待排序的记录中选出最小的元素,顺序放在已排好序的序列最后,直到全部记录排序完毕.也就是:每一趟在n-i+1(i=1,2,…n-1)个记录中选取关键字最小的记录作为有序序列中第i个记录.基于此思想的算法主要有简单选择排序.树型选择排序和堆排序.(这里只介绍常用的简单选择排序) b) 简单选择排序的基本思想:给定数组:int[] arr={里面n个数据}:第1趟排序,在待排序数据arr[1]~arr[n]中选出最小的数

java冒泡排序Bubble Sort算法代码

java冒泡排序Bubble Sort算法代码 下载代码地址:http://www.zuidaima.com/share/1550463269096448.htm package com.zuidaima.util; /** *冒泡排序 *@paramsrc待排序数组 *@author www.zuidaima.com */ void doBubbleSort(int[] src) { int len=src.length; for(int i=0;i<len;i++) { for(int j=

分享知识-快乐自己:Java中的经典算法之冒泡排序(Bubble Sort)

原理:比较两个相邻的元素,将值大的元素交换至右端. 思路:依次比较相邻的两个数,将小数放在前面,大数放在后面.即在第一趟:首先比较第1个和第2个数,将小数放前,大数放后.然后比较第2个数和第3个数,将小数放前,大数放后,如此继续,直至比较最后两个数,将小数放前,大数放后.重复第一趟步骤,直至全部排序完成. 第一趟比较完成后,最后一个数一定是数组中最大的一个数,所以第二趟比较的时候最后一个数不参与比较: 第二趟比较完成后,倒数第二个数也一定是数组中第二大的数,所以第三趟比较的时候最后两个数不参与比

java学习-4 经典算法

1.河内之塔.. 2.Algorithm Gossip: 费式数列. 3. 巴斯卡三角形 4.Algorithm Gossip: 三色棋 5.Algorithm Gossip: 老鼠走迷官(一) 6.Algorithm Gossip: 老鼠走迷官(二) 7.Algorithm Gossip: 骑士走棋盘 8.Algorithm Gossip: 八皇后 9.Algorithm Gossip: 八枚银币. 10.Algorithm Gossip: 生命游戏. 11.Algorithm Gossip:

Java经典算法案例

笔试中的编程题3 JAVA经典算法40例[程序1] 题目:古典问题:有一对兔子,从出生后第3个月起每个月都生一对兔子,小兔子长到第四个月后每个月又生一对兔子,假如兔子都不死,问每个月的兔子总数为多少? 1.程序分析: 兔子的规律为数列1,1,2,3,5,8,13,21.... public class exp2{public static void main(String args[]){int i=0;for(i=1;i<=20;i++)System.out.println(f(i));}pu

JAVA经典算法50题(转)

转载请注明出处:http://blog.csdn.net/l1028386804/article/details/51097928 JAVA经典算法50题 [程序1]   题目:古典问题:有一对兔子,从出生后第3个月起每个月都生一对兔子,小兔子长到第四个月后每个月又生一对兔子,假如兔子都不死,问每个月的兔子总数为多少?1.程序分析:兔子的规律为数列1,1,2,3,5,8,13,21.... [java] view plain copy public class Demo01 { public s

10道java经典算法题,每一题都能提升你的java水平!第二弹!

10道java经典算法! 持续更新java小知识,跪求关注,祝关注我的人都:身体健康,财源广进,福如东海,寿比南山,早生贵子,从不掉发! [程序1] 题目:有1.2.3.4个数字,能组成多少个互不相同且无重复数字的三位数?都是多少? 1.程序分析:可填在百位.十位.个位的数字都是1.2.3.4.组成所有的排列后再去   掉不满足条件的排列. public class Wanshu { public static void main(String[] args) { int i=0; int j=

java文本相似度计算(Levenshtein Distance算法(中文翻译:编辑距离算法))----代码和详解

算法代码实现: package com.util; public class SimFeatureUtil { private static int min(int one, int two, int three) { int min = one; if (two < min) { min = two; } if (three < min) { min = three; } return min; } public static int ld(String str1, String str2)