Java常用的八种排序算法与代码实现

目录
  • 1.直接插入排序
  • 2.希尔排序
  • 3.简单选择排序
  • 4.堆排序
  • 5.冒泡排序
  • 6.快速排序
  • 7.归并排序
  • 8.基数排序

1.直接插入排序

经常碰到这样一类排序问题:把新的数据插入到已经排好的数据列中。

  • 将第一个数和第二个数排序,然后构成一个有序序列
  • 将第三个数插入进去,构成一个新的有序序列。
  • 对第四个数、第五个数……直到最后一个数,重复第二步。

如何写写成代码:

首先设定插入次数,即循环次数,for(int i=1;i<length;i++),1个数的那次不用插入。
设定插入数和得到已经排好序列的最后一个数的位数。insertNumj=i-1
从最后一个数开始向前循环,如果插入数小于当前数,就将当前数向后移动一位。
将当前数放置到空着的位置,即j+1。

代码实现如下:

public void insertSort(int[] a){
        int length=a.length;//数组长度,将这个提取出来是为了提高速度。
        int insertNum;//要插入的数
        for(int i=1;i<length;i++){//插入的次数
            insertNum=a[i];//要插入的数
            int j=i-1;//已经排序好的序列元素个数
            while(j>=0&&a[j]>insertNum){//序列从后到前循环,将大于insertNum的数向后移动一格
                a[j+1]=a[j];//元素移动一格
                j--;
            }
            a[j+1]=insertNum;//将需要插入的数放在要插入的位置。
        }
    }

2.希尔排序

对于直接插入排序问题,数据量巨大时。

  • 将数的个数设为n,取奇数k=n/2,将下标差值为k的书分为一组,构成有序序列。
  • 再取k=k/2 ,将下标差值为k的书分为一组,构成有序序列。
  • 重复第二步,直到k=1执行简单插入排序。

如何写成代码:

  • 首先确定分的组数。
  • 然后对组中元素进行插入排序。
  • 然后将length/2,重复1,2步,直到length=0为止。

代码实现如下:

public  void sheelSort(int[] a){
        int d  = a.length;
        while (d!=0) {
            d=d/2;
            for (int x = 0; x < d; x++) {//分的组数
                for (int i = x + d; i < a.length; i += d) {//组中的元素,从第二个数开始
                    int j = i - d;//j为有序序列最后一位的位数
                    int temp = a[i];//要插入的元素
                    for (; j >= 0 && temp < a[j]; j -= d) {//从后往前遍历。
                        a[j + d] = a[j];//向后移动d位
                    }
                    a[j + d] = temp;
                }
            }
        }
    }

3.简单选择排序

常用于取序列中最大最小的几个数时。

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

  • 遍历整个序列,将最小的数放在最前面。
  • 遍历剩下的序列,将最小的数放在最前面。
  • 重复第二步,直到只剩下一个数。

如何写成代码:

  • 首先确定循环次数,并且记住当前数字和当前位置。
  • 将当前位置后面所有的数与当前数字进行对比,小数赋值给key,并记住小数的位置。
  • 比对完成后,将最小的值与第一个数的值交换。
  • 重复2、3步。

代码实现如下:

public void selectSort(int[] a) {
        int length = a.length;
        for (int i = 0; i < length; i++) {//循环次数
            int key = a[i];
            int position=i;
            for (int j = i + 1; j < length; j++) {//选出最小的值和位置
                if (a[j] < key) {
                    key = a[j];
                    position = j;
                }
            }
            a[position]=a[i];//交换位置
            a[i]=key;
        }
    }

4.堆排序

对简单选择排序的优化。

  • 将序列构建成大顶堆。
  • 将根节点与最后一个节点交换,然后断开最后一个节点。
  • 重复第一、二步,直到所有节点断开。

代码实现如下:

public  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  void swap(int[] data, int i, int j) {
        int tmp=data[i];
        data[i]=data[j];
        data[j]=tmp;
    }
    //对data数组从0到lastIndex建大顶堆
    private 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总是记录较大子节点的索引
                        biggerIndex++;
                    }
                }
                //如果k节点的值小于其较大的子节点的值
                if(data[k]<data[biggerIndex]){
                    //交换他们
                    swap(data,k,biggerIndex);
                    //将biggerIndex赋予k,开始while循环的下一次循环,重新保证k节点的值大于其左右子节点的值
                    k=biggerIndex;
                }else{
                    break;
                }
            }
        }
    }

5.冒泡排序

一般不用。

  • 将序列中所有元素两两比较,将最大的放在最后面。
  • 将剩余序列中所有元素两两比较,将最大的放在最后面。
  • 重复第二步,直到只剩下一个数。

如何写成代码:

  • 设置循环次数。
  • 设置开始比较的位数,和结束的位数。
  • 两两比较,将最小的放到前面去。
  • 重复2、3步,直到循环次数完毕。

代码实现如下:

public void bubbleSort(int[] a){
        int length=a.length;
        int temp;
        for(int i=0;i<a.length;i++){
            for(int j=0;j<a.length-i-1;j++){
                if(a[j]>a[j+1]){
                    temp=a[j];
                    a[j]=a[j+1];
                    a[j+1]=temp;
                }
            }
        }
    }

6.快速排序

要求时间最快时。

  • 选择第一个数为p,小于p的数放在左边,大于p的数放在右边。
  • 递归的将p左边和右边的数都按照第一步进行,直到不能递归。

代码实现如下:

public static void quickSort(int[] numbers, int start, int end) {
    if (start < end) {
        int base = numbers[start]; // 选定的基准值(第一个数值作为基准值)
        int temp; // 记录临时中间值
        int i = start, j = end;
        do {
            while ((numbers[i] < base) && (i < end))
                i++;
            while ((numbers[j] > base) && (j > start))
                j--;
            if (i <= j) {
                temp = numbers[i];
                numbers[i] = numbers[j];
                numbers[j] = temp;
                i++;
                j--;
            }
        } while (i <= j);
        if (start < j)
            quickSort(numbers, start, j);
        if (end > i)
            quickSort(numbers, i, end);
    }
}

7.归并排序

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

  • 选择相邻两个数组成一个有序序列。
  • 选择相邻的两个有序序列组成一个有序序列。
  • 重复第二步,直到全部组成一个有序序列。

代码实现如下:

public static void mergeSort(int[] numbers, int left, int right) {
    int t = 1;// 每组元素个数
    int size = right - left + 1;
    while (t < size) {
        int s = t;// 本次循环每组元素个数
        t = 2 * s;
        int i = left;
        while (i + (t - 1) < size) {
            merge(numbers, i, i + (s - 1), i + (t - 1));
            i += t;
        }
        if (i + (s - 1) < right)
            merge(numbers, i, i + (s - 1), right);
    }
}
private static void merge(int[] data, int p, int q, int r) {
    int[] B = new int[data.length];
    int s = p;
    int t = q + 1;
    int k = p;
    while (s <= q && t <= r) {
        if (data[s] <= data[t]) {
            B[k] = data[s];
            s++;
        } else {
            B[k] = data[t];
            t++;
        }
        k++;
    }
    if (s == q + 1)
        B[k++] = data[t++];
    else
        B[k++] = data[s++];
    for (int i = p; i <= r; i++)
        data[i] = B[i];
}

8.基数排序

用于大量数,很长的数进行排序时。

  • 将所有的数的个位数取出,按照个位数进行排序,构成一个序列。
  • 将新构成的所有的数的十位数取出,按照十位数进行排序,构成一个序列。

代码实现如下:

public void sort(int[] array) {
        //首先确定排序的趟数;
        int max = array[0];
        for (int i = 1; i < array.length; i++) {
            if (array[i] > max) {
                max = array[i];
            }
        }
        int time = 0;
        //判断位数;
        while (max > 0) {
            max /= 10;
            time++;
        }
        //建立10个队列;
        List<ArrayList> queue = new ArrayList<ArrayList>();
        for (int i = 0; i < 10; i++) {
            ArrayList<Integer> queue1 = new ArrayList<Integer>();
            queue.add(queue1);
        }
        //进行time次分配和收集;
        for (int i = 0; i < time; i++) {
            //分配数组元素;
            for (int j = 0; j < array.length; j++) {
                //得到数字的第time+1位数;
                int x = array[j] % (int) Math.pow(10, i + 1) / (int) Math.pow(10, i);
                ArrayList<Integer> queue2 = queue.get(x);
                queue2.add(array[j]);
                queue.set(x, queue2);
            }
            int count = 0;//元素计数器;
            //收集队列元素;
            for (int k = 0; k < 10; k++) {
                while (queue.get(k).size() > 0) {
                    ArrayList<Integer> queue3 = queue.get(k);
                    array[count] = queue3.get(0);
                    queue3.remove(0);
                    count++;
                }
            }
        }
    }

到此这篇关于Java常用的八种排序算法与代码实现的文章就介绍到这了,更多相关Java八种排序算法与代码实现内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • 新手初学Java常见排序算法

    目录 1.冒泡排序 2.选择排序 3.简单插入排序 4.希尔排序 5.归并排序 6.快速排序 总结 1.冒泡排序 排序原理:相邻两个元素比较,如果前者比后者大,则交换两个元素.每执行一次,都会确定一个最大值,其位置就固定了,下一次就不需要再参与排序了. 时间复杂度:O(n^2) 稳定性:稳定 具体实现: public class Bubble { /** * 对数组a中的元素进行排序 */ public static void sort(Comparable[] a){ //每冒泡一次,参与冒泡

  • Java数据结构之基于比较的排序算法基本原理及具体实现

    目录 1. 七大基于比较的排序-总览 1.1常见基于比较的排序分类 1.2时间复杂度,空间复杂度以及稳定性. 2.直接插入排序 2.1 直接插入排序的基本思想 2.2 直接插入排序动画演示 2.3 代码示例 2.4 时间复杂度,空间复杂度以及稳定性 3. 希尔排序 3.1 算法思想 3.2 图片演示 3.3 代码示例 3.4 时间复杂度,空间复杂度以及稳定性 4.选择排序 4.1 算法思想 4.2 动画演示 4.3 代码示例 4.4 时间复杂度,空间复杂度以及稳定性 5.堆排序 5.1 算法思想

  • 优化常见的java排序算法

    目录 冒泡排序 原始的写法 优化一 优化二 选择排序 方法一 方法二 堆排序 建大堆来实现堆排 建小堆来实现堆排 插入排序 实现 优化一 优化二 归并排序 递归实现归并排序 优化 来看O(n)的排序 当然除了基于比较的排序.还有基于非比较的排序. 总结 冒泡排序 冒泡排序的思想: 每次让当前的元素和它的下一个元素比较大小.如果前一个的元素大于后一个元素的话,交换两个元素. 这样的话经历一次扫描之后能确保数组的最后一个元素一定是数组中最大的元素. 那么下次扫描的长度比上次少一个.因为数组的最后一个

  • Java常用的八种排序算法与代码实现

    目录 1.直接插入排序 2.希尔排序 3.简单选择排序 4.堆排序 5.冒泡排序 6.快速排序 7.归并排序 8.基数排序 1.直接插入排序 经常碰到这样一类排序问题:把新的数据插入到已经排好的数据列中. 将第一个数和第二个数排序,然后构成一个有序序列 将第三个数插入进去,构成一个新的有序序列. 对第四个数.第五个数--直到最后一个数,重复第二步. 如何写写成代码: 首先设定插入次数,即循环次数,for(int i=1;i<length;i++),1个数的那次不用插入. 设定插入数和得到已经排好

  • Java常用的八种排序算法及代码实现+图解

    目录 1.冒泡排序 冒泡排序法的思路 2.冒泡排序法的代码实现 3.冒泡排序法优化 4.选择排序 5.插入排序 插入排序的思路 经典的排序算法有八种,分别为: 冒泡排序 选择排序 插入排序 归并排序 希尔排序 快速排序 堆排序 基数排序 其中冒泡排序.选择排序.插入排序称为三大基本排序. 虽然这三大基本排序算法时间复杂度都是O(n2),但是其实细细讨论之下,还是有各自的特点的. 1.冒泡排序 冒泡排序法的思路 基本思路: 假设我们需要进行升序排列 进行N轮的比较,每一轮将相邻的两个元素依次比较,

  • python如何实现常用的五种排序算法详解

    一.冒泡排序 原理: 比较相邻的元素.如果第一个比第二个大就交换他们两个 每一对相邻元素做同样的工作,直到结尾最后一对 每个元素都重复以上步骤,除了最后一个 第一步: 将乱序中的最大值找出,逐一移到序列最后的位置 alist = [3, 5, 9, 2, 1, 7, 8, 6, 4] def bubble_sort(alist): # 找最大值的方式是通过对列表中的元素进行两两比较,值大的元素逐步向后移动 # 序列中有n个元素,两两比较的话,需要比较n-1次 for i in range(len

  • Java中常用的6种排序算法详细分解

    排序算法很多地方都会用到,近期又重新看了一遍算法,并自己简单地实现了一遍,特此记录下来,为以后复习留点材料. 废话不多说,下面逐一看看经典的排序算法: 1. 选择排序 选择排序的基本思想是遍历数组的过程中,以 i 代表当前需要排序的序号,则需要在剩余的 [i-n-1] 中找出其中的最小值,然后将找到的最小值与 i 指向的值进行交换.因为每一趟确定元素的过程中都会有一个选择最大值的子流程,所以人们形象地称之为选择排序.举个实例来看看: 初始: [38, 17, 16, 16, 7, 31, 39,

  • 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] <

  • Java中七种排序算法总结分析

    目录 前言:对文章出现的一些名词进行解释 一.插入排序 1.基本思想 2.直接插入排序 3.希尔排序(缩小增量排序) 二.选择排序 1.基本思想 2.直接选择排序 3.堆排序 三.交换排序 1.基本思想 2.冒泡排序 3.快速排序(递归与非递归) 1.Hoare版 2.挖坑法 3.前后标记法(难理解) 4.快速排序优化 5.快速排序非递归 6.相关特性总结 四.归并排序(递归与非递归) 前言:对文章出现的一些名词进行解释 排序: 使一串记录,按照其中的某个或某些关键字的大小,递增或者递减排列起来

  • 常用的C语言排序算法(两种)

    1. 要求输入10个整数,从大到小排序输出 输入:2 0 3 -4 8 9 5 1 7 6 输出:9 8 7 6 5 3 2 1 0 -4 解决方法:选择排序法 实现代码如下: #include <stdio.h> int main(int argc, const char * argv[]) { int num[10],i,j,k,l,temp; //用一个数组保存输入的数据 for(i=0;i<=9;i++) { scanf("%d",&num[i]);

  • PHP四种排序算法实现及效率分析【冒泡排序,插入排序,选择排序和快速排序】

    本文实例讲述了PHP四种排序算法实现及效率分析.分享给大家供大家参考,具体如下: PHP的四种基本排序算法为:冒泡排序.插入排序.选择排序和快速排序. 下面是我整理出来的算法代码: 1. 冒泡排序: 思路:对数组进行多轮冒泡,每一轮对数组中的元素两两比较,调整位置,冒出一个最大的数来. //简单版: function bubbleSort($arr) { $n = count($arr); for($i=1;$i<$n;$i++) { //冒泡的轮数(最多$n-1轮) for($j=0;$j<

  • c语言5个常用的排序算法实例代码

    1.插入排序 基本思想:插入排序就是每一步都将一个待排数据按其大小插入到已经排序的数据中的适当位置,直到全部插入完毕. void insertSort(vector<int>& nums) { int k = 0; for (int i = 0; i < nums.size(); ++i) { int temp = nums[i]; int j = i; for (; j > 0 && temp < nums[j-1]; --j) nums[j] =

  • Java的Arrays.sort()方法排序算法实例分析

    暂时网上看过很多JDK8中Arrays.sort的底层原理,有些说是插入排序,有些说是归并排序,也有说大于域值用计数排序法,否则就使用插入排序...其实不全对.让我们分析个究竟: // Use Quicksort on small arrays if (right - left < QUICKSORT_THRESHOLD) { //QUICKSORT_THRESHOLD = 286 sort(a, left, right, true); return; } 数组一进来,会碰到第一个阀值QUICK

随机推荐