Java:几种排序算法对比

直接插入排序
插入排序就是:取出一个数,插入到有序数组中,首先,取出第一个元素放入有序数组中,然后取出第二个,两个数进行比较,如果它小,则有序数的最后一个向后移动一格,然后与有序数组倒数第二个比较,如果小,则继续向后移动。如果碰到比它小的,则插入在其后面。
算法思想为:外层循环是遍历数组的所有值 内层循环是,找到小于该值的下标,然后大于该下标的值向后移动。

public static void insertSort(int[] array) {
        for (int i = 0; i < array.length; i++) {
            int j;
            for (j = i - 1; j >= 0 && array[i] < array[j]; j--){
            }
            int pos=j+1;
            int key=array[i];
            //把大于key的值都向后移动
            for(int k=i;k>pos;k--){
                array[k]=array[k-1];
            }
            //在pos位置插入key
            array[pos]=key;
        }
    }

选择排序
选择排序的主要思想:首先找出整个数组中最小的一个数,然后第一个数和最小的数进行交换,然后,继续寻找最小的数,然后和数组第二个数进行交换。

 public static void selectSort(int[] array) {
        for (int i = 0; i < array.length; i++) {
            int min = i;
            //找到最小值的下标
            for (int j = i + 1; j < array.length; j++) {
                if (array[j] < array[min]) {
                    min = j;
                }
            }
            swap(array, min, i);
        }
    }

    public static void swap(int[] array, int a, int b) {
        int tmp;
        tmp = array[a];
        array[a] = array[b];
        array[b] = tmp;
    }

冒泡排序
冒泡排序思想:首先从第一个数开始,将其作为最大的数,然后和下一个数进行比较,然后进行交换,永远保持大的数在后面,这样没进行一次循环都会找出一个最大的数,最终,最大的数会在数组的最后去

//优化版本
 public static <T extends Comparable<T>> void bubbleSort(T[] t) {
        boolean swap = true;
        for (int i = 0; i < t.length && swap; i++) {
            swap = false;
            for (int j = 1; j < t.length - i - 1; j++) {
                if (t[j].compareTo(t[j + 1]) > 0) {
                    T tmp = t[j];
                    t[j] = t[j + 1];
                    t[j + 1] = tmp;
                    swap = true;
                }
            }
        }
    }
 public static void bubbleSort(int[] array) {
        for (int i = 0; i < array.length-1; i++) {
            for (int j = 0; j < array.length - i - 1; j++) {
                if (array[j] > array[j+1]) {
                        int tmp = array[a];
        				array[a] = array[b];
      				  array[b] = tmp;
                }
            }
        }
    }

堆排序
堆排序基本思路:首先创建一个大堆,将最大的元素放在最上面,然后再与最后一个元素交换,原来有N个数,现在最大的在最后面,去除后,剩余的N-1个数再进行创建大堆,然后再进行交换,直到个数变为1,这个时候就是完整的排序

static void heapSort(int[] array) {
        for (int i = array.length / 2 - 1; i >= 0; i--) {
            //调整堆,使所有的双亲节点都大于子节点
            heapify(array, i, array.length);
        }
        //初步调整完毕,取出最顶上的节点,然后与最后一个结点交换,除去最后一个节点,然后继续调整堆,使所有的双亲节点都大于子节点
        for (int j = array.length - 1; j > 0; j--) {
            swap(array, 0, j);
            //交换最后第一个和最后一个,去除最后一个,再进行调整
            heapify(array, 0, j);
        }
    }

    static void heapify(int[] arr, int i, int length) {
        //找到非叶子节点
        int tmp = arr[i];
       //找到其子节点
        for (int k = 2 * i + 1; k < length; k = 2 * k + 1) {
            //比较两个子节点的大小
            if (arr[k] < arr[k + 1] && k + 1 < length) {
                k++;
            }
            //比较子节点与父节点的大小
            //谁大谁在上
            if (tmp < arr[k]) {
                arr[i] = arr[k];
                i = k;
            } else {
                break;
            }
        }
        //此时顶上的数为arr[k],  k位置的数应该变为tmp
        arr[i]=tmp;
    }

    //交换堆顶元素与最后一个元素
    public static void swap(int[] array, int a, int b) {
        int tmp;
        tmp = array[a];
        array[a] = array[b];
        array[b] = tmp;
    }

归并排序
归并排序思想:采用分治算法,将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。

 //归并排序
    public static void mergeSort(int[] array) {
        //创建一个额外的空间
        int[] extra = new int[array.length];
        mergeSortInner(array, 0, array.length, extra);
    }

    //进行分组
    public static void mergeSortInner(int[] array, int low, int high, int[] extra) {
        //分组结束条件,等于0或者只有一个数
        if (low == high - 1) {
            return;
        }
        if (low >= high) {
            return;
        }
        //满足分组条件 进行分组
        int mid = low + (high - low) / 2;
        //运用递归 一直分组
        //分左边的分组
        mergeSortInner(array, low, mid, extra);
        //分右边的分组
        mergeSortInner(array, mid, high, extra);
        //此时分组已经分好,这个时候要进行合并,然后排序。
        merge(array, low, mid, high, extra);
    }

    //两个分组进行排序合并
    public static void merge(int[] array, int low, int mid, int high, int[] extra) {

        int i = low;
        int j = mid;
        int x = 0;
        //遍历数组,按大小将数排入到extra中
        while (i < mid && j < high) {
            if (array[i] <=array[j]) {
                extra[x++] = array[i++];
            } else {
                extra[x++] = array[j++];
            }
        }
        //如果i>mid,说明左边的已经全部都放入extra中,此时直接将右边有序的插入到后面
        while (j < high) {
            extra[x++] = array[j++];
        }
        //如果j>high,说明右边的已经全部都放入extra中,此时直接将左边有序的插入到后面
        while (i < mid) {
            extra[x++] = array[i++];
        }
        //最后将extra已经排好的数放入到array中
        for (int k = low; k < high; k++) {
            array[k] = extra[k - low];
        }
    }

快速排序
快速排序主要思想::任取待排序元素序列中 的某元素作为基准值,按照该排序码将待排序集合分割成两子序列,左子序列中所有元素均小于基准值,右 子序列中所有元素均大于基准值,然后最左右子序列重复该过程,直到所有元素都排列在相应位置上为止。

public static void quickSort(int[] array, int low, int high) {
        //递归终止条件
        if (low > high) {
            return;
        }

        int i = low, j = high, tmp = array[low], t;
        while (i < j) {
            //找到一个比基准值小的数
            while (tmp <= array[j] && i < j) {
                j--;
            }
            //找到一个比基准值大的数
            while (tmp >= array[i] && i < j) {
                i++;
            }
            //找到比基准值大的和比基准值小的数。进行交换
            if (i < j) {
                t = array[j];
                array[j] = array[i];
                array[i] = t;
            }
        }
        //以上操作已经将所有大于和小于基准值的数分好。
        //此时再将基准值放进去
        array[low] = array[i];
        array[i] = tmp;

        //递归进行左右数组,进行上述步骤
        quickSort(array, low, j - 1);
        //递归调用右半数组
        quickSort(array, j + 1, high);
    }

在这里插入图片描述

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值