数据结构与算法----# 一、排序

一、排序

1、比较器Comparable

Java中的比较器(排序) - 情陌人灬已不在 - 博客园 (cnblogs.com)

Comparable和Comparator接口都是为了对类进行比较,众所周知,诸如Integer,double等基本数据类型,java可以对他们进行比较,而对于类的比较,需要人工定义比较用到的字段比较逻辑。可以把Comparable理解为内部比较器,而Comparator是外部比较器。

实体类student:

public class Student implements Comparable<Student> {
    private String name;
    private int age;
	//有参、无参、get、set、tostring
    @Override
    public int compareTo(Student o) {
        return this.age-o.age;
    }
}

测试类:

public class TestCompare {
    public static void main(String[] args) {
        Student s1 = new Student("马云", 40);
        Student s2 = new Student("马化腾", 41);
        Comparable max = getMax(s1, s2);
        System.out.println(max);
    }
    public static Comparable getMax(Comparable c1, Comparable c2){
        int res=c1.compareTo(c2);
        if (res>=0){
            return c1;
        }else {
            return c2;
        }
    }
}

2、冒泡排序

冒泡排序优缺点

  • 优点:比较简单,空间复杂度较低,是稳定的
  • 缺点:时间复杂度太高,效率较低

java代码:

/*
    冒泡排序算法:由小到大  分为三个方法较之前更加 封装解耦
    最坏时间复杂度:逆序情况下O(n^2)
    适用场景:元素较少的情况下可选择适用
    优点:安全稳定排序,比较两个相同的数据时顺序不变
* */
public class BubbleSort {

    /*
    * 对数组a中的元素排序 Integer 类型 implements Comparable<Integer>,因此可以采用比较器
    * */
    public static void bubbleSort(Integer[] a){
        for (int i=0;i<a.length-1;i++){           //依次循环,每次比较出最大的一个数
            for (int j=0;j<a.length-1-i;j++){   //比较剩下的数
                if (greater(a[j],a[j+1]))
                    exch(a,j,j+1);
            }
            //System.out.println("第"+(i+1)+"趟:"+ Arrays.toString(a)); //测试每趟下来的结果
        }
    }

    /*
    数组元素i和j交换位置方法
    * */
    public static void exch(Comparable[] a,int i,int j){
        Comparable temp;
        temp=a[i];
        a[i]=a[j];
        a[j]=temp;
    }

    /*
     * 比较a,b两个元素的大小方法
     * */
    public static boolean greater(Comparable a,Comparable b){
        return a.compareTo(b)>0;
    }
}

测试类:

public class BubbleSortTest {
    public static void main(String[] args) {
        Integer[] arr= new Integer[]{3, 5, 1, 4, 2};
        bubbleSort(arr);                          //给数组排序
        System.out.println(Arrays.toString(arr));
    }
}

3、选择排序

java代码:

/*
*   选择排序算法:升序 分为三个方法较之前更加 封装解耦
    时间复杂度:O(n^2)
    适用场景:元素较少的情况下可选择适用
    优点:不稳定排序,比较两个相同的数据时顺序可能发生改变
* */
public class SelectSort {

    public static void Sort(Integer[] arr){
                                                //最小元素下标
        int minIndex;                           
        for (int i=0;i<arr.length-1;i++){       //进行N次交换
            minIndex=i;                         //默认最小元素下标为i
            for (int j=i+1;j< arr.length;j++){  //从i+1比较到最后一个元素
                if (greater(arr[minIndex],arr[j])){
                    minIndex=j;                 //被较小元素下标替换
                }
            }
            exch(arr,i,minIndex);               //交换i与最小元素
        }
    }

    /*
        数组元素i和j交换位置方法
        * */
    public static void exch(Comparable[] a,int i,int j){
        Comparable temp;
        temp=a[i];
        a[i]=a[j];
        a[j]=temp;
    }

    /*
     * 比较a,b两个元素的大小方法
     * */
    public static boolean greater(Comparable a,Comparable b){
        return a.compareTo(b)>0;
    }

}

测试类:

public class SelectTest {

    public static void main(String[] args) {
        Integer[] arr=new Integer[]{4,3,5,6,1,2};
        Sort(arr);
        System.out.println(Arrays.toString(arr));
    }
}

选择与冒泡比较:
图片失效!

4、直接插入和希尔排序

/*
直接插入排序  最坏时间复杂度:O(n^2)  最好:O(n)
* */
public static class Insertion {

    //升序
    public static void insertionSort(Integer[] wait){
        for (int i=1;i<wait.length;i++){                    //插入次数为待排序数组wait[].length-1 从索引1开始,0不用比较
            for (int j=i;j>0;j--){                          //j>0 防止 j-1 导致 ArrayIndexOutOfBoundsException
                if (greater(wait[j-1],wait[j])){            // 前 > 后时交换
                    exch(wait,j-1,j);
                }else {
                    break;
                }
            }
        }
    }

}

/*希尔排序的排序思路是:
把较大的数据集合分割成若干个小组(逻辑上分组),
然后对每一个小组分别进行插入排序,
此时,插入排序所作用的数据量比较小(每一个小组),插入的效率比较高
*/
public static class ShellSort{

    public static void shellSort(Integer[] a){
        int N=a.length;  int h=1;
        //1、确定h初始值
        while (h<N/2){
            h=2*h+1;
        }

        //2、排序
        while (h>0){
            //2.1、找到待插入的元素
            for (int i=h;i<N;i++){
                //2.3、把待插入元素放入有序序列中
                for (int j=i;j>h;j-=h){
                    //2.2、待插入元素为a[j] 比较a[j]与a[j-h]
                    if (greater(j-h,j)){
                        //2.3、若j-h较大则交换
                        exch(a,j-h,j);
                    }else {
                        break;
                    }
                }
            }
            h=h/2;
        }
    }
}
posted @ 2022-03-16 22:02  lam要努力  阅读(144)  评论(0编辑  收藏  举报