经典排序算法

虽然很经典,虽然也很久了,但是我还是想发个博客啊哈哈哈,不好意思打扰了

二分查找(这个送的哈)

public static boolean binarySearch(final List<Integer> numbers, final Integer value) {
        if (numbers == null || numbers.isEmpty()) {
            return false;
        }
        final Integer comparison = numbers.get(numbers.size() / 2);
        if (value.equals(comparison)) {
            return true;
        }
        if (value < comparison) {
            return binarySearch(numbers.subList(0, numbers.size() / 2), value);
        } else {
            return binarySearch(numbers.subList(numbers.size() / 2, numbers.size()), value);
        }
    }

冒泡排序:

冒泡排序虽然很经典但是还是有可以优化的地方,如下,有优化的地方吗? 还是有的,比如[8,1,2,3,4,5,6,7], 只需一次就好了,那接下来的循环不就浪费了?可以设置一个标志位

    private void bubbleSort(int[] a) {
        boolean isSort;
        for (int i = 0; i < a.length; i++) {
            isSort = false;
            for (int j = 0; j < a.length - i - 1; j++) {
                if (a[j + 1] < a[j]) {
                    int temp;
                    temp = a[j + 1];
                    a[j + 1] = a[j];
                    a[j] = temp;
                    isSort = true;
                }
            }
            if (!isSort) {
                return;  //到此就结束了。
            }
        }
        System.out.println(Arrays.toString(a));
    }

堆排序:

public class HeapSort {


    private static int[] data = {3, 6, 23, 4, 3, 2, 9, 10, 18, 11};

    //建立大根堆
    public void buildMaxHeap(int[] data, int lastIndex) {
        //根据当前的lastIndex,计算对应的第一个父节点
        for (int i = lastIndex / 2; i >= 0; i--) {
            int k = i;
            while (2 * k + 1 <= lastIndex) {
                int biggerIndex = 2 * k + 1; //存放左右节点中最大的索引
                if (biggerIndex < lastIndex) { //说明有右节点
                    if (data[biggerIndex] < data[biggerIndex + 1]) {
                        biggerIndex++;          //存放左右节点中较大的
                    }
                }
                //如果当前的父节点小于左右子节点 中最大的,则进行交换
                if (data[k] < data[biggerIndex]) {
                    swap(data, k, biggerIndex);
                    k = biggerIndex;     //交换了之后上边满足了,可能下边又不满足了
                } else {     //如果是满足的那么停止掉while 循环
                    break;
                }
            }
        }
    }
    //交换两个节点的值
    public void swap(int[] data, int i, int j) {
        int tmp;
        tmp = data[i];
        data[i] = data[j];
        data[j] = tmp;
    }

    //排序主方法
    public void heapSort(int[] data) {
        for (int i = 0; i < data.length - 1; i++) {
            buildMaxHeap(data, data.length - 1 - i);
            //建立好一次大顶堆之后,交换第一个和最后一个,然后再进行剩余的建堆
            swap(data, 0, data.length - 1 - i);
            System.out.print("第" + i + "趟排序         ");
            System.out.println(Arrays.toString(data));
        }
    }

    @Test
    public void testHeapSort() {
        heapSort(data);
    }

插入排序:

//在原有的空间上进行插入排序
    private void insertSort(int[] a) {
        int insertNum; //存放要插入的数
        int arrayLength = a.length;
        for (int i = 1; i < arrayLength; i++) {
            insertNum = a[i];
            int j = i - 1;     //存放要比较的索引(当前已经排好序的部分)
            while (j >= 0 && a[j] > insertNum) {                 //循环将排好序的数都往后移动
                a[j + 1] = a[j];
                j--;
            }
            a[j + 1] = insertNum;
        }
    }
    //思路2 在新的集合中插入元素,比较简单,不再写

归并排序:

public List<Integer> mergetSort(final List<Integer> values) {
        if (values.size() < 2) {
            return values;
        }
        final List<Integer> leftHalf = values.subList(0, values.size() / 2); //from 包含,to 不包含
        final List<Integer> rightHalf = values.subList(values.size() / 2, values.size()); //from 包含,to 不包含
        return merge(mergetSort(leftHalf), mergetSort(rightHalf));
    }

    private List<Integer> merge(List<Integer> left, List<Integer> right) {
        final List<Integer> returnTo = new ArrayList<>(); //from 包含,to 不包含
        //记录左侧和右侧合并的位置
        int leftAttr = 0;
        int rightAttr = 0;
        while (leftAttr < left.size() && rightAttr < right.size()) {
            //执行合并
            if (left.get(leftAttr) < right.get(rightAttr)) {
                returnTo.add(left.get(leftAttr));
                leftAttr++;
            } else {
                returnTo.add(right.get(rightAttr));
                rightAttr++;
            }
            //将左侧剩余的或者右侧剩余的直接添加到集合之中
            while (leftAttr < left.size()) {
                returnTo.add(left.get(leftAttr));
                leftAttr++;
            }
            while (rightAttr < right.size()) {
                returnTo.add(right.get(rightAttr));
                rightAttr++;
            }
        }
        return returnTo;
    }

快速排序:

public static void main(String[] args) {
        List<Integer> list = quickSort(numbers);
        for (Integer integer : list) {
            System.out.print(integer + " ");
        }
    }

    public static List<Integer> quickSort(List<Integer> numbers) {
        if (numbers.size() < 2) {
            return numbers;
        }
        //基准
        final Integer pivot = numbers.get(0);
        final List<Integer> lower = new ArrayList<>();
        final List<Integer> higher = new ArrayList<>();
        for (int i = 1; i < numbers.size(); i++) {
            if (numbers.get(i) < pivot) {
                lower.add(numbers.get(i));
            } else {
                higher.add(numbers.get(i));
            }
        }

        final List<Integer> sorted = quickSort(lower);
        sorted.add(pivot);
        sorted.addAll(quickSort(higher));
        return sorted;

    }

简单选择排序:

/**
 * @author **
 * <p>
 * 常用于取序列中最大最小的几个数时。
 * (如果每次比较都交换,那么就是交换排序;如果每次比较完一个循环再交换,就是简单选择排序。)
 * 遍历整个序列,将最小的数放在最前面。
 * 遍历剩下的序列,将最小的数放在最前面。
 * 重复第二步,直到只剩下一个数。
 * <p>
 * 如何写成代码:
 * 首先确定循环次数,并且记住当前数字和当前位置。
 * 将当前位置后面所有的数与当前数字进行对比,小数赋值给key,并记住小数的位置。
 * 比对完成后,将最小的值与第一个数的值交换。
 * 重复2、3步。
 */

public class SimpleSelectionSort {

    private static int a[] = {2, 1, 5, 8, 7, 6};

    public static void main(String[] args) {
        simpleSelectionSort(a);
        for (int i = 0; i < a.length; i++) {
            System.out.print(a[i] + " ");
        }
    }

    //执行排序的方法
    public static void simpleSelectionSort(int a[]) {
        int length = a.length;
        for (int i = 0; i < length; i++) {         //循环次数
            int key = a[i];                 //刚开始先假设剩下没有排序的第一个为最小值,以后不断更新这两个值
            int position = i;
            for (int j = i + 1; j < length; j++) { //从剩下的序列中找出最小的值,和其位置
                if (a[j] < key) {     //如果查找到值小于当前找到的最小值,则更新最小值和最小值所在的位置
                    position = j;
                    key = a[j];
                }
            }
            a[position] = a[i];
            a[i] = key; //最小值赋值给需要排的当前位
        }
    }

}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值