java排序算法2(简单选择排序、堆排序)

简单选择排序---不稳定

选择排序在未排序序列中找到最小(大)元素,存放到排序序列的起始位置,然后以此类推,直到所有元素均排序完毕。

        for (int i = 0; i < arr.length; i++) {
            //记录最小值下标位置
            int min=i;
            for (int j=i+1;j<arr.length;j++){
                if (arr[i]>arr[j]){
                    min=j;
                }
            }
            //交换位置
            if (min != i) {
                int tmp=arr[i];
                arr[i]=arr[min];
                arr[min]=tmp;//如果有两个相同的值,2,2,1,这种情况,第一次排序时,第一个2到了1的位置,所以排序不稳定
            }
        }
平均时间复杂度 最坏 最好 空间复杂度
O(n²) O(n²) O(n²) O(1)

堆排序---不稳定

预备知识

image

1.父结点索引:(i-1)/2(这里计算机中的除以2,省略掉小数)
2.左孩子索引:2i+1
3.右孩子索引:2
i+2
升序用大顶堆,降序用小顶堆。

	//维护堆,参数为数组和当前需要维护的根节点,len表示堆中有多少元素
    public void heapify(int[] arr,int len, int i) {
        // 最大值节点
        int max = i;
        int lChild = i * 2 + 1;
        int rChild = i * 2 + 2;
        //找出孩子节点中最大的那个值,然后交换
        if (lChild < len && arr[lChild] > arr[max]) {
            max=lChild;
        }
        if (rChild < len && arr[rChild] > arr[max]) {
            max=rChild;
        }
        //交换节点位置
        if (max != i) {
            swep(arr,i,max);
            //递归维护之后的节点
            heapify(arr,len,max);
        }
    }
    //交换节点
    public void swep(int[] arr,int i,int j){
        int tmp=arr[i];
        arr[i]=arr[j];
        arr[j]=tmp;
    }

    //堆排序
    public void heapSort(int[] arr) {
        //建堆,i表示最后一个非叶子节点
        for (int i = arr.length/2-1; i >=0; i--) {
            heapify(arr,arr.length,i);
        }
        //排序,将堆顶元素和最后一个元素交换,然后将最后一个元素移除堆,维护堆,再将倒数第二个元素和堆顶元素交换......
        for (int j = arr.length - 1; j >0 ; j--) {
            swep(arr,j,0);
            //最后一个元素不需要参与维护,所以长度是arr.length-1,一次减少一次
            heapify(arr,j,0);
        }
    }

1.建立堆的过程, 从length/2 一直处理到0, 时间复杂度为O(n);
2.调整堆的过程是沿着堆的父子节点进行调整, 执行次数为堆的深度, 时间复杂度为O(lgn);
3.堆排序的过程由n次第2步完成, 时间复杂度为O(nlgn).

平均时间复杂度 最坏 最好 空间复杂度
O(nlog2n) O(nlog2n) O(nlog2n) O(1)
posted @ 2023-04-24 21:23  一个苦逼的23届毕业生  阅读(9)  评论(0编辑  收藏  举报