Java基础之八大排序算法

前言

关系

复杂度

一、直接插入排序

基本思想

将新的数据插入已经排好的数据列中。

将第一个和第二个数排序,构成有序数列

然后将第三个数插进去,构成新的有序数列,后面的数重复这个步骤

算法描述

1、设定插入的次数,即是循环次数,for(int i=1;i<length;i++),1个数的那次不用插入。

2、设定插入的数和得到的已经排好的序列的最后一个数,insertNum和j=i-1。

3、从最后一个数向前开始循环,如果插入数小于当前数就将当前数向前移动一位

4、将当前位置放置到空的位置,即j+1。

代码实现

public class Demo01 {
    public static void main(String[] args) {
        int [] data = {2,1,41,21,14,33,5};
        int temp; //要插入的数
        for (int i = 1; i < data.length; i++) {  // 插入的次数
            temp = data[i]; //要插入的数
            int j  = i-1;   //已经排好的数字
            while (j>=0&&data[j]>temp){ //判断后一个数,将大于要插入的数向后移动一格
                data[j+1] =data[j]; //元素移动一格
                j--;
            }
            data[j+1]=temp;     //将要插入的数字放入1插入的位置
        }
        for (int i = 0; i < data.length; i++) {
            System.out.print(data[i]+" ");
        }
    }
}

二、希尔排序

基本思想

对于直接插入的数,数据量巨大:

1.将数的个数设置为n,取奇数k = n/2,将下标的差值k的数分为一组,构成有序数列。

2.再取k = k/2,将下标差值为k的数构成一组,构成有序数列,

3.重复第二步,直到k=1执行简单的插入排序

算法描述

1.首先确定分组的数字

2.然后对组中的数字进行插入排序

3.然后将length/2,重复1,2步骤。直到length=0为止。

代码实现

public class Demo02 {
    public static void main(String[] args) {
        int [] data = {2,5,14,34,12,4,87,21,1,6};
        int d = data.length;
        while (d!=0){
            d = d/2;
            for (int x = 0; x < d; x++) {
                for (int i = d+x; i < data.length; i += d) {
                    int j = i - d;      //j为有序序列最后一位的位数
                    int temp = data[i]; //要插入的元素
                    for (;j>=0&&temp < data[j]; j -=d){
                        data[j+d]=data[j]; //向后移动d位
                    }
                    data[j+d] = temp;
                }
            }
        }
        for (int i = 0; i < data.length; i++) {
            System.out.print(data[i]+" ");
        }

    }
}

三、简单选择排序

基本思想

常用于取序列数中最大最小的几棵树

(如果每次比较都交换,那么就是交换排序;如果每次比较完一个循环再交换,就是简单选择排序。)

1.遍历整个序列,将最小的数放在最前面

2.遍历剩余的序列,将最小的数字放在最前面

3.重复步骤2,知道剩余最后一个数字。

算法描述

1.首先确定循环次数,并且记住当前的位置和当前数字

2.将当前位置后面的所有数字和当前位置的数字作比较,小数赋值给key,并记住小值的位置

3.比对完成后,将最小的值和第一个数的值交换

4.重复2,3步骤

代码实现

public class Demo03 {
    public static void main(String[] args) {
        int[] data = {2,6,123,56,23,1};
        for (int i = 0; i < data.length; i++) { //循环次数
            int key = data[i];//最小值
            int position=i;  //当前位置
            for (int j = i+1; j < data.length; j++) {//选出最小值
                if(data[j]<key){
                    key = data[j];
                    position =j;
                }
            }
            data[position] = data[i];//交换位置
            data[i] = key;
        }
        for (int i = 0; i < data.length; i++) {
            System.out.print(data[i]+" ");
        }
    }
}

四、堆排序

基本思想:

对简单选择排序的优化

1.将序列构建为大顶堆

2.将根节点与最后一个节点兑换,然后断开最后一个节点

3.重复一二步骤,直到所有节点断开

代码实现:

public class Demo04 {
    public static void main(String[] args) {
        int []data = {21,13,3,2,1,23,11,25};
        heapsort(data);
    }
    public static void heapsort(int a[]){
        System.out.println("开始排序");
        int arrayLength = a.length;
        for (int i = 0; i < arrayLength-1; i++) {
            buildMaxHeap(a,arrayLength-1-i);
            swap(a,0,arrayLength-1-i);
            System.out.println(Arrays.toString(a));
        }
    }
    private static void swap(int[] data, int i, int j) {
        // TODO Auto-generated method stub
        int tmp=data[i];
        data[i]=data[j];
        data[j]=tmp;
    }

    public static void buildMaxHeap(int[] data,int lastIndex){
        //从lastIndex处节点(最后一个节点)的父节点开始
        for (int i = (lastIndex-1)/2;i>=0;i--){
            //k 保存当前判断的节点
            int k = i;
//            如果当前k节点存在子节点
            while (k*2+1<=lastIndex){
//                k节点的左子节点的索引
                int biggerIndex = 2*k+1;
//                如果biggerIndex小于lastIndex,即biggerIndex+1代表的k节点的右子节点存在
                if (biggerIndex<lastIndex){
//                    如果右子节点的值较大
                    if(data[biggerIndex]<data[biggerIndex+1]){
                        biggerIndex++;
                    }
                }
//                如果k节点的值小于其较大的子节点的值
                if (data[k]<data[biggerIndex]){
                    swap(data,k,biggerIndex);
                    k = biggerIndex;
                }else {
                    break;
                }
            }
        }
    }
}

五、冒泡排序

基本思想

1.将序列中所有的元素两两比较

2.将剩余序列的所有元素两两比较,将最大的放到最后面

3.重复第二步,知道最后一个数

算法描述

1.设置循环次数

2.设置比较的位数和结束的位数

3.两两比较,将最小的放到前面去

4.重复2,3步骤,直到循环结束

代码实现

public class Demo05 {
    public static void main(String[] args) {
        int[] data={1,34,31,2,65,87,255,8,33,64,3};
       int temp;
        for (int i = 0; i < data.length; i++) {
            for (int j = 0; j < data.length-i-1; j++) {
                if(data[j] > data[j+1]){
                    temp = data[j];
                    data[j] = data[j+1];
                    data[j+1] = temp;
                }
            }
        }
        for (int i = 0; i < data.length; i++) {
            System.out.print(data[i]+" ");
        }
    }
}

六、快速排序

基本思想

要求时间最快

1.选择第一个数作为P,小于P的放左边,大于p的放右边

2.递归将p的左边和右边的数按照步骤一进行,直到不能递归

代码实现

public class Demo06 {
    public static void main(String[] args) {
        int[] data = {5,33,22,11,23,2,32,12,21,10};
        quickSort(data,0,data.length-1);
        sorts(data);
    }
    public static void quickSort(int[] data,int L,int R){
        if(L < R){
//            先选择比较的基数
            int base = data[L];
            int temp;
            int left=L,right=R;
            do{
                while ((data[left] < base) && (left < R)){
                    left++;
                }
                while ((data[right]) > base &&(right > L)){
                    right--;
                }
                if (left <= right){
                    temp = data[left];
                    data[left] = data[right];
                    data[right] = temp;
                    left++;
                    right--;
                }
            }while (left <= right);
            if (L < right){
                quickSort(data,L,right);
            }
            if (R > left){
                quickSort(data,left,R);
            }
        }
    }
    public static void sorts(int[] data){
        for (int i = 0; i < data.length; i++) {
            if (i == data.length-1){
                System.out.print(data[i]);
            }else {
                System.out.print(data[i]+",");
            }

        }
    }
}

七、归并排序

基本思想

速度仅次于快排,内存少的时候使用,可以进行并行运算的时候使用。

1.选择相邻两个数组成的有序序列

2.选择相邻的两个有序序列组成的一个有序序列

3.重复步骤二,直到组成一个有序序列

public class Demo0701 {
    public static void main(String[] args) {
        int[] arr = {12,34,3,2,13,43,34,25,83};
        mSort(arr, 0, arr.length-1);
        sorts(arr);
    }

    /**
     * 递归分治
     * @param arr 待排数组
     * @param left 左指针
     * @param right 右指针
     */
    public static void mSort(int[] arr, int left, int right) {
        if(left >= right)
            return ;
        int mid = (left + right) / 2;

        mSort(arr, left, mid); //递归排序左边
        mSort(arr, mid+1, right); //递归排序右边
        merge(arr, left, mid, right); //合并
    }

    /**
     * 合并两个有序数组
     * @param arr 待合并数组
     * @param left 左指针
     * @param mid 中间指针
     * @param right 右指针
     */
    public static void merge(int[] arr, int left, int mid, int right) {
        //[left, mid] [mid+1, right]
        int[] temp = new int[right - left + 1]; //中间数组
        int i = left;
        int j = mid + 1;
        int k = 0;

        //执行完这个while循环,相当于将两个子序列合并后重新进行了一次排序并将排序结果记录在了临时数组temp[k]中。
        // while走完后k的值等于数组的长度,i的值此时大于mid,j的值大于right
        while(i <= mid && j <= right) {
            if(arr[i] <= arr[j]) {
                temp[k++] = arr[i++];
            }
            else {
                temp[k++] = arr[j++];
            }
        }

        while(i <= mid) {
            temp[k++] = arr[i++];
        }

        while(j <= right) {
            temp[k++] = arr[j++];
        }

        //将有序的临时数组temp[k]一个一个赋值到原数组arr[]中
        for(int p=0; p<temp.length; p++) {
            arr[left + p] = temp[p];
        }
    }
    public static void sorts(int[] data){
        for (int i = 0; i < data.length; i++) {
            if (i == data.length-1){
                System.out.print(data[i]);
            }else {
                System.out.print(data[i]+",");
            }
        }
    }
}

八、基数排序(桶排序)

基本思想

用于大量数,很长数进行排列

1.将所有的数的个数取出来,按照个位数排序,构成序列

2.将新构成的所有数的十位数取出,按照十位数进行排序

代码实现

public class Demo08 {
    public static void main(String[] args) {
        int[] data = {12,34,3,2,13,43,34,25,83};
        if(data == null && data.length == 0)
            return ;

        int maxBit = getMaxBit(data);

        for(int i=1; i<=maxBit; i++) {

            List<List<Integer>> buf = distribute(data, i); //分配
            collecte(data, buf); //收集
        }
        new PrintSort(data);
    }

    /**
     * 分配
     * @param arr 待分配数组
     * @param iBit 要分配第几位
     * @return
     */
    public static List<List<Integer>> distribute(int[] arr, int iBit) {
        List<List<Integer>> buf = new ArrayList<List<Integer>>();
        for(int j=0; j<10; j++) {
            buf.add(new LinkedList<Integer>());
        }
        for(int i=0; i<arr.length; i++) {
            buf.get(getNBit(arr[i], iBit)).add(arr[i]);
        }
        return buf;
    }

    /**
     * 收集
     * @param arr 把分配的数据收集到arr中
     * @param buf
     */
    public static void collecte(int[] arr, List<List<Integer>> buf) {
        int k = 0;
        for(List<Integer> bucket : buf) {
            for(int ele : bucket) {
                arr[k++] = ele;
            }
        }

    }

    /**
     * 获取最大位数
     * @param
     * @return
     */
    public static int getMaxBit(int[] arr) {
        int max = Integer.MIN_VALUE;
        for(int ele : arr) {
            int len = (ele+"").length();
            if(len > max)
                max = len;
        }
        return max;
    }

    /**
     * 获取x的第n位,如果没有则为0.
     * @param x
     * @param n
     * @return
     */
    public static int getNBit(int x, int n) {
        String sx = x + "";
        if(sx.length() < n)
            return 0;
        else
            return sx.charAt(sx.length()-n) - '0';
    }
}

到此这篇关于Java基础之八大排序算法的文章就介绍到这了,更多相关java八大排序算法内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Java实现的计算稀疏矩阵余弦相似度示例

    本文实例讲述了Java实现的计算稀疏矩阵余弦相似度功能.分享给大家供大家参考,具体如下: import java.util.HashMap; public class MyUDF{ /** * UDF Evaluate接口 * * UDF在记录层面上是一对一,字段上是一对一或多对一. Evaluate方法在每条记录上被调用一次,输入为一个或多个字段,输出为一个字段 */ public Double evaluate(String a, String b) { // TODO: 请按需要修改参数和

  • java中gc算法实例用法

    在我们对gc中的算法有基本概念理解后,要把算法的理念实现还需要依托实际垃圾收集器的使用.因为光靠一些简单的原理不足以支撑整个程序的运行,在回收机制上有专门的收集器.下面我们就垃圾收集器的概念.使用注意事项.收集器图解进行介绍,然后带来两种常见的垃圾收集器供大家参考. 1.概念 垃圾收集器时之前列举的垃圾收集算法的具体实现. 2.注意事项 每一个回收器都存在Stop The World 的问题,只不过各个回收器在Stop The World 时间优化程度.算法的不同,可根据自身需求选择适合的回收器

  • java实现同态加密算法的实例代码

    什么是同态加密? 同态加密是上世纪七十年代就被提出的一个开放问题,旨在不暴露数据的情况下完成对数据的处理,关注的是数据处理安全. 想象一下这样一个场景,作为一名满怀理想的楼二代,你每天过着枯燥乏味的收租生活,希望摆脱世俗的枷锁.铜臭的苟且去追求诗与远方. 你需要雇一个代理人去承担收租的粗活,但又不希望其窥探你每月躺赚的收入.于是,你请高人打造了一套装备,既能保证代理人顺利完成收租,又不会泄露收入信息. 这套装备包括信封.胶水.皮夹和神奇剪刀,每一样东西都有奇特的功能: 信封一旦用胶水密封,只有神

  • java 实现KMP算法

    KMP算法是一种神奇的字符串匹配算法,在对 超长字符串 进行模板匹配的时候比暴力匹配法的效率会高不少.接下来我们从思路入手理解KMP算法. 在对字符串进行匹配的时候我们最容易想到的就是一个个匹配,类似下面这种: 换成Java代码就是: public static boolean bfSearch(String pattern,String txt){ if (txt.length() < pattern.length()) return false; for (int i = 0; i < t

  • 详解Java分布式系统中一致性哈希算法

    业务场景 近年来B2C.O2O等商业概念的提出和移动端的发展,使得分布式系统流行了起来.分布式系统相对于单系统,解决了流量大.系统高可用和高容错等问题.功能强大也意味着实现起来需要更多技术的支持.例如系统访问层的负载均衡,缓存层的多实例主从复制备份,数据层的分库分表等. 我们以负载均衡为例,常见的负载均衡方法有很多,但是它们的优缺点也都很明显: 随机访问策略.系统随机访问,缺点:可能造成服务器负载压力不均衡,俗话讲就是撑的撑死,饿的饿死. 轮询策略.请求均匀分配,如果服务器有性能差异,则无法实现

  • java算法之余弦相似度计算字符串相似率

    概述 功能需求:最近在做通过爬虫技术去爬取各大相关网站的新闻,储存到公司数据中.这里面就有一个技术点,就是如何保证你已爬取的新闻,再有相似的新闻 或者一样的新闻,那就不存储到数据库中.(因为有网站会去引用其它网站新闻,或者把其它网站新闻拿过来稍微改下内容就发布到自己网站中). 解析方案:最终就是采用余弦相似度算法,来计算两个新闻正文的相似度.现在自己写一篇博客总结下. 一.理论知识 先推荐一篇博客,对于余弦相似度算法的理论讲的比较清晰,我们也是按照这个方式来计算相似度的.网址:相似度算法之余弦相

  • java实现国产sm4加密算法

    前言 今天给大家带来一个国产SM4加密解密算法的java后端解决方案,代码完整,可以直接使用,希望给大家带来帮助,尤其是做政府系统的开发人员,可以直接应用到项目中进行加密解密. 画重点!是SM4哦,不是SM.哈哈,各位要在知识里遨游,不要想歪.正文开始~ 国产SM4加密解密算法概念介绍 SMS4算法是在国内广泛使用的WAPI无线网络标准中使用的加密算法,是一种32轮的迭代非平衡Feistel结构的分组加密算法,其密钥长度和分组长度均为128.SMS4算法的加解密过程中使用的算法是完全相同的,唯一

  • Java多种经典排序算法(含动态图)

    算法分析 一个排序算法的好坏,一般是通过下面几个关键信息来分析的,下面先介绍一下这几个关键信息,然后再将常见的排序算法的这些关键信息统计出来. 名词介绍 时间复杂度:指对数据操作的次数(或是简单的理解为某段代码的执行次数).举例:O(1):常数时间复杂度:O(log n):对数时间复杂度:O(n):线性时间复杂度. 空间复杂度:某段代码每次执行时需要开辟的内存大小. 内部排序:不依赖外部的空间,直接在数据内部进行排序: 外部排序:数据的排序,不能通过内部空间来完成,需要依赖外部空间. 稳定排序:

  • Java算法之时间复杂度和空间复杂度的概念和计算

    一.算法效率 算法效率分析分为两种:第一种是时间效率,第二种是空间效率.时间效率被称为时间复杂度,而空间效率被称作空间复杂度. 时间复杂度主要衡量的是一个算法的运行速度,而空间复杂度主要衡量一个算法所需要的额外空间. 在计算机发展的早期,计算机的存储容量很小.所以对空间复杂度很是在乎.但是经过计算机行业的迅速发展,计算机的存储容量已经达到了很高的程度.所以我们如今已经不需要再特别关注一个算法的空间复杂度.因为现在的内存不像以前那么贵,所以经常听到过牺牲空间来换取时间的说法 二.时间复杂度 2.1

  • Java基础之八大排序算法

    前言 关系 复杂度 一.直接插入排序 基本思想: 将新的数据插入已经排好的数据列中. 将第一个和第二个数排序,构成有序数列 然后将第三个数插进去,构成新的有序数列,后面的数重复这个步骤 算法描述 1.设定插入的次数,即是循环次数,for(int i=1;i<length;i++),1个数的那次不用插入. 2.设定插入的数和得到的已经排好的序列的最后一个数,insertNum和j=i-1. 3.从最后一个数向前开始循环,如果插入数小于当前数就将当前数向前移动一位 4.将当前位置放置到空的位置,即j

  • 必须知道的C语言八大排序算法(收藏)

    概述 排序有内部排序和外部排序,内部排序是数据记录在内存中进行排序,而外部排序是因排序的数据很大,一次不能容纳全部的排序记录,在排序过程中需要访问外存. 我们这里说说八大排序就是内部排序. 当n较大,则应采用时间复杂度为O(nlog2n)的排序方法:快速排序.堆排序或归并排序序. 快速排序:是目前基于比较的内部排序中被认为是最好的方法,当待排序的关键字是随机分布时,快速排序的平均时间最短: 1.插入排序-直接插入排序(Straight Insertion Sort) 基本思想: 将一个记录插入到

  • python实现八大排序算法(2)

    本文接上一篇博客python实现的八大排序算法part1,将继续使用python实现八大排序算法中的剩余四个:快速排序.堆排序.归并排序.基数排序 5.快速排序 快速排序是通常被认为在同数量级(O(nlog2n))的排序方法中平均性能最好的. 算法思想: 已知一组无序数据a[1].a[2].--a[n],需将其按升序排列.首先任取数据a[x]作为基准.比较a[x]与其它数据并排序,使a[x]排在数据的第k位,并且使a[1]~a[k-1]中的每一个数据<a[x],a[k+1]~a[n]中的每一个数

  • python实现八大排序算法(1)

    排序 排序是计算机内经常进行的一种操作,其目的是将一组"无序"的记录序列调整为"有序"的记录序列.分内部排序和外部排序.若整个排序过程不需要访问外存便能完成,则称此类排序问题为内部排序.反之,若参加排序的记录数量很大,整个序列的排序过程不可能完全在内存中完成,需要访问外存,则称此类排序问题为外部排序.内部排序的过程是一个逐步扩大记录的有序序列长度的过程. 看图使理解更清晰深刻: 假定在待排序的记录序列中,存在多个具有相同的关键字的记录,若经过排序,这些记录的相对次序

  • 八大排序算法的Python实现

    Python实现八大排序算法,具体内容如下 1.插入排序 描述 插入排序的基本操作就是将一个数据插入到已经排好序的有序数据中,从而得到一个新的.个数加一的有序数据,算法适用于少量数据的排序,时间复杂度为O(n^2).是稳定的排序方法.插入算法把要排序的数组分成两部分:第一部分包含了这个数组的所有元素,但将最后一个元素除外(让数组多一个空间才有插入的位置),而第二部分就只包含这一个元素(即待插入元素).在第一部分排序完成后,再将这个最后元素插入到已排好序的第一部分中. 代码实现 def inser

  • java实现的各种排序算法代码示例

    折半插入排序 折半插入排序是对直接插入排序的简单改进.此处介绍的折半插入,其实就是通过不断地折半来快速确定第i个元素的 插入位置,这实际上是一种查找算法:折半查找.Java的Arrays类里的binarySearch()方法,就是折半查找的实现,用 于从指定数组中查找指定元素,前提是该数组已经处于有序状态.与直接插入排序的效果相同,只是更快了一些,因 为折半插入排序可以更快地确定第i个元素的插入位置 代码: package interview; /** * @author Administrat

  • Java实现的各种排序算法(插入排序、选择排序算法、冒泡排序算法)

    一.插入排序算法实现java版本 public static int[] insert_sort(int[] a) { for (int i = 0; i < a.length; i++) { for(int j=i+1;j>0&&j<a.length;j--) { if(a[j]<a[j-1]) { int tmp = a[j]; //这样定义初始化逻辑上是可以的,j变量,每次tmp的值变化的 a[j] = a[j-1]; a[j-1] = tmp; } } }

  • Python实现八大排序算法

    如何用Python实现八大排序算法 1.插入排序 描述 插入排序的基本操作就是将一个数据插入到已经排好序的有序数据中,从而得到一个新的.个数加一的有序数据,算法适用于少量数据的排序,时间复杂度为 O(n^2).是稳定的排序方法.插入算法把要排序的数组分成两部分:第一部分包含了这个数组的所有元素,但将最后一个元素除外(让数组多一个空间才有插 入的位置),而第二部分就只包含这一个元素(即待插入元素).在第一部分排序完成后,再将这个最后元素插入到已排好序的第一部分中. 代码实现 def insert_

  • python八大排序算法速度实例对比

    这篇文章并不是介绍排序算法原理的,纯粹是想比较一下各种排序算法在真实场景下的运行速度. 算法由 Python 实现,可能会和其他语言有些区别,仅当参考就好. 测试的数据是自动生成的,以数组形式保存到文件中,保证数据源的一致性. 排序算法 直接插入排序 时间复杂度:O(n²) 空间复杂度:O(1) 稳定性:稳定 def insert_sort(array): for i in range(len(array)): for j in range(i): if array[i] < array[j]:

  • Java实现8种排序算法的示例代码

    冒泡排序 O(n2) 两个数比较大小,较大的数下沉,较小的数冒起来. public static void bubbleSort(int[] a) { //临时变量 int temp; //i是循环次数,也是冒泡的结果位置下标,5个数组循环5次 for (int i = 0; i < a.length; i++) { //从最后向前面两两对比,j是比较中下标大的值 for (int j = a.length - 1; j > i; j--) { //让小的数字排在前面 if (a[j] <

随机推荐