数据结构---------(2)排序

news2024/12/24 9:31:51

排序

1.选择排序

从待排序的数据中选择最小的元素,将其放在已排序的序列末尾,然后在剩余的数据中再选择最小的元素,放在已排序序列的末尾,以此类推,直到所有的数据都排好序为止。
在这里插入图片描述

public static void main(String[] args) {
    int[] arr = {2,5,1,8,9};
    System.out.println("排序前:");
    for (int i = 0; i < arr.length; i++) {
        System.out.print(arr[i]+" ");
    }
    System.out.println();
    selectSort(arr);
    System.out.println("排序后:");
    for (int i = 0; i < arr.length; i++) {
        System.out.print(arr[i]+" ");
    }
    System.out.println();
}
/**
 * 选择排序,选择最小的一个数据到第一位,第二位,等等
 * @param arr 要排序的数组
 */
public static void selectSort(int[] arr){
    //排除一些无用的数
    if(arr == null||arr.length < 2){
        return;
    }
    for (int i = 0; i < arr.length - 1; i++) {//1 ~ N-1,
        int minIndex = i;//最小的坐标,依次更新这个最小的坐标。
        for (int j = i+1; j < arr.length; j++){//从i+1的数据开始进行比较
            //如果当前的数字大小小于最小值,就把当前的坐标赋值给minIndex
            minIndex = arr[j] < arr[minIndex] ? j : minIndex;
        }
        //将i位置的数字进行交换,交换成最小的值
        swap(arr,i,minIndex);
    }
}
/**
 * 交换数组arr中i和j位置的数。
 * @param arr
 * @param i
 * @param j
 */
public static void swap(int[] arr,int i,int j){
    if(i==j) return;//排除不需要交换的数据
    int temp = arr[i];
    arr[i] = arr[j];
    arr[j] = temp;
}

上面代码的过程

2	5	1	9	8
排序过程
按照数组的顺序,每次确定一个位置(外部循环),
依次遍历未确定的内容,找到最小()的,放到要排序的位置。
1	5	2	9	8 	第一个位置排好
1	2	5	9	8	前两个位置排好
1	2	5	8	9	前三个位置排好
1	2	5	8	9	前四个位置排好

时间复杂度O(N^2)
额外复杂度O(1)

2.冒泡排序

它重复地走访过要排序的元素列,依次比较两个相邻的元素,如果顺序(如从大到小、首字母从Z到A)错误就把他们交换过来。走访元素的工作是重复地进行,直到没有相邻元素需要交换,也就是说该元素列已经排序完成。
在这里插入图片描述

 //冒泡排序
 public static void main(String[] args) {
     int[] arr = {2,5,1,8,9};
     System.out.println("排序前:");
     for (int i = 0; i < arr.length; i++) {
         System.out.print(arr[i]+" ");
     }
     System.out.println();
     bubbleSort(arr);
     System.out.println("排序后:");
     for (int i = 0; i < arr.length; i++) {
         System.out.print(arr[i]+" ");
     }
     System.out.println();
 }

 /**
  * 相邻两个数字进行交换,一次轮询确定一个位置
  * @param arr
  */
public static void bubbleSort(int[] arr){
   //排除一些无用的数
   if(arr == null||arr.length < 2){
       return;
   }
   //最后一个不用排,外循环,需要确定多少个数字的位置
   for (int e = arr.length - 1; e>0 ; e--) {//外层循环,在哪一轮上玩这个东西
       for (int i = 0; i < e; i++) {//具体玩某一轮,某一轮的最后就是冒出的那个气泡。
           if(arr[i] > arr[i+1]){ 
               swag(arr,i,i+1);
           }
       }
   }
}
//交换
public static void swag(int[] arr,int i,int j){
    arr[i] = arr[i]^arr[j];
    arr[j] = arr[i]^arr[j];
    arr[i] = arr[i]^arr[j];
}

排序过程
依次冒出一个最大(小)的数到指定的位置

2	5	1	9	8
排序过程
第一次外循环
2	5	1	9	8
2	1	5	9	8
2	1	5	9	8
2	1	5	8	9   第一轮内循环结束,最后一个位置被确定,是9

第二次外循环
1	2	5	8	9  

第三次外循环
1	2	5	8	9

第四次外循环
1	2	5	8	9

3.插入排序

将一个记录插入到已经排好序的有序表中,从而一个新的、记录数增1的有序表。在其实现过程使用双层循环,外层循环对除了第一个元素之外的所有元素,内层循环对当前元素前面有序表进行待插入位置查找,并进行移动。(就好比整理牌的时候。)
在这里插入图片描述

过程简单描述:
1、从数组第2个元素开始抽取元素。
2、把它与左边第一个元素比较,如果左边第一个元素比它大,则继续与左边第二个元素比较下去,直到遇到不比它大的元素,然后插到这个元素的右边。
3、继续选取第3,4,….n个元素,重复步骤 2 ,选择适当的位置插入。

public static void main(String[] args) {
    int[] arr = {2,5,1,8,9};
    System.out.println("排序前:");
    for (int i = 0; i < arr.length; i++) {
        System.out.print(arr[i]+" ");
    }
    System.out.println();
    insertionSort(arr);
    System.out.println("排序后:");
    for (int i = 0; i < arr.length; i++) {
        System.out.print(arr[i]+" ");
    }
    System.out.println();
}

public static void insertionSort(int[] arr){
    if(arr==null||arr.length<2){
        return;
    }
    //0-1上有序
    //0-N上有序
    for (int i = 1; i < arr.length; i++) {
        for (int j = i-1; j >= 0 && arr[j]>arr[j+1] ; j--) { //两个体条件,在0之前,左边的数比右边的数大
            swap(arr,j,j+1);
        }
    }
}
public static void swap(int[] arr,int i,int j){
    arr[i] = arr[i]^arr[j];
    arr[j] = arr[i]^arr[j];
    arr[i] = arr[i]^arr[j];
}

过程:

2	5	1	9	8
排序过程
2	5	1	9	8	第一次循环排号了25这两个数
2	1	5	9	8 	第二次循环,第一次内循环,15换了位置
1	2	5	9	8	第二次循环,第二次内循环,12换了位置
1	2	5	9	8	第三次循环
1	2	5	8	9	第四次循环

3.1 希尔排序(插入排序的一种变种)

希尔排序可以说是插入排序的一种变种。无论是插入排序还是冒泡排序,如果数组的最大值刚好是在第一位,要将它挪到正确的位置就需要 n - 1 次移动。也就是说,原数组的一个元素如果距离它正确的位置很远的话,则需要与相邻元素交换很多次才能到达正确的位置,这样是相对比较花时间了。

希尔排序就是为了加快速度简单地改进了插入排序,交换不相邻的元素以对数组的局部进行排序。

希尔排序的思想是采用插入排序的方法,先让数组中任意间隔为 h 的元素有序,刚开始 h 的大小可以是 h = n / 2,接着让 h = n / 4,让 h 一直缩小,当 h = 1 时,也就是此时数组中任意间隔为1的元素有序,此时的数组就是有序的了。

在这里插入图片描述

public static void main(String[] args) {
   int[] arr = {1,3,4,321,2,6,254,42352,234562,4246,2,454,345};
   System.out.println("排序前:");
   for (int i = 0; i < arr.length; i++) {
       System.out.print(arr[i]+" ");
   }
   System.out.println();
   shellSort(arr);
   System.out.println("排序后:");
   for (int i = 0; i < arr.length; i++) {
       System.out.print(arr[i]+" ");
   }
   System.out.println();
}

/**
* 希尔排序
* @param arr
*/
public static void shellSort(int[] arr){
   if(arr==null||arr.length<2){
       return;
   }
   //gap就是分的组数,分组越来越小
   for (int gap = arr.length/2; gap > 0; gap--) {
       for (int j = 0; j < arr.length - gap; j++) {
           if(arr[j]>arr[j+gap]){
               swap(arr,j,j+gap);
           }
       }
   }
}
/**
* 交换数组i位置和j位置的值
* @param arr
* @param i
* @param j
*/
public static void swap(int[] arr,int i,int j){
   int tmp = arr[i];
   arr[i] = arr[j];
   arr[j] = tmp;
}

4.归并排序

将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为二路归并。
左右分别排序,然后再将左右内容整合到一起。
在这里插入图片描述

public static void main(String[] args) {
    int[] arr = {1,4,7,8,3,6,9};
    mergeSort(arr);
    for (int i = 0; i < arr.length; i++) {
        System.out.println(arr[i]);
    }
}
public static void mergeSort(int[] arr){
    if(arr==null || arr.length<2) return;
    process(arr,0,arr.length-1);
}

/**
 * @param arr:要排序的数组
 * @param L:数组开始的下标
 * @param R:数组结束的下标
 */
public static void process(int[] arr,int L,int R){
    if(L==R) return;
    int mid = L + ((R-L)>>1);//获取中点位置。
    process(arr,L,mid);
    process(arr,mid+1,R);
    merge(arr,L,mid,R);
}

/**
 * @param arr:数组
 * @param L:数组开始的下标
 * @param M:数组的中间下标
 * @param R:数组的最后的下标
 */
public static void merge(int[] arr,int L,int M,int R){
    int[] help = new int[R-L+1];
    int i = 0;
    int p1 = L;
    int p2 = M+1;
    while(p1 <= M && p2 <=R){ //正常复制
        //help[i++]等价于help[i]  i++
        help[i++] = arr[p1] <= arr[p2] ? arr[p1++]:arr[p2++];
    }
    while(p1<=M){//将左半部分的内容复制下来,跟下面的while循环只能有一个执行
        help[i++] = arr[p1++];
    }
    while(p2<=R) {//将有半部分的内容复制下来
        help[i++] = arr[p2++];
    }
    for(i=0;i<help.length;i++){
        arr[L+i] = help[i];
    }
}

归并排序使用的是递归方法。

1	3	4	2	5
第一次所有的都排序,分为左(0,2)和右(3,4)合并到整个
左边分为(0,1)(1,2)右边只能分为(3,4)
(0,1)排序
(1,2)排序
(3,4)排序 
将左边的联合到,再结合右边的

5.快速排序

我们从数组中选择一个元素,我们把这个元素称之为中轴元素吧,然后把数组中所有小于中轴元素的元素放在其左边,所有大于或等于中轴元素的元素放在其右边,显然,此时中轴元素所处的位置的是有序的。也就是说,我们无需再移动中轴元素的位置。

从中轴元素那里开始把大的数组切割成两个小的数组(两个数组都不包含中轴元素),接着我们通过递归的方式,让中轴元素左边的数组和右边的数组也重复同样的操作,直到数组的大小为1,此时每个元素都处于有序的位置。

在这里插入图片描述
代码

public static void main(String[] args) {
    int[] arr = {1,23,4,2,5,2,6,8,8};
    System.out.println("排序前:");
    for (int i = 0; i < arr.length; i++) {
        System.out.print(arr[i]+" ");
    }
    System.out.println();
    quickSort(arr);
    System.out.println("排序后:");
    for (int i = 0; i < arr.length; i++) {
        System.out.print(arr[i]+" ");
    }
    System.out.println();
}
public static void quickSort(int    [] arr){
    if(arr==null||arr.length<2){
        return;
    }
    quickSort(arr,0,arr.length-1);
}
//arr[l...r]排好序
public static void quickSort(int[] arr,int L,int R){
    if(L<R){
        swap(arr,(int)(Math.random()*(R-L+1)),R);
        int[] p = partition(arr,L,R);
        quickSort(arr,L,p[0]-1);//<区
        quickSort(arr,p[1]+1,R);//>区
    }
}
//这是一个处理arr[l...r]的函数,以arr[R]这个值作为划分依据,分为大于arr[R],等于arr[R],小于arr[R]的区域
//返回等于区域(左边界,右边界),所以返回的是一个长度为2的数组res,res[0],res[1]
public static int[] partition(int[] arr,int L,int R){
    int less = L - 1;//<区,右边界
    int more = R;//>区 左边界
    while(L<more){//遍历整个地址
        if(arr[L] < arr[R]){ //当前数小于划分值
            less++;
            swap(arr,less,L);
            L++;
//                swap(arr,++less,L++);
        }else if(arr[L] > arr[R]){ //当前数大于划分值
            more--;
            swap(arr,more,L);
//                swap(arr,--more,L);
        }else{
            L++;
        }
    }
    swap(arr,more,R);
    return new int[]{less+1,more};
}
/**
 * 交换数组i位置和j位置的值
 * @param arr
 * @param i
 * @param j
 */
public static void swap(int[] arr,int i,int j){
    int tmp = arr[i];
    arr[i] = arr[j];
    arr[j] = tmp;
}

课后习题:
习题:
荷兰国旗
给定一个数组arr,和一个数num,请把小于等于num的数放在数组的左边,大于num的数放在数组的右边。要求额外空间复杂度O(1),时间复杂度 O(N)

/**
 * 题目描述
 * 给定一个数组arr,和一个数num,请把小于等于num的数放在数组的左边,大于num的数放在数组的右边。要求额外空间复杂度O(1),时间复杂度 O(N)
 */
public static void code01(int[] arr,int num){
    if(arr.length<=2)
        return ;
    partition(arr,num);
}

/**
 * 设定一个小于等于区,从0开始比较,如果当前数字小于等于num ,让其与小于等于区的下一个值做交换,再将小于等于区扩大一位,
 * 直到将所有的数字都与num进行过比较。重新排好的数组就是所求的数组
 * @param arr
 * @param num
 */
public static void partition(int[] arr,int num){
    int less = 0;//设定一个小于等于区,这个区域-1的位置都是小于等于num的数字
    for (int i = 0; i < arr.length; i++) {//从0开始比较,直到将所有的数字都与num进行过比较。
        if(arr[i]<=num){//如果当前数字小于等于num
            swap(arr,less,i);//让其与小于等于区的下一个值做交换
            less++;//将小于等于区扩大一位
        }
    }
}
/**
 * 另一种写法
 * 设定一个小于等于区,从-1开始比较,如果当前数字小于等于num ,将小于等于区扩大一位,让其与小于等于区的内容做交换
 * 直到将所有的数字都与num进行过比较。重新排好的数组就是所求的数组
 * @param arr
 * @param num
 */
public static void partition2(int[] arr,int num){
    int less = -1;//设定一个小于等于区,这个区域-1的位置都是小于等于num的数字
    for (int i = 0; i < arr.length; i++) {//从0开始比较,直到将所有的数字都与num进行过比较。
        if(arr[i]<=num){//如果当前数字小于等于num
            less++;//将小于等于区扩大一位
            swap(arr,less,i);//让其与小于等于区的下一个值做交换
        }
    }
}
public static void swap(int[] arr,int L,int R){
    arr[L] = arr[L]^arr[R];
    arr[R] = arr[L]^arr[R];
    arr[L] = arr[L]^arr[R];
}

整个算法的经典之处

arr[i] <= num  arr[i] 和 小于等于区的下一个数交换,小于等于区右扩,i++
arr[i] >  num  i++

给定一个数组arr,和一个数num,请把小于num的数放在数组的左边,等于num的数放在数组的中间,大于num的数放在数组的右边。要求额外空间复杂度O(1),时间复杂度O(N)

/**
* 定一个数组arr, 和一个数num, 请把小于等于num的数放在数组的左边,等于num的放中间,大于num的数放在数组的右边。要求:额外空间复杂度O(1),时间复杂度O(n)。
*/
public static void code02(int[] arr,int num){
   if(arr.length<=2)
       return ;
   partition(arr,0,arr.length-1,num);
}

/**
* @param arr 数组
* @param left 左边
* @param right 右边
* @param num 大于小于等于的值
*/
public static void partition(int[] arr,int left,int right,int num){
   int L = left -1;
   int R = right+1;
   for (int i = 0; i < arr.length;) {
       if(arr[i]<num){//当前值和小于区下一个(++)交换,小于区右扩,i++
           L++;
           swap(arr,i,L);
           i++;
       }else if(arr[i]>num){//当前值和大于区前一个(--)交换,大于区右扩,i不变
           R--;
           swap(arr,i,R);
       }else{//等于num i++
           i++;
       }
   }
}

public static void swap(int[] arr,int L,int R){
   arr[L] = arr[L]^arr[R];
   arr[R] = arr[L]^arr[R];
   arr[L] = arr[L]^arr[R];
}

/**
* while循环的写法
* @param arr
* @param left
* @param right
* @param num
*/
public static void partition2(int[] arr,int left,int right,int num){
   int L = left -1;
   int R = right+1;
   int cur = left;
   while(cur<R){
       if(arr[cur]<num){//当前值和小于区下一个交换,小于区右扩,i++
           ++L;
           swap(arr,cur,L);
           ++cur;
       }else if(arr[cur]>num){//当前值和大于区前一个交换,大于区右扩,i不变
           --R;
           swap(arr,cur,R);
       }else{//等于num i++
           cur++;
       }
   }
}

算法的经典之处

arr[i]<num 	当前值和小于区下一个交换,小于区右扩,i++
arr[i]>num 	当前值和大于区前一个交换,大于区右扩,i不变
arr[i]=num 	i++

6.计数排序

计数排序是一种适合于最大值和最小值的差值不是不是很大的排序。

基本思想:就是把数组元素作为数组的下标,然后用一个临时数组统计该元素出现的次数,例如 temp[i] = m, 表示元素 i 一共出现了 m 次。最后再把临时数组统计的数据从小到大汇总起来,此时汇总起来是数据是有序的。

在这里插入图片描述

public static void main(String[] args) {
    int[] arr = {1,4,2,5,2,6,8,8};
    System.out.println("排序前:");
    for (int i = 0; i < arr.length; i++) {
        System.out.print(arr[i]+" ");
    }
    System.out.println();
    int[] arr2 = countSort(arr);
    System.out.println("排序后:");
    for (int i = 0; i < arr2.length; i++) {
        System.out.print(arr2[i]+" ");
    }
    System.out.println();
}

/**
 * 计数排序
 * @param arr
 * @return
 */
public static int[] countSort(int[] arr){
    int[] temp = new int[10];
    for (int a : arr) {
        temp[a]++;
    }

    int[] result = new int[arr.length];
    int r = 0;
    for (int i = 0; i < temp.length; i++) {

        while (temp[i]>0){
            result[r]=i;
            r++;
            temp[i]--;
        }
    }
    return result;
}

7.堆排序

1.堆就是用数组实现的完全二叉树结构
数组获取某个二叉树的
左孩子(2i+1)
右孩子(2
i+2)
父节点((i-1)/2)
i为要获取的节点的数组下标

3	5	2	7	1	9	6

			3
			
	5				2
	
	
7		1		9		6

5的左节点2*1+1,arr[3]=7
5的右节点2*1+2,arr[4]=1
5的父节点(1-1)/2,arr[0]=3

2.完全二叉树中如果每颗子树的最大值都在顶部就是大根堆
3.完全二叉树中如果每颗子树的最小值都在顶部就是小根堆
父节点是最大值是大根堆,相反小根堆

public static void heapSort(int[] arr){
    if(arr==null||arr.length<2){
        return;
    }
    for (int i = 0; i < arr.length; i++) {//O(N)
        heapInsert(arr,i);//O(logN)
    }
    int heapSize = arr.length;
    swap(arr,0,--heapSize);
    while (heapSize > 0){//O(N)
        heapify(arr,0,heapSize);//O(logN)
        swap(arr,0,--heapSize);//O(1)
    }
}
/**
 * 某个位置现在处在index的位置,往上继续移动
 * @param arr
 * @param index
 */
public static void heapInsert(int[] arr,int index){
    while(arr[index] > arr[(index-1)/2]){
        swap(arr,index,(index-1)/2);
        index = (index-1)/2;
    }
}
//某个数在index位置,能否往下移动
public static void heapify(int[] arr,int index,int heapSize){
    int left = index * 2 + 1;//左孩子下标
    while( left < heapSize ){//下方还有孩子的时候
        //下标的两个孩子,谁的值最大,把下标给largest
        int largest = left+1 < heapSize && arr[left+1] > arr[left] ? left+1 : left;
        //父和孩子之间,谁的值大,把下标给largest
        largest = arr[largest] > arr[index] ? largest : index;
        if(largest == index){
            break;
        }
        swap(arr,largest,index);
        index = largest;
        left = index * 2 + 1;
    }
}
public static void swap(int[] arr,int i,int j){
    arr[i] = arr[i]^arr[j];
    arr[j] = arr[i]^arr[j];
    arr[i] = arr[i]^arr[j];
}

另一种写法

public static void heapSort(int[] arr){
    if(arr==null||arr.length<2){
        return;
    }
/*       for (int i = 0; i < arr.length; i++) {
        heapInsert(arr,i);
    }*/
    //生成大根堆最快的方法
    for(int i=arr.length-1;i>=0;i--){
        heapify(arr,i,arr.length);
    }

    int heapSize = arr.length;
    swap(arr,0,--heapSize);
    while (heapSize > 0){
        heapify(arr,0,heapSize);
        swap(arr,0,--heapSize);
    }
}

4.堆结构的heapInsert与heapify操作
heapInsert操作,将左边的内容一直从大到小排列

/**
 * 某个位置现在处在index的位置,往上继续移动
 * @param arr
 * @param index
 */
public static void heapInsert(int[] arr,int index){
    while(arr[index] > arr[(index-1)/2]){
        swap(arr,index,(index-1)/2);
        index = (index-1)/2;
    }
}

heapify操作,父节点,左节点,右节点中的最大的值

//某个数在index位置,能否往下移动
public static void heapify(int[] arr,int index,int heapSize){
    int left = index * 2 + 1;//左孩子下标
    while( left < heapSize ){//下方还有孩子的时候
        //下标的两个孩子,谁的值最大,把下标给largest
        int largest = left+1 < heapSize && arr[left+1] > arr[left] ? left+1 : left;
        //父和孩子之间,谁的值大,把下标给largest
        largest = arr[largest] > arr[index] ? largest : index;
        if(largest == index){
            break;
        }
        swap(arr,largest,index);
        index = largest;
        left = index * 2 + 1;
    }
}

5.堆结构的增大和减小

6.优先级队列结构,就是堆结构

8.桶排序(计数排序和基数排序的基础)

桶排序思想下的排序
1.计数排序
2.基数排序
分析:
1.桶排序思想下的排序都是不基于比较的排序。
2.时间复杂度为O(N),额外空间负载度O(N)。
3.应用范围有限,需要样本的数据状况满足桶的划分。


9.基数排序

基数排序的排序思路是这样的:先以个位数的大小来对数据进行排序,接着以十位数的大小来多数进行排序,接着以百位数的大小……

排到最后,就是一组有序的元素了。不过,他在以某位数进行排序的时候,是用“桶”来排序的。

由于某位数(个位/十位….,不是一整个数)的大小范围为0-9,所以我们需要10个桶,然后把具有相同数值的数放进同一个桶里,之后再把桶里的数按照0号桶到9号桶的顺序取出来,这样一趟下来,按照某位数的排序就完成了

在这里插入图片描述

public class RadioSort {
    public static void main(String[] args) {
        int[] arr = {5, 3, 6, 8, 100, 7, 9, 4, 20};
        sort(arr);
    }
 
    public static int[] sort(int[] arr) {
       if(arr==null||arr.length==2) {
           return arr;
       }
       int max = findMax(arr);
       int num = 1;
       while (max/10>0){
           max= max/10;
           num++;
       }
 
        List<List<Integer>> totalBucket = new LinkedList<>();
 
        //初始化桶
        for (int i = 0; i < 10; i++) {
            totalBucket.add(new LinkedList<Integer>());
        }
        for (int i = 0; i < num; i++) {
            //放入对应的桶
            for (int j = 0; j < arr.length; j++) {
                int location = (arr[j] / (int)Math.pow(10,i)) % 10;
                totalBucket.get(location).add(arr[j]);
            }
 
 
            int k = 0;
            for (List<Integer> integers : totalBucket) {
                for (Integer integer : integers) {
                    arr[k++]=integer;
                }
                integers.clear();
            }
 
 
        }
        return arr;
    }
 
    public static int findMax(int[] arr) {
        int max = arr[0];
        for (int i : arr) {
            if(i>max){
                max = i;
            }
        }
        return max;
    }
}

比较器

1.比较器的实质就是重载比较运算符
2.比较器可以很好的应用在特殊标准的排序上。
3.比较器可以很好的应用在根据特殊标准的结构上。

public static void main(String[] args) {
    Student student1 = new Student("A", 2, 20);
    Student student2 = new Student("B", 1, 30);
    Student student3 = new Student("C", 3, 32);
    Student[] students = {student1, student2, student3};
    Arrays.sort(students,new IdAscendingComparator());
    for (int i = 0; i < students.length; i++) {
        System.out.println(students[i]);
    }
}
public static class IdAscendingComparator implements Comparator<Student> {
    /**
     * 返回负数的时候,第一个参数排到前面
     * 返回正数的时候,第二个参数排到前面
     * 返回0的时候,谁在前面无所谓
     */
    @Override
    public int compare(Student o1, Student o2) {
        if(o1.getId() < o2.getId()){
            return -1;
        }
        if(o1.getId() > o2.getId()){
            return 1;
        }
        return 0;
    }
}

class Student{
    private String name;
    private int id;
    private int age;

    public Student(String name, int id, int age) {
        this.name = name;
        this.id = id;
        this.age = age;
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", id=" + id +
                ", age=" + age +
                '}';
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}
public class Code06_smallgendui {
  public static void main(String[] args) {
      PriorityQueue<Integer> heap = new PriorityQueue<>(new Acomp());//小根堆
      heap.add(6);
      heap.add(9);
      heap.add(3);
      heap.add(2);
      heap.add(10);
      while (!heap.isEmpty()){
          System.out.println(heap.poll());
      }
  }
}
class Acomp implements Comparator<Integer>{

  @Override
  public int compare(Integer o1, Integer o2) {
      return o1-o2;
  }
}

排序算法的比较

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/702179.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

大数据分析案例-基于KMeans聚类算法对客户进行分群分析

&#x1f935;‍♂️ 个人主页&#xff1a;艾派森的个人主页 ✍&#x1f3fb;作者简介&#xff1a;Python学习者 &#x1f40b; 希望大家多多支持&#xff0c;我们一起进步&#xff01;&#x1f604; 如果文章对你有帮助的话&#xff0c; 欢迎评论 &#x1f4ac;点赞&#x1f4…

【GESP】2023年03月图形化二级 -- 绘制图形

文章目录 绘制图形1. 准备工作2. 功能实现3. 设计思路与实现&#xff08;1&#xff09;角色、舞台背景设置a. 角色设置b. 舞台背景设置 &#xff08;2&#xff09;脚本编写a. 角色&#xff1a;小猫 4. 评分标准 绘制图形 1. 准备工作 &#xff08;1) 隐藏默认角色小猫。 2. 功…

【Redis入门】 —— 关于Redis的一点儿知识

&#x1f4a7; 【 R e d i s 入门】——关于 R e d i s 的一点儿知识 \color{#FF1493}{【Redis入门】 —— 关于Redis的一点儿知识} 【Redis入门】——关于Redis的一点儿知识&#x1f4a7; &#x1f337; 仰望天空&#xff0c;妳我亦是行人.✨ &#x1f984; 个人主页…

2023年华中杯数学建模B题小学数学应用题相似性度量及难度评估解题全过程文档及程序

2023年华中杯数学建模 B题 小学数学应用题相似性度量及难度评估 原题再现 某 MOOC 在线教育平台希望能够进行个性化教学&#xff0c;实现用户自主学习。在用户学习时&#xff0c;系统从题库中随机抽取若干道与例题同步的随堂测试题&#xff0c;记录、分析学生的学习和答题信息…

深入Vite:再谈ESM的高阶特性

谈到前端模块化的发展历史&#xff0c;就一定不会漏掉ESM&#xff0c;除此之外&#xff0c;还有大家熟知的CommonJS、AMD、CMD以及ES6等。目前&#xff0c; ESM 已经逐步得到各大浏览器厂商以及 Node.js 的原生支持&#xff0c;正在成为主流前端模块化方案。 而 Vite 本身就是…

chatgpt赋能python:Python除零错误:原因,解决办法和实践建议

Python 除零错误&#xff1a;原因&#xff0c;解决办法和实践建议 介绍 Python 作为一门广泛使用的高级编程语言&#xff0c;它的强大之处就体现在它的简洁性、可读性和易用性上。但是在实践中&#xff0c;有时候我们会遇到一些让我们不得不头痛的问题&#xff0c;其中之一就…

(0017) H5-vue创建项目vue init webpack

1、初始化项目 1、vue 命令讲解 vue list &#xff1a;查看可以基于那些模板创建vue应用vue init <template-name> <project-name>init&#xff1a;表示要用vue-cli来初始化项目 <template-name>&#xff1a;表示模板名称&#xff0c;vue-cli官方提供的5种…

【LeetCode】218. 天际线问题

218. 天际线问题&#xff08;困难&#xff09; 思路 题意转化 完整思路分析 multiset的使用 multiset 是关联容器的一种&#xff0c;是排序好的集合&#xff08;元素默认升序&#xff09;&#xff0c;并且允许有相同的元素。 不能直接修改 multiset 容器中元素的值。因…

柯美658 558 458 308 554 364等报错故障代码C2152,C2153,C2154,C2155,C2156 C2253.C2254维修

代码基本都是转印带故障代码,转印带有两个传感器是检测转印带工作和没有工作时加压有没有归位的,传感器基本不会坏,更多的情况是因为转印带上的废粉落在了传感器上导致传感器故障,清洁即可。

剑指offer--JZ24 反转链表

反转链表需要三个指针&#xff0c;一个保留前一个结点的指针&#xff0c;一个后移指针&#xff0c;一个当前指针。C语言版本代码如下&#xff1a; #include <stdio.h> #include <stdlib.h>// 单链表节点结构定义 struct ListNode {int val;struct ListNode* next;…

用acsii , unicode,utf-8讨论为什么采用中文编程不行

一、背景介绍 很多刚接触计算机的同学&#xff0c;可能会发出一个疑问&#xff0c;为什么不能直接使用中文编程&#xff1f; 要了解这个问题&#xff0c;还得从计算机的起源说起&#xff01; 在计算机软件里面&#xff0c;一切的信息都可以用 1 和 0 来表示&#xff08;严格…

mongodb节点一直处于recovering状态问题修复

mongoDB版本&#xff1a;5.0.4 该节点mongod服务日志一直在刷如下日志 {"t":{"$date":"2023-06-19T15:24:50.15608:00"},"s":"I", "c":"REPL", "id":5579708, "ctx":"…

云计算的发展趋势及其对企业的影响

第一章&#xff1a;引言 近年来&#xff0c;云计算在IT行业迅猛发展&#xff0c;成为企业提升业务效率和创新能力的重要工具。通过云计算&#xff0c;企业能够将数据和应用程序存储在云端的服务器上&#xff0c;实现灵活的资源调配和高效的数据管理。本文将探讨云计算的发展趋…

Win11无法连接Win7的打印机解决方法

win11无法连接win7的打印机怎么解决&#xff1f;在日常的办公中&#xff0c;局域网可以实现文件管理&#xff0c;打印机共享文件打印等功能&#xff0c;但是如果两个机器系统各不同的话&#xff0c;可能有的就会提示无法连接&#xff0c;下面就把基本简单的共享设置方法分享给大…

uview的折叠面板和u-tabs的扩展

第一个&#xff1a;首先要安装uview UI框架 &#xff08;已发布如何安装&#xff09; 第二个&#xff1a;使用uview 中的折叠面板&#xff08;Collapse 折叠面板 | uView 2.0 - 全面兼容nvue的uni-app生态框架 - uni-app UI框架&#xff09; 第三点&#xff1a;明白一个插槽使用…

linux - spin lock实现分析

linux - spin lock实现分析 spinlock1 spinlock的数据结构2 spinlock的接口2.1 spin_lock_init2.2 spin_lock2.3 spin_unlock2.4 spin_lock_irq2.5 spin_unlock_irq2.6 spin_lock_irqsave2.7 spin_unlock_irqrestore2.8 spin_lock_bh2.9 spin_unlock_bh spinlock 1 spinlock的数…

第四十三章 开发Productions - ObjectScript Productions - 使用记录映射器 - 编辑记录映射字段和组合

文章目录 第四十三章 开发Productions - ObjectScript Productions - 使用记录映射器 - 编辑记录映射字段和组合编辑记录映射字段和组合NameDatatypeAnnotationWidth (fixed-width record maps only)RequiredRepeating (delimited record maps only)IgnoreTrailing Data (fixed…

RabbitMQ快速上手(延迟队列)

安装 官网 参考文章&#xff1a; ​ https://blog.csdn.net/miaoye520/article/details/123207661 ​ https://blog.csdn.net/lvoelife/article/details/126658695 安装Erlang&#xff0c;并添加环境变量ERLANG_HOME&#xff0c;命令行运行erl 安装rabbitmq&#xff0c;rab…

Pastebin设计之旅:从零设计网络文本存储系统

项目简介&#xff1a;Pastebin是一个在线的文本存储平台&#xff0c;让用户可以存储和分享代码片段或者其他类型的文本。它支持多种编程和标记语言的语法高亮&#xff0c;用户可以选择让他们的"paste"公开或私有。无需注册就可以使用&#xff0c;但注册用户可以更方便…

森海塞尔重磅推出TC Bars智能音视频一体机, 为中小型协作空间缔造理想解决方案

森海塞尔重磅推出TC Bars智能音视频一体机&#xff0c; 为中小型协作空间缔造理想解决方案 全球音频行业先驱森海塞尔重磅推出首款内置摄像头的可扩展一体化会议设备 德国韦德马克&#xff0c;2023年6月13日——森海塞尔作为先进音频技术的首选&#xff0c;致力于使协作与学习…