七大排序详解

目录

一、排序的解释

1、排序

2、排序的稳定性

3、 内部排序和外部排序

(1)内部排序

​编辑 (2)外部排序

二、各大排序的测试方法 

三、选择排序 

1、直接选择排序

 2、堆排序

3、双向选择排序

四、交换排序

(1)冒泡排序

2、快速排序 

(1)分区方法一 

(2)分区方法二

五、插入排序

1、直接插入排序

 2、折半插入排序

3、希尔排序

 六、归并排序

七、排序练习题

1、剑指 Offer 51. 数组中的逆序对

 2、排序链表

八、相关代码


一、排序的解释

1、排序

        排序,就是使一串记录,按照其中的某个或某些关键字的大小,递增或递减的排列起来的操作。平时的上下文中,如果提到排序,通常指的是排升序(非降序)。通常意义上的排序,都是指的原地排序(in place sort)。

2、排序的稳定性

       待排序的序列中,存在值相同的元素,经过排序后,值相等的先后顺序没有发生变化的排序算法称之为稳定的算法  。 就是下图中的5a和5b的先后顺序并没有发生变化。        

3、 内部排序和外部排序

(1)内部排序

待排序的数据都放在内存中

(2)外部排序 

        数据存储在硬盘中,每次排序都需要从硬盘读取一部分内容到内存中,把这部分数据排序之后再写会硬盘。比如说桶排序,基数排序,奇数排序,这些方法都需要在特殊的场景下才可以使用,局限性比较大。

二、各大排序的测试方法 

package Seven_sorts;

import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.concurrent.ThreadLocalRandom;

/**
 * 测试七大排序
 */
public class SortTest {
    //生成随机数的一个类
    private static final ThreadLocalRandom random=ThreadLocalRandom.current();

    /**
     * 产生一个大小为n的随机整数数组,数组的取值范围为[l...r]
     * @param n  数组的元素个数
     * @param l  数组的取值最小值
     * @param r  数组的取值最大值
     * @return
     */
    public static int[] generaRabdomArrary(int n,int l,int r){
        int[] data=new int[n];
        for (int i = 0; i <n ; i++) {
            //生成了一个[l...r)的随机数放在数组中
            data[i]= random.nextInt(l,r);
        }
        return data;
    }

    /**
     * 生成一个大小为n的近乎有序的数组
     * @param n  元素个数
     * @param swaptinmes  交换的次数,次数越大,数组越无序
     * @return
     */
    public static int[] generateSortArrary(int n,int swaptinmes){
        //先生成一个有序数组
        int[] data =new int[n];
        for (int i = 0; i < n; i++) {
            data[i]=i;
        }
        //对有序数组的部分元素进行交换
        for (int i = 0; i <swaptinmes; i++) {
            int a= random.nextInt(n);
            int b= random.nextInt(n);
            int temp=data[a];
            data[a]=data[b];
            data[b]=temp;
        }
        return data;
    }

    /**
     * 深拷贝数组
     * @param arr
     * @return
     */
    public static int[] arraryCopy(int[] arr){
        return Arrays.copyOf(arr,arr.length);
    }

    /**
     * 在指定的数组arr上测试名称为sortName的排序耗时
     * @param arr
     * @param sortName
     */
    public static void testSort(int[] arr,String sortName){
        Class<SevenSort> cla=SevenSort.class;
        try {
            //根据战法名称拿到算法
            Method method= cla.getDeclaredMethod(sortName,int[].class);
            //计时
            long start=System.nanoTime();
            method.invoke(null,arr);
            long end=System.nanoTime();
            if (isSorted(arr)){
                System.out.println(sortName+"排序完成,共耗时:"+(end-start)/1000000.0+"ms");
            }
        }catch (Exception e){
            e.printStackTrace();
        }
    }

    /**
     * 检查当前数组是否是一个非降序数组
     * @param arr
     * @return
     */
    private static boolean isSorted(int[] arr){
        for (int i = 0; i < arr.length-1; i++) {
            if (arr[i]>arr[i+1]){
                System.out.println("排序算法有误!");
                return false;
            }
        }
        return true;
    }
}

三、选择排序 

1、直接选择排序

       每一次从无序区间选出最大(或最小)的一个元素,存放在无序区间的最后(或最前),直到全部待排序的数据元素排完 。

在这里插入图片描述

 9,2,5a,7,5b,4,3,6

对于这一组数据来说,最开始排序时,

待排序数组(无序区间)为[i...n),已排序数组(有序区间)为[]

当进行了第一次排序后,2,9,5a,7,5b,4,3,6

待排序数组(无序区间)为[i...n)-1,已排序数组(有序区间)为[]+1

 /**
     * 直接选择排序
     * @param arr
     */
    public static void selsctionSort(int[] arr){
        //最开始的无序区间[i...n),有序区间为[]
        for (int i = 0; i < arr.length; i++) {
            //最小元素索引下标
            int min=i;
            for (int j = i+1; j < arr.length; j++) {
                if (arr[j]<arr[min]){
                    min=j;
                }
            }
            //此时min就是最小值的索引,进行交换操作
            swap(arr,i,min);
        }
    }

 2、堆排序

CSDN</

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值