常用排序算法(一)

刷题过程中对常用的排序算法有遗忘,所以写一篇笔记。

一、冒泡排序

一种简单的排序算法,重复地走过要需要排序的序列,比较相邻两个元素的大小。依次将较大的元素放到数组的末尾,或是依次将较小的元素放到数组的首部,直到走访工作全部结束。

1、算法过程

比较相邻的元素,如果顺序错误就交换

对每一对相邻元素都做相同的工作,从第一对比到最后一对

已经放到最后的元素在下一轮就不需要比较了,因为它已经是当前轮次最大的元素

2、代码

public int[] bubbleSort(int[] nums){
    for(int i = 0; i < nums.length - 1; i++){
        for(int j = 0; j < nums.length - 1 - i; j++){
            if(nums[j] > nums[j+1]){
                int temp = nums[j];
                nums[j] = nums[j+1];
                nums[j+1] = temp;
            }
        }
    }
    return nums;
}

二、选择排序

简单直观的排序算法,算法过程是在未排序的序列中,找到最大/最小的元素,将其放到队尾/队首。依次循环

1、算法描述

n个元素的排序经过n-1次排序得到最终结果,以找到最大元素为例

初始状态:全都是无序

排序时:数组后方元素是有序的,是一个递增序列。前半部分元素还是无序的状态

2、代码

public class SelectionSort {
    public int[] selectionSort(int[] nums){
        for(int i = 0; i < nums.length; i++){
            int minIndex = i;
            for(int j = i+1; j < nums.length; j++){
                if(nums[j] < nums[minIndex]){
                    minIndex = j;
                }
            }
            int temp = nums[i];
            nums[i] = nums[minIndex];
            nums[minIndex] = temp;
        }
        return nums;
    }
}

三、插入排序

逐步构建有序序列,对于未排序的数据,在已排序的序列中扫描,找到对应的位置插入

1、算法描述

从第一个元素开始,默认已经排序

取出下一个元素,在已排序的元素中从后往前扫描

如果该元素大于新元素,就将元素移到下一个位置

找到新元素对应的位置,把该位置设置为新元素即可

2、代码

public static int[] insertSort(int[] nums){
        for(int i = 1; i < nums.length; i++){
            //当前i位置的元素为新元素
            //在已排序的序列中依次判断,大于新元素就后移,否则就插入
            int pre = i - 1;
            int cur = nums[i];
            //这里一定用cur保存nums[i]的值,因为nums[pre+1]的值可能会被修改
            while(pre >= 0 && nums[pre] > cur){
                nums[pre + 1] = nums[pre];
                pre--;
            }
            nums[pre+1] = cur;
        }
        return nums;
    }

四、希尔排序

希尔排序比一般O(n²)排序的速度要快很多,适用于中小规模的排序。

1、算法描述

将要排序的序列按照一定的间隔分组,先进行组内排序。

每轮完成之后缩小间隔,继续在组内排序

初始间隔大小gap = nums.length / 2,这是希尔推荐的

2、代码

代码部分还是值得思考的。

public static void shellSort(int[] nums){
        for(int gap = nums.length / 2; gap > 0; gap = gap / 2) {
            //大循环是进行一次各组内的排序
            for (int i = gap; i < nums.length; i++) {
                int j = i;
                int temp = nums[j];
                //开始各组内排序
                while (j - gap >= 0 && temp < nums[j - gap]) {
                    nums[j] = nums[j - gap];
                    j -= gap;
                }
                nums[j] = temp;
            }
        }
    }

五、归并排序

归并的核心思想就是分治。不断地将要排序的数组分为若干小分组。当小分组的大小为1,直接合并即可。

1、算法描述

把长度为n的序列分为长度为n/2的两个子序列

在子序列中进行归并

两个子序列归并后成为一个完整的有序序列

2、代码

public class MergeSort {
    public static void main(String[] args) {

    }
    public static void sort(int[] nums){
        int[] temp = new int[nums.length];
        sort(nums,0,nums.length - 1,temp);
    }
    public static void sort(int[] nums,int left,int right,int[] temp){
        if(left < right){
            int mid = (left + right) / 2;
            sort(nums,left,mid,temp);
            sort(nums,mid+1,right,temp);
            merge(nums,left,mid,right,temp);
        }
    }

    private static void merge(int[] nums, int left, int mid, int right, int[] temp) {
        int i = left;
        int j = mid + 1;
        int t = 0;
        if(i <= mid && j <= right){
            if(nums[i] <= nums[j]){
                temp[t++] = nums[i++];
            }else{
                temp[t++] = nums[j++];
            }
        }
        while(i <= mid){
            temp[t++] = nums[i++];
        }
        while(j <= right){
            temp[t++] = nums[j++];
        }
        t = 0;
        //将temp中的元素拷贝到原数组中
        while (left <= right){
            nums[left++] = temp[t++];
        }
    }
}

()

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值