选择排序-Java

堆排序理论:

https://blog.csdn.net/qq_36186690/article/details/82505569

代码:

package com.paixu.paixuTest;

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

/**
 * 选择排序
 * 1)简单选择排序
 * 2)堆排序
 */
public class xuanZhePaiXu {
    public static void main(String[] args) {
        System.out.println("请输入带排序数,以空格间隔:");
        Scanner scanner = new Scanner(System.in);
        int[] arr = new int[5];
        while (scanner.hasNext()) {
            for (int i = 0; i < arr.length; i++) {
                arr[i] = scanner.nextInt();
            }
            // 1、简单选择排序
            jianDanZuanZhr(arr);

            // 2、堆排序
            duiPaiXu(arr);

        }
    }

    /**
     *  堆排序
     * @param arr
     * 堆满足两个条件 1)完全二叉树  2)父节点必须大于或者等于子节点,或者是小于等于
     * 堆排序的过程:
     * 1)先将无序的序列构造成大顶堆或者小顶推(升序就构造大顶堆、降序就构造小顶堆)
     * 2)将堆顶元素与末尾元素交换,将最大元素"沉"到数组末端;
     * 3)重新调整结构,使其满足堆定义,然后继续交换堆顶元素与当前末尾元素,反复执行调整+交换步骤,直到整个序列有序。
     */
    private static void duiPaiXu(int[] arr) {
        // 构造大顶堆 从第一个非叶子节点开始,从下至上,从左往右
        for (int i = arr.length/2-1;i>=0;i--){
            adjustHeap(arr,i,arr.length);
        }
        // 调整堆结构+交换顶堆元素与末尾元素
        for (int j=arr.length-1;j>0;j--){
            swap(arr,0,j);  // 交换元素
            adjustHeap(arr,0,j);  // 交换元素后,又重新构造大顶堆
        }
        System.out.println("堆排序:"+Arrays.toString(arr));

    }

    private static void swap(int[] arr, int a, int b) {
        int temp = arr[a];
        arr[a] = arr[b];
        arr[b] = temp;
    }

    /**
     * 构造大顶推
     * @param arr
     * @param i
     * @param length
     * 父亲:(i-1)/2
     * 子节点:2i+1   2i+2
     */
    private static void adjustHeap(int[] arr, int i, int length) {
        int temp = arr[i];
        for (int k=i*2+1;k<length;k=i*2+1){  //从i结点的左子结点开始,也就是2i+1处开始
            if (k+1<length && arr[k]<arr[k+1]){ //如果左子结点小于右子结点,k指向右子结点
                k++;
            }
            if (arr[k]>temp){  //如果子节点大于父节点,将子节点值赋给父节点(不用进行交换)
                arr[i] = arr[k];  // 子节点的值赋值给了父节点,那么最后原本父节点的值也要给子节点
                i = k;  // 子节点的下标赋值给i,为了最后赋值
            }else {
                break;
            }
        }
        arr[i] = temp;

    }

    /** 简单选择排序
     * 每次从后面选择一个最小的与前面设置的最小的交换
     * @param arr
     */
    private static void jianDanZuanZhr(int[] arr) {
        for (int i=0;i<arr.length-1;i++){
            int min = i;  // 初始化第一个最小
            for (int j=i+1;j<arr.length;j++){
                if (arr[j]<arr[min]){
                    min = j;
                }
            }
            if (min!=i){  // 不等,说明有比他小的元素。
                int temp = arr[min];
                arr[min] = arr[i];
                arr[i] = temp;
            }
        }
        System.out.println("简单选择排序:"+Arrays.toString(arr));
    }
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值