Sorting algorithm

排序算法

1. 冒泡排序
2. 选择排序
3. 插入排序
4. 希尔排序
5. 快速排序
6. 归并排序
7. 基数排序
8. 堆排序


冒泡排序

BubbleSort.java
package com.Taking.sort;

import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * Demo class
 * 冒泡排序
 *
 * @author Taking
 * @date 2020/5/20
 */
public class BubbleSort {
    public static void main(String[] args) {
        System.out.println("------------------------");
        System.out.println("*******冒泡排序算法*******");
        startTime();
        bubbleSort(randomArray());
        endTime();
        System.out.println("------------------------");
    }

    /**
     * 产生长度为100000的随机数组
     */
    public static int[] randomArray() {
        int[] arr = new int[100000];
        for (int i = 0; i < arr.length; i++) {
            //随机产生数据
            arr[i] = (int) (Math.random() * 100000);
        }
        return arr;
    }

    /**
     * 算法开始时时间
     */
    public static void startTime() {
        //开始时间
        Date date1 = new Date();
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String start = simpleDateFormat.format(date1);
        System.out.println("开始时间为:" + start);
    }

    /**
     * 算法结束时时间
     */
    public static void endTime() {
        //结束时间
        Date date2 = new Date();
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String end = simpleDateFormat.format(date2);
        System.out.println("结束时间为:" + end);
    }

    /**
     * 冒泡排序
     * O(n^2)
     * @param arr
     */
    public static void bubbleSort(int[] arr) {
        //临时变量
        int temp = 0;
        //标志
        boolean flag = false;
        for (int i = 0; i < arr.length - 1; i++) {
            for (int j = 0; j < arr.length - 1 - i; j++) {
                //如果逆序,交换位置
                if (arr[j] > arr[j + 1]) {
                    flag = true;
                    temp = arr[j];
                    arr[j] = arr[j + 1];
                    arr[j + 1] = temp;
                }
            }
            //无逆序,跳出循环
            if (!flag) {
                break;
            } else {
                flag = false;
            }
        }
    }
}

选择排序

SelectSort.java
package com.Taking.sort;

import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * Demo class
 * 选择排序
 *
 * @author Taking
 * @date 2020/5/20
 */
public class SelectSort {
    public static void main(String[] args) {
        System.out.println("------------------------");
        System.out.println("*******选择排序算法*******");
        startTime();
        selectSort(randomArray());
        endTime();
        System.out.println("------------------------");
    }

    /**
     * 产生长度为100000的随机数组
     */
    public static int[] randomArray() {
        int[] arr = new int[100000];
        for (int i = 0; i < arr.length; i++) {
            //随机产生数据
            arr[i] = (int) (Math.random() * 100000);
        }
        return arr;
    }

    /**
     * 算法开始时时间
     */
    public static void startTime() {
        //开始时间
        Date date1 = new Date();
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String start = simpleDateFormat.format(date1);
        System.out.println("开始时间为:" + start);
    }

    /**
     * 算法结束时时间
     */
    public static void endTime() {
        //结束时间
        Date date2 = new Date();
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String end = simpleDateFormat.format(date2);
        System.out.println("结束时间为:" + end);
    }

    /**
     * 选择排序
     * O(n^2)
     * @param arr
     */
    public static void selectSort(int[] arr) {
        for (int i = 0; i < arr.length - 1; i++) {
            //假设最小值的坐标为i
            int minIndex = i;
            //假设最小值为arr[i]
            int min = arr[i];
            for (int j = i + 1; j < arr.length; j++) {
                //若arr[j]小于min,则把下标赋值给minIndex,把值赋给min
                if (min > arr[j]) {
                    minIndex = j;
                    min = arr[j];
                }
            }
            //一趟比较结束,交换位置,确定最小数的位置
            arr[minIndex] = arr[i];
            arr[i] = min;
        }
    }
}

插入排序

InsertSort.java
package com.Taking.sort;

import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * Demo class
 * 插入排序
 *
 * @author Taking
 * @date 2020/5/20
 */
public class InsertSort {
    public static void main(String[] args) {
        System.out.println("------------------------");
        System.out.println("*******插入排序算法*******");
        startTime();
        insertSort(randomArray());
        endTime();
        System.out.println("------------------------");
    }

    /**
     * 产生长度为100000的随机数组
     */
    public static int[] randomArray() {
        int[] arr = new int[100000];
        for (int i = 0; i < arr.length; i++) {
            //随机产生数据
            arr[i] = (int) (Math.random() * 100000);
        }
        return arr;
    }

    /**
     * 算法开始时时间
     */
    public static void startTime() {
        //开始时间
        Date date1 = new Date();
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String start = simpleDateFormat.format(date1);
        System.out.println("开始时间为:" + start);
    }

    /**
     * 算法结束时时间
     */
    public static void endTime() {
        //结束时间
        Date date2 = new Date();
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String end = simpleDateFormat.format(date2);
        System.out.println("结束时间为:" + end);
    }

    /**
     * 插入排序
     * O(n^2)
     * @param arr
     */
    public static void insertSort(int[] arr) {
        // 定义待插入的变量,插入位置的索引
        int insertVal = 0;
        int insertIndex = 0;
        for(int i=0;i<arr.length-1;i++){
            //待插入的数赋值
            insertVal = arr[i+1];
            //与待插入的位置的数进行比较
            insertIndex = i;
            //进行判断:索引越界或者找到位置,跳出循环
            while(insertIndex>=0 && insertVal<arr[insertIndex]){
                arr[insertIndex+1] = arr[insertIndex];
                insertIndex--;
            }
            if(insertIndex+1 != i){
                arr[insertIndex+1] = insertVal;
            }
        }
    }
}

希尔排序

ShellSort.java
package com.Taking.sort;

import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * Demo class
 * 希尔排序
 * 
 * @author Taking
 * @date 2020/5/21
 */
public class ShellSort {
    public static void main(String[] args) {
        shellSort(randomArray());
        shellSort2(randomArray());
    }

    /**
     * 产生长度为100000的随机数组
     */
    public static int[] randomArray() {
        int[] arr = new int[100000];
        for (int i = 0; i < arr.length; i++) {
            //随机产生数据
            arr[i] = (int) (Math.random() * 100000);
        }
        return arr;
    }

    /**
     * 算法开始时时间
     */
    public static void startTime() {
        //开始时间
        Date date1 = new Date();
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String start = simpleDateFormat.format(date1);
        System.out.println("开始时间为:" + start);
    }

    /**
     * 算法结束时时间
     */
    public static void endTime() {
        //结束时间
        Date date2 = new Date();
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String end = simpleDateFormat.format(date2);
        System.out.println("结束时间为:" + end);
    }

    /**
     * 希尔排序
     * O(n^2*log(n))
     * @param arr
     */
    public static void shellSort(int[] arr) {
        System.out.println("------------------------");
        System.out.println("*******希尔排序算法(交换)*******");
        startTime();
        //临时变量
        int temp = 0;
        int count = 0;
        for(int gap = arr.length/2 ; gap>0 ; gap/=2){
            for(int i=gap; i<arr.length ; i++){
                for(int j=i-gap;j>=0;j-=gap){
                    if(arr[j]>arr[j+gap]){
                        temp = arr[j];
                        arr[j] =arr[j+gap];
                        arr[j+gap] = temp;
                    }
                }
            }
        }
        endTime();
        System.out.println("------------------------");
    }

    /**
     * 希尔排序
     * O(n*log(n))
     * @param arr
     */
    public static void shellSort2(int[] arr) {
        System.out.println("------------------------");
        System.out.println("*******希尔排序算法(移位)*******");
        startTime();
        //临时变量
        int temp=0;
        //分组
        for(int gap=arr.length/2;gap>0;gap/=2){
            for(int i=gap;i<arr.length;i++){
                int j=i;
                temp = arr[j];
                if(arr[j-gap]>arr[j]){

                    while(j-gap>=0 && temp < arr[j-gap]){
                        arr[j] = arr[j-gap];
                        j-=gap;
                    }
                    arr[j]=temp;
                }
            }
        }
        endTime();
        System.out.println("------------------------");
    }
}

快速排序

QuickSort.java
package com.Taking.sort;

import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * Demo class
 * 快速排序
 * 
 * @author Taking
 * @date 2020/5/21
 */
public class QuickSort {
    public static void main(String[] args) {
        System.out.println("------------------------");
        System.out.println("*******快速排序算法*******");
        startTime();
        quickSort(randomArray(), 0, randomArray().length - 1);
        endTime();
        System.out.println("------------------------");
    }

    /**
     * 产生长度为100000的随机数组
     */
    public static int[] randomArray() {
        int[] arr = new int[100000];
        for (int i = 0; i < arr.length; i++) {
            //随机产生数据
            arr[i] = (int) (Math.random() * 100000);
        }
        return arr;
    }

    /**
     * 算法开始时时间
     */
    public static void startTime() {
        //开始时间
        Date date1 = new Date();
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String start = simpleDateFormat.format(date1);
        System.out.println("开始时间为:" + start);
    }

    /**
     * 算法结束时时间
     */
    public static void endTime() {
        //结束时间
        Date date2 = new Date();
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String end = simpleDateFormat.format(date2);
        System.out.println("结束时间为:" + end);
    }

    /**
     * 快速排序
     * O(n^log(n))
     * @param arr
     * @param left
     * @param right
     */
    public static void quickSort(int[] arr, int left, int right) {
        //定义两个索引
        int l = left;
        int r = right;
        //中值赋值给pivot
        int pivot = arr[(left + right) / 2];
        int temp = pivot;
        while (l < r) {
            //中轴左边的数值小于中轴值,则右移,大于中轴值,跳出循环
            while (arr[l] < pivot) {
                l++;
            }
            //中轴右边的数值大于中轴值,则左移,小于中轴值,跳出循环
            while (arr[r] > pivot) {
                r--;
            }
            //将左边比中轴值大的数与右边比中轴值小的数交换位置
            temp = arr[l];
            arr[l] = arr[r];
            arr[r] = temp;
            //如果l>=r跳出循环
            if (l >= r) {
                break;
            }
            //如果左边存在等于中轴值的数,则r左移
            if (arr[l] == pivot) {
                r--;
            }
            //如果右边存在等于中轴值的数,则l右移
            if (arr[r] == pivot) {
                l++;
            }
        }
        //防止栈溢出
        if (l == r) {
            l++;
            r--;
        }
        //向左递归
        if (left < r) {
            quickSort(arr, left, r);
        }
        //向右递归
        if (right > l) {
            quickSort(arr, l, right);
        }
    }

}

归并排序

MergeSort.java
package com.Taking.sort;

import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * Demo class
 * 归并排序
 * 
 * @author Taking
 * @date 2020/5/21
 */
public class MergeSort {
    public static void main(String[] args) {
        System.out.println("------------------------");
        System.out.println("*******归并排序算法*******");
        startTime();
        mergeSort(randomArray(),0,randomArray().length-1,new int[randomArray().length]);
        endTime();
        System.out.println("------------------------");
    }

    /**
     * 产生长度为100000的随机数组
     */
    public static int[] randomArray() {
        int[] arr = new int[100000];
        for (int i = 0; i < arr.length; i++) {
            //随机产生数据
            arr[i] = (int) (Math.random() * 100000);
        }
        return arr;
    }

    /**
     * 算法开始时时间
     */
    public static void startTime() {
        //开始时间
        Date date1 = new Date();
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String start = simpleDateFormat.format(date1);
        System.out.println("开始时间为:" + start);
    }

    /**
     * 算法结束时时间
     */
    public static void endTime() {
        //结束时间
        Date date2 = new Date();
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String end = simpleDateFormat.format(date2);
        System.out.println("结束时间为:" + end);
    }

    /**
     * 归并排序
     * O(n^log(n))
     * @param arr
     * @param left
     * @param right
     * @param temp
     */
    public static void mergeSort(int[] arr,int left,int right,int[] temp) {
        if(left<right){
            //确定中值索引
            int mid = (left+right)/2;
            //左递归
            mergeSort(arr,left,mid,temp);
            //右递归
            mergeSort(arr,mid+1,right,temp);
            //合并
            merge(arr,left,mid,right,temp);
        }
    }

    /**
     * 合并过程
     * @param arr
     * @param left
     * @param mid
     * @param right
     * @param temp  临时数组
     */
    public static void merge(int[] arr,int left,int mid,int right,int[] temp){
        //分成左右两组
        //左索引
        int i=left;
        //右索引
        int j=mid+1;
        //临时数组索引
        int t = 0;
        //比较左右两组数的大小
        while(i<=mid && j<=right){
            //如果左边小,存入临时数组,左索引右移,临时数组索引右移
            if(arr[i]<=arr[j]){
                temp[t] = arr[i];
                t++;
                i++;
            }else{
                //如果右边小,存入临时数组,右索引右移,临时数组索引右移
                temp[t] = arr[j];
                t++;
                j++;
            }
        }
        //如果右组都已存入临时数组,则将左组剩下的值依次存入临时数组
        while(i<=mid){
            temp[t] = arr[i];
            t++;
            i++;
        }
        //如果左组都已存入临时数组,则将右组剩下的值依次存入临时数组
        while(j<=right){
            temp[t] = arr[j];
            t++;
            j++;
        }
        //将临时数组置0,将临时数组的值赋值给原数组
        t=0;
        //定义原数组索引
        int tl = left;
        while(tl<=right){
            arr[tl] = temp[t];
            tl++;
            t++;
        }
    }
}

基数排序

RadixSort.java
package com.Taking.sort;

import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * Demo class
 * 基数排序
 * 
 * @author Taking
 * @date 2020/5/22
 */
public class RadixSort {
    public static void main(String[] args) {
        System.out.println("------------------------");
        System.out.println("*******基数排序算法*******");
        startTime();
        radixSort(randomArray());
        endTime();
        System.out.println("------------------------");
    }

    /**
     * 产生长度为100000的随机数组
     */
    public static int[] randomArray() {
        int[] arr = new int[100000];
        //若数组过大会出现:Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
        for (int i = 0; i < arr.length; i++) {
            //随机产生数据
            arr[i] = (int) (Math.random() * 100000);
        }
        return arr;
    }

    /**
     * 算法开始时时间
     */
    public static void startTime() {
        //开始时间
        Date date1 = new Date();
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String start = simpleDateFormat.format(date1);
        System.out.println("开始时间为:" + start);
    }

    /**
     * 算法结束时时间
     */
    public static void endTime() {
        //结束时间
        Date date2 = new Date();
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String end = simpleDateFormat.format(date2);
        System.out.println("结束时间为:" + end);
    }

    /**
     * 基数排序
     * O(d(n+r))
     * @param arr
     */
    public static void radixSort(int[] arr) {
        //定义一个二维数组,[桶的个数,桶中存放的数据]
        int[][] bucket = new int[10][arr.length];
        //定义一个一维数组,用于计数存放某个桶中的元素个数
        int[] bucketElementCounts = new int[10];
        //确定元素中最高位
        int max = arr[0];
        for (int i = 0; i < arr.length; i++) {
            if (max < arr[i]) {
                max = arr[i];
            }
        }
        int length = (max + "").length();
        //有几位数,就循环几次
        for (int i = 0, n = 1; i < length; i++, n *= 10) {
            //确定相应位数值,并存放到对应桶中
            for (int j = 0; j < arr.length; j++) {
                int digitOfElement = arr[j] / n % 10;
                //存放桶中,然后计数+1
                bucket[digitOfElement][bucketElementCounts[digitOfElement]++] = arr[j];
            }
            //定义一个原数组的索引
            int index = 0;
            //遍历二维数组,按顺序存放到原数组
            for (int j = 0; j < bucket.length; j++) {
                if (bucketElementCounts[j] != 0) {
                    for (int k = 0; k < bucketElementCounts[j]; k++) {
                        arr[index++] = bucket[j][k];
                    }
                }
                //将每个桶的计数值清零,方便下一次计数
                bucketElementCounts[j] = 0;
            }
        }
    }
}

堆排序

HeapSort.java
package com.Taking.sort;

import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * Demo class
 * 堆排序
 * 
 * @author Taking
 * @date 2020/5/22
 */
public class HeapSort {
    public static void main(String[] args) {
        System.out.println("------------------------");
        System.out.println("*******堆排序算法*******");
        startTime();
        heapSort(randomArray());
        endTime();
        System.out.println("------------------------");
    }

    /**
     * 产生长度为100000的随机数组
     */
    public static int[] randomArray() {
        int[] arr = new int[100000];
        for (int i = 0; i < arr.length; i++) {
            //随机产生数据
            arr[i] = (int) (Math.random() * 100000);
        }
        return arr;
    }

    /**
     * 算法开始时时间
     */
    public static void startTime() {
        //开始时间
        Date date1 = new Date();
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String start = simpleDateFormat.format(date1);
        System.out.println("开始时间为:" + start);
    }

    /**
     * 算法结束时时间
     */
    public static void endTime() {
        //结束时间
        Date date2 = new Date();
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String end = simpleDateFormat.format(date2);
        System.out.println("结束时间为:" + end);
    }

    /**
     * 构造大顶堆
     *
     * @param arr
     * @param i
     * @param length
     */
    public static void constructLargeHeap(int[] arr, int i, int length) {
        //将非子叶点的值赋值给临时变量temp
        int temp = arr[i];
        //比较左右孩子节点大小,将值大的与其父节点比较
        //定义孩子节点索引k
        for (int k = 2 * i + 1; k < length; k = 2 * k + 1) {
            //左孩子节点小于右孩子节点,将索引k右移
            if (k + 1 < length && arr[k] < arr[k + 1]) {
                k++;
            }
            //大于互换位置
            if (arr[k] > temp) {
                arr[i] = arr[k];
                i = k;
            } else {
                //小于则跳出循环
                break;
            }
            //将非叶子节点的值与最大值的值的位置交换
            arr[i] = temp;
        }
    }

    /**
     * 堆排序
     * O(n^log(n))
     * @param arr
     */
    public static void heapSort(int[] arr) {
        //定义临时变量
        int temp = 0;
        //构造大顶堆
        for (int i = arr.length / 2 - 1; i >= 0; i--) {
            constructLargeHeap(arr, i, arr.length);
        }
        //将堆顶数与堆末尾的数进行交换,使得最大值在数组最后
        for (int j = arr.length - 1; j >= 0; j--) {
            temp = arr[j];
            arr[j] = arr[0];
            arr[0] = temp;
            //交换完,再对最大值前面的子数组构造大顶堆
            constructLargeHeap(arr, 0, j);
        }
    }
}
算法速度测试(针对随机数组)
运行环境:Intel® Core™ i5-7300HQ CPU @ 2.50GHz 2.5GHz RAM:8.00GB
排序算法\数量级1000005000001000000500000010000000
冒泡排序20s400s1600s- -- -
选择排序5s96s400s- -- -
插入排序1s26s100s- -- -
希尔排序(交换|移位)12s~14s|<1s240s|1s913s|1s- -- -
快速排序<1s<1s<=1s1s2s
归并排序<1s<=1s<=1s1~2s2~3s
基数排序<1s<1s<=1s1s1s
堆排序<1s<1s<=1s1~2s3s
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值