Java代码-八种数组排序方法

一.冒泡排序

1.1概述

对于一组,多次将数组中的数两两比较,较大或者较小的数向后排(经过一轮比较后,最大/最小的数就会到结尾),循环直至有序排列。

1.2代码实现

import java.lang.reflect.Array;
import java.util.Arrays;
import java.util.Scanner;

public class maopao {
    public static void main(String[] args) {
        System.out.println("请输入需要排序的数字,数字之间用空格或者回车隔开,输入完数字后输入任意非数字结束输入");
        Scanner scanner = new Scanner(System.in); //复习scanner
        Double[] input1= new Double[10]; //复习数组的定义 声明 创建
        int count=0;
        while (scanner.hasNextDouble()){    //复习scanner.xxx 不用if用while
            input1[count] = scanner.nextDouble();
            count++;
        }
        scanner.close();
        Double[] input2 = new Double[count];
        for (int i = 0; i < count; i++) {  //去掉冗余
            input2[i]=input1[i];
        }
        Double[] output = new Double[count];
        output=mp(input2);
        System.out.println("排序后的数组为:"+Arrays.toString(output));
    }

    private static Double[] mp(Double[] a) {
        double temp;
        // 降序排列
        for (int i = 0; i < a.length-1; i++) {   //n个数分n-1大轮
            for (int j = 0; j < a.length-1-i; j++) {  //每小轮有n-1-i次排序,每排一大轮每小轮少比较一次(每大轮出一个最值)
                if(a[j]

二.选择排序

2.1概述

从第一个数开始,依次和后面的数进行比较,小/大的数往前放(经过一轮最小/大数出现在最前面),之后从第二个数开始上述比较方式,循环至排序结束。

2.2代码实现

import java.util.Arrays;
import java.util.Scanner;

public class xuanze {
    public static void main(String[] args) {
        System.out.println("输入需要排序的数组");
        Double[] input1 = new Double[100000000];
        int count = 0;
        Scanner scanner = new Scanner(System.in);
        while (scanner.hasNextDouble()){
            input1[count] = scanner.nextDouble();
            count++;
        }
        Double[] input2 = new Double[count];
        for (int i = 0; i < count; i++) {
            input2[i]=input1[i];
        }
        //System.out.println(Arrays.toString(input2));
        Double[] output = new  Double[count];
        //output=xz(input2);
        output=xz1(input2);
        System.out.println("排序后的数是:"+Arrays.toString(output));
    }

    private static Double[] xz(Double[] a) {
        double temp;
        for (int i = 0; i < a.length-1; i++) {
            for (int j = i; j < a.length-1; j++) {
                if(a[j]>a[j+1]){
                    temp=a[j];
                    a[j]=a[j+1];
                    a[j+1]=temp;
                }
            }
        }
        return a;
    }

    private static Double[] xz1(Double[] a) {
        double temp;
        for (int i = 0; i < a.length-1; i++) {
            for (int j = i+1; j < a.length; j++) {
                if(a[j]

方法xz和方法xz1是两种不同写法。第一中方法是大轮内小轮比较,第二种方法是两两比较。

三.直接插入排序

3.1概述

将数组中第一个数看成一个数组,插入原数组第二个数,使得这两个数形成有序数组,再在这个有序数组插入原数组的第三个数,使得这三个数形成有序数组,以此类推,直到将原数组排序。

3.2代码实现

import java.util.Arrays;
import java.util.Scanner;

public class charu {
    public static void main(String[] args) {
        System.out.println("输入需要排序的数组");
        Double[] input1 = new Double[10000000];
        int count = 0;
        Scanner scanner = new Scanner(System.in);
        while (scanner.hasNextDouble()){
            input1[count]=scanner.nextDouble();
            count++;
        }
        scanner.close();
        Double[] input2 = new Double[count];
        for (int i = 0; i < count; i++) {
            input2[i] = input1[i];
        }
        Double[] output = new Double[count];
        output = cr(input2);
        //output=cr1(input2);
        //output=cr2(input2);
        System.out.println("排序后的数组是:"+ Arrays.toString(output));
    }

    private static Double[] cr(Double[] a) {
        double temp = 0;
        for (int i = 0; i < a.length-1; i++) { // i定义大轮数
            for (int j = i+1; j >0 ; j--) { // j负责插入数的比较
                if (a[j]0&&a[j]0在前
                Double temp = a[j];
                a[j] = a[j-1];
                a[j-1]=temp;
                j--;
            }
        }
        return a;
    }
    private static Double[] cr2(Double[] a) {
        for (int i=1;i0 ; j--) {
                if (a[j]

四.希尔排序

4.1概述

希尔排序又称缩小增量排序,基本思想是将原数组按增量ht分组,每个子文件安插入法排序。同样,下一个增量ht/2将文件再分为子文件,再按插入法排序。直到ht=1排好序。该方法的关键是是选择合适的增量。

4.2代码实现

import java.util.Arrays;
import java.util.Scanner;

public class xier {
    public static void main(String[] args) {
        System.out.println("输入需要排序的数组");
        Double[] input1 = new Double[10000000];
        int count = 0;
        Scanner scanner = new Scanner(System.in);
        while (scanner.hasNextDouble()){
            input1[count]=scanner.nextDouble();
            count++;
        }
        scanner.close();
        Double[] input2 = new Double[count];
        for (int i = 0; i < count; i++) {
            input2[i] = input1[i];
        }
        Double[] output = new Double[count];
        //output = cr(input2);
        output=xe(input2);
        System.out.println("排序后的数组为:"+ Arrays.toString(output));
    }
    private static Double[] xe(Double[] a) {
//        //克努特序列
//        int jiange = 1;
//        while (jiange 0; h=h/2) {  //循环h
            for (int i = h; i -1 ; j=j-h) { //小轮循环 后面的数与前面的数比较(前后差h)
                    //j-h大于-1保证索引大于等于0  j=j-h 前后两个数索引位置
                    if (a[j]

五.快速排序

5.1概述

从数组中取一个数,作为基准数,将比这个数大或者等于的数放到右边,小于的放到左边。(降序),再对左右区间重复上述方法,直到每个区间只有一个数。

5.2代码实现

import java.util.Arrays;
import java.util.Scanner;

public class kuaisu {
    public static void main(String[] args) {
        System.out.println("输入需要排序的数组");
        Double[] input1 = new Double[10000000];
        int count = 0;
        Scanner scanner = new Scanner(System.in);
        while (scanner.hasNextDouble()){
            input1[count]=scanner.nextDouble();
            count++;
        }
        scanner.close();
        Double[] input2 = new Double[count];
        for (int i = 0; i < count; i++) {
            input2[i] = input1[i];
        }
        //Double[] output = new Double[count];
        //output = cr(input2);
        ks(input2,0,input2.length-1);
        System.out.println("排序后的数组为:"+ Arrays.toString(input2));
    }

    private static void ks(Double[] a,int start,int end) {
        //快速排序法需要利用前后数的位置,默认起始位置为0和length-1
        if (start= x) { //从后向前找比选取数小的数
                j--;//j一直减,直到找到为止,此时j位置上就是比选取数小的数
            }
            if (i < j) { //还未找到选取数对应的索引
                a[i] = a[j]; //交换数
                i++; //下次从前向后找起始,新数下标
            }
            while (i < j && a[i] <= x) { //向前向后找比比新数大的数
                i++; //i一直加,直到找到为止,此时j位置上就是比选取数大的数
            }
            if (i < j) {
                a[j] = a[i]; //交换
                j--; //下次从后向前找起始,新数下标
            }
        }
        a[i]=x; //完成一次排序
        return i;
        //快速排序法 选取一个数经过左小又大的方式(升序)分左右两组,并确定其在数组中的位置;
        //再将左右两组分别重复上述方法(递归)再确定两个选取数的位置;
        //再次选取、分组、选取、分组......最终确定每个数的位置,完成排序;
        //所以ks方法中,有寻找索引和左右分组(前组从前向后,后组从后向前)
        //在寻找索引的时候,除了有选取的数,还需要两个数,一个从前向后找位置(前索引),一个从后向前找位置(后索引)
        //在两个数不等的时候,先从后找数,直到找到小数后索引一直减,找到后将该数移动到选取数的位置
        //再从前找,直到找到大数前索引一直加,找到后将该数移动到后索引的位置
        //重复上述,直到前后两索引数相同,定位选取数位置,此时前索引=后索引=选取数的索引
    }
}

六.归并排序

6.1概述

假设初始序列有N个数,可以看成是N个有序的子序列,每个子序列长度是1,然后两两归并,得到N/2个长度为2或1的有序子序列,然后两两归并,如此重复直到排序完成。

6.2代码实现

import java.util.Arrays;
import java.util.Scanner;

public class guibing {
    public static void main(String[] args) {

        System.out.println("输入需要排序的数组");
        Double[] input1 = new Double[10000000];
        int count = 0;
        Scanner scanner = new Scanner(System.in);
        while (scanner.hasNextDouble()){
            input1[count]=scanner.nextDouble();
            count++;
        }
        //scanner.close();
        Double[] input2 = new Double[count];
        for (int i = 0; i < count; i++) {
            input2[i] = input1[i];
        }
        cf(input2,0,input2.length-1);
        System.out.println("排序后的数组为:"+ Arrays.toString(input2));
    }


    private static void cf(Double[] a, int start,int end) {
        //先拆分后合并,拆分需要计算从哪分开,需要计算分开位置,所以需要起始和结束位置(start、end)
        //计算中间索引
        int centerIndex = (start+end)/2;
        //开始拆分,分为两组
        if (start

七.基数排序

7.1概述

基数排序法基于对不同位的分组(从个位开始)进行排序。

7.2代码实现


import java.util.Arrays;
import java.util.Scanner;

import static sun.management.MemoryUsageCompositeData.getMax;

public class jishu {
    public static void main(String[] args) {
        System.out.println("输入需要排序的数组");
        Double[] input1 = new Double[10000000];
        int count = 0;
        Scanner scanner = new Scanner(System.in);
        while (scanner.hasNextDouble()){
            input1[count]=scanner.nextDouble();
            count++;
        }
        scanner.close();
        Double[] input2 = new Double[count];
        for (int i = 0; i < count; i++) {
            input2[i] = input1[i];
        }
        Double[] output = new Double[count];
        //output = cr(input2);
        output = js(input2);
        System.out.println("排序后的数组为:"+ Arrays.toString(output));
    }

    private static Double[] js(Double[] a) {
        double max = getMaxNumber(a); //得到数组中的最大值
        int len = String.valueOf(max).length(); //得到最大数一共几位,几位就大循环几次
        double[][] temp = new double[10][a.length]; //根据需要创建
        int[] c = new int[10]; //c用于计数 c[余数]=有几个某位相同的数  根据需要创建
        for (int i = 0,n=1; i < len; i++,n=n*10) {  //大循环 n为后加
            for (int j = 0; j < a.length; j++) { //将a中的每个数转移出去
                int ys = (int) ((a[j] / n) % 10); //丢失精度 该代码比较小数有问题  后加
                temp[ys][c[ys]] = a[j]; //赋值 temp[余数][该余数下有多少个数]
                c[ys]++;
            }

            //反转移数
            int index=0; //创建反转回的索引
            //for (int j = 0; j < a.length; j++) { //错误
                for (int k = 0; k < c.length; k++) { //遍历余数(0-9)
                    if (c[k]!=0){
                    for (int l = 0; l < c[k]; l++) {//遍历c
                        a[index]=temp[k][l];
                        index++;
                    }}
                    c[k]=0;
                }
            //}
            //Arrays.fill(c, 0);// 正确
        }

        return a;
    }

    private static double getMaxNumber(Double[] a) {
        double max = a[0];
        for (int i = 0; i < a.length; i++) {
            if (a[i]>max){
                max = a[i];
            }
        }
        return max;
    }
}
//基数排序法不需要两个索引去比较两个数的大小
//需要将数不断按...、十、个位分组排序

八.堆排序

8.1概述

堆排序利用堆这种数据结构进行偶爱徐,堆排序是一种选择性排序。

8.2代码实现

import java.util.Arrays;
import java.util.Scanner;

public class dui {
    public static void main(String[] args) {
        System.out.println("输入需要排序的数组");
        Double[] input1 = new Double[10000000];
        int count = 0;
        Scanner scanner = new Scanner(System.in);
        while (scanner.hasNextDouble()){
            input1[count]=scanner.nextDouble();
            count++;
        }
        scanner.close();
        Double[] input2 = new Double[count];
        for (int i = 0; i < count; i++) {
            input2[i] = input1[i];
        }
        Double[] output = new Double[count];
        //output = cr(input2);
        output=d(input2);
        System.out.println("排序后的数组为:"+ Arrays.toString(output));
    }

    private static Double[] d(Double[] a) {
        //定义开始调整的位置
        int start = (a.length-1)/2; //从一半开始调 方便遍历数组全部元素
        for (int i = start; i >=0 ; i--) {
            toMaxHeap(a,a.length,i); // 将数组变成一个大顶堆
        }
        for (int i = a.length-1; i >=0 ; i--) { //最后一个数和第一个数交换位置并再次调整大顶堆
            double t = a[0];
            a[0] = a[i];
            a[i] = t;
            toMaxHeap(a,i,0);
        }
        return a;
    }


    private static void toMaxHeap(Double[] a, int size, int index) {
        int left = index*2+1; //左节点
        int right = index*2+2;//右节点
        int maxIndex = index;
        //获取最大节点对应的索引
        if(lefta[maxIndex]){
            maxIndex=left;
        }
        if (righta[maxIndex]){
            maxIndex=right;
        }
        //调换位置
        if (maxIndex!=index){
            double t = a[maxIndex];
            a[maxIndex] = a[index];
            a[index] = t;
            //调换之后可能会影响到下面的子数,不是大顶堆,我们还需要再次调换
            toMaxHeap(a,size,maxIndex);
        }

    }
}

九.总结归纳

时间复杂度和空间复杂度比较

排序方法 时间复杂度 空间复杂度 稳定性
冒泡排序 O(n^2)  O(1) 很好
选择排序 O(n^2) O(1) 很差
插入排序  O(n^2) O(1) 很好
希尔排序 介于O(n)和O(n ^ 2)之间 O(1) 较差
快速排序 O(nlogn) O(logn) 较差
并归排序 O(nlogn) O(n) 较好
基数排序 O(n+k)  O(n+k) 很不好
堆排序 O(nlogn) O(1) 较差

其中k是最大元素的值。

更多:8 种常见排序的总结

你可能感兴趣的:(算法,java)