堆排序和归并排序 java代码实现

堆排序

java代码实现

package csdn.dreamzuora.sort;

import java.util.List;

/**
 * Title: 抽象出排序类
 * Description:
 *
 * @version 1.0
 * @author: weijie
 * @date: 2020/10/22 17:59
 */
public abstract class Sort<E> {


    public void sort(List<E> array){
        if (array == null || array.isEmpty()){
            return;
        }
    };

    public void sort(List<E> array, int left, int right){

    };

}

package csdn.dreamzuora.sort;

import java.util.List;

/**
 * Title: 堆排序
 * Description:
 *
 * @version 1.0
 * @author: weijie
 * @date: 2020/10/22 17:51
 * @url https://www.cnblogs.com/rosesmall/p/9554545.html
 */
public class HeapSort extends Sort<Integer>{

    @Override
    public void sort(List<Integer> array) {
        //1.构建大顶堆
        for(int size = array.size(), i = size / 2 - 1; i >= 0; i--){
            //从第一个非叶子结点从下至上,从右至左调整结构
            adjustHeap(array, i, size);
        }
        //2.调整堆结构、交换堆顶元素与末尾元素
        for (int j = array.size() - 1; j > 0; j--){
            swap(array, 0, j);
            adjustHeap(array, 0, j);
        }
    }

    /**
     * 调整大顶堆(仅是调整过程,建立在大顶堆已构建的基础上)
     * @param arr
     * @param i
     * @param length
     */
    public void adjustHeap(List<Integer> arr, int i, int length){
        //先取出当前元素i
        int temp = arr.get(i);
        //从i结点的左子结点开始,也就是2i+1处开始
        for(int k = i*2 + 1; k < length; k = k*2 + 1){
            //如果左子结点小于右子结点,k指向右子结点
            if(k+1 < length && arr.get(k) < arr.get(k+1)){
                k++;
            }
            //如果子节点大于父节点,将子节点值赋给父节点(不用进行交换)
            if(arr.get(k) > temp){
                arr.set(i, arr.get(k)) ;
                i = k;
            }else{
                break;
            }
        }
        //将temp值放到最终的位置
        arr.set(i, temp);
    }

    private void swap(List<Integer> arr, int a, int b){
        int temp = arr.get(a);
        arr.set(a, arr.get(b));
        arr.set(b, temp);
    }
}

单元测试

package csdn.dreamzuora.sort;

import org.junit.Test;
import org.junit.jupiter.api.Assertions;

import java.util.Arrays;
import java.util.List;

import static org.junit.Assert.*;

/**
 * Title:
 * Description:
 *
 * @version 1.0
 * @author: weijie
 * @date: 2020/10/26 23:14
 */
public class HeapSortTest {

    @Test
    public void sort() {
        HeapSort heapSort = new HeapSort();
        List<Integer> list = Arrays.asList(4, 5, 2, 6);
        heapSort.sort(list);
        Assertions.assertEquals(Arrays.asList(2, 4, 5, 6), list);
    }
}

归并排序

java代码实现

package csdn.dreamzuora.sort;

import java.util.ArrayList;
import java.util.List;

/**
 * Title: 归并排序
 * Description:
 * 将数组进行拆分,拆分后按照一定的顺序各自排序,然后再归并到一起,使得归并后的数组仍然有序
 *
 * 归并排序算法可以利用递归的思想或者迭代的思想去实现。首先我们先把一个无序的数组去拆分,然后利用一定的规则,去合并。
 * 类似于二叉树的结构。其总的时间复杂度为O( n log n)。空间复杂度为 S(nlogn)
 *
 * @version 1.0
 * @author: weijie
 * @date: 2020/10/22 17:51
 * @url: https://blog.csdn.net/dreamzuora/article/details/52830740
 */
public class MergeSort extends Sort<Integer>{

    @Override
    public void sort(List<Integer> a) {
        if (a == null || a.isEmpty()){
            return;
        }
        List<Integer> b = new ArrayList<>();
        for (int i = 0; i < a.size(); i++){
            b.add(0);
        }
        merge(a, b,0, a.size());
        for (int i = 0; i < b.size(); i++){
            a.set(i, b.get(i));
        }
    }

    private void merge(List<Integer> a, List<Integer> b, int start, int end){
        //递归出口
        if (end - start <= 1){
            return;
        }

        int mid = (start + end)/2;
        int left = start;
        int right = mid;
        int index = start;

        //递归入口
        merge(a, b, start, mid);
        merge(a, b, mid, end);

        //核心处理
        while (left < mid || right < end){
            //右区间遍历完成,直接取左区间值
            if (right >= end){
                b.set(index ++, a.get(left ++));
            }
            else if (left < mid && a.get(left) < a.get(right)){
                b.set(index ++, a.get(left ++));
            }
            else {
                b.set(index ++, a.get(right ++));
            }
        }

        //原数组赋值
        for (int i = start; i < index; i++){
            a.set(i, b.get(i));
        }
    }

}

单元测试

package csdn.dreamzuora.sort;

import org.junit.Test;
import org.junit.jupiter.api.Assertions;

import java.util.*;

import static org.junit.Assert.*;

/**
 * Title:
 * Description:
 *
 * @version 1.0
 * @author: weijie
 * @date: 2020/10/28 10:51
 */
public class MergeSortTest {

    @Test
    public void sort() {
        MergeSort mergeSort = new MergeSort();
        Random random = new Random();
        List<Integer> actuallyList = Arrays.asList(random.nextInt(100), random.nextInt(100), random.nextInt(100), random.nextInt(100), random.nextInt(100), random.nextInt(100));
        List<Integer> expectList = new ArrayList<>(actuallyList);
        Collections.sort(expectList);
        mergeSort.sort(actuallyList);
        Assertions.assertEquals(expectList, actuallyList);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值