Java数据结构和算法-选择类排序(简单选择排序,堆排序)

简单选择排序:

每一趟从待排序的数据元素中选出最小(最大)的元素,顺序放在待排序的数列最前,直到全部待排序的数据元素全部排完。

最差时间复杂度:O(n^2),最优时间复杂度:O(n^2),平均时间复杂度:O(n^2),所需辅助空间:O(1)。

package com.algorithm.sort;

import java.util.Scanner;

/**
 * 简单选择排序
 */
public class SelectSort {
    public static void main(String[] args) {
        Scanner scanner=new Scanner(System.in);
        int n=scanner.nextInt();
        int[] a=new int[n];
        int i=0;
        while (i<n){
            a[i++]=scanner.nextInt();
        }
        selectSort(a);

    }

    public static void selectSort(int[] array){
        int[] newArray=new int[array.length];
        int min;
        for(int i=0;i<array.length;i++){
            min=array[i];
            int temp;
            for (int j=i+1;j<array.length;j++){
                if(array[j]<min){
                    min=array[j];
                    temp=array[j];
                    array[j]=array[i];
                    array[i]=temp;

                }
            }
            newArray[i]=min;

        }
        for(int num:newArray){
            System.out.println(" "+num);
        }
    }
}

堆排序:

  堆排序是利用这种数据结构而设计的一种排序算法,堆排序是一种选择排序,它的最坏,最好,平均时间复杂度均为O(nlogn),它也是不稳定排序。

       堆排序是一种选择排序,整体主要由构建初始堆+交换堆顶元素和末尾元素并重建堆两部分组成。其中构建初始堆经推导复杂度为O(n),在交换并重建堆的过程中,需交换n-1次,而重建堆的过程中,根据完全二叉树的性质,[log2(n-1),log2(n-2)...1]逐步递减,近似为nlogn。所以堆排序时间复杂度一般认为就是O(nlogn)级。

堆排序Java实现:

package com.algorithm.sort;

/**
 * 堆排序
 */

public class HeapSort {
    public static void main(String[] args) {
        int[] array={39,44,1,0,33,12,37,28,16};
        HeapSort heapSort=new HeapSort();
        heapSort.heapSort(array);
        for(int i=0;i<array.length;i++){
            System.out.println(array[i]);
        }
    }

   public void heapSort(int[] a){
        if (a==null||a.length<=1){
            return;
        }
        //创建大堆
       buildMaxHead(a);
        for(int i=a.length-1;i>=1;i--){
            //最大元素已经排在下表为0的位置
            exchangeElements(a,0,i);//每交换一次沉淀一个最大元素
            maxHeap(a,i,0);
        }
   }

    private static void buildMaxHead(int[] a) {
        int half=(a.length-1)/2;
        for(int i=half;i>=0;i--){
            //只需遍历长度的一半
            maxHeap(a,a.length,i);
        }

    }
    //length表示用于构造大堆的数组长度元素数量
    private static void maxHeap(int[] a, int length, int i) {
        int left=i*2+1;
        int right=i*2+2;
        int largest=i;
        if(left<length&&a[left]>a[i]){
            largest=left;
        }
        if(right<length&&a[right]>a[largest]){
            largest=right;
        }
        if(i!=largest){
            //进行数据交换
            exchangeElements(a,i,largest);
            maxHeap(a,length,largest);
        }
    }
    //在数组a里面进行两个下表元素交换
    private static void exchangeElements(int[] a,int i,int largest) {
        int temp=a[i];
        a[i]=a[largest];
        a[largest]=temp;
    }
}
输出: 0 1 12 16 28 33 37 39 44

代码执行:

思路:

 a.将无需序列构建成一个堆,根据升序降序需求选择大顶堆或小顶堆;

 b.将堆顶元素与末尾元素交换,将最大元素"沉"到数组末端;

 c.重新调整结构,使其满足堆定义,然后继续交换堆顶元素与当前末尾元素,反复执行调整+交换步骤,直到整个序列有序。

链接:https://www.cnblogs.com/chengxiao/p/6129630.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值