数据结构与算法的第二天 原创

Piwriw.
发布于 2022-1-19 18:05
浏览
0收藏

春节不停更,此文正在参加「星光计划-春节更帖活动」

前言

  • 这是我在51CTO春节不停更,此文正在参加「星光计划-春节更帖活动」第三天的第三篇文章了,看到我之前写的文章的小伙伴应该也知道我计划在这次活动中,跟大家分享一下,我学习数据结构与算法的一些心得,可能分享的程度由于我自身能力,更加偏向于新手向,但是我希望大家有耐心看完的话,一定会有自己的感悟,话不多说,让我们开始吧:laughing::laughing::laughing:
  • 由于本人能力有限,在过程中难免会出现错误,以及可能也有存在更好的代码,希望大家在评论区发现错误也能留言,大家一起来讨论这个问题:two_hearts:

最“爱”的排序

  • 大家看到这个title的时候,脑子闪过的应该是什么排序呢?我想大家应该都有属于的答案。但是你会不会跟我一个第一个想到的是选择排序插入排序。 其实原因也很简单,因为这是我们学习排序的时候,大家最先接触到的排序算法,以及可以说说我们最好理解的排序算法,我也个人认为它是很暴力的遍历算法。当然了,在这情况下,由于能量守恒定律,它的时间复杂度达到了不太好的0(n^2),但是我们也会经常使用这二个排序是为什么呢?,下面我给出一个表格

    O(n) O(nlogn) O(n^2)
    1 趋近于0 1
    10 10 100
    100 200 10000
    1000 3000 1000000
    • 这里由于我的log底数取10,但是一般情况下我们实际中是以2为底数,此时logn会增大
    • 我们不难发现其实在n数据量小的时候,我们O(n^2),这个时间复杂度我们还是可以接受的,但是随着n的增大,这个增大过快了,举个例子,当我们做一个计算的时候,我们使用的是O(n)的时候需要一百天,但是O(n^2)就大概需要27年,这是我们没办法接受的

什么是选择排序?

  • 第一次从待排序的数据元素中选出最小(或最大)的一个元素,存放在序列的起始位置,然后再从剩余的未排序元素中寻找到最小(大)元素,然后放到已排序的序列的末尾。以此类推,直到全部待排序的数据元素的个数为零。
  • 其实就是每次都找一个max或者min作为基准,也就是我们只处理了一个数据,所以也是导致了它需要不断遍历的过程,但是它理解起来,更符合我们的认知,就好比(这里我以从max交换),我要从给一堆学生成绩排序,我以我手中拿到的一份试卷成绩为基准,然后去翻一遍所有的学生成绩,如果拿到学生的成绩大于了我手上的试卷成绩,那么我就更新一下我手上试卷的成绩,不然我就什么也不做
    • 其实这里我们是在以一个为基准,不断更新的基准的过程

代码实现

/**
 * @Author Piwriw.
 * @Date 2022/1/19 
 * @motto 你不能做我的诗,正如我不能做你的梦.
 */

/**
 * 选择排序
 */
public class SelectSort {
    private SelectSort() {
    }

    public static <E extends Comparable<E>> void sort(E[] arr) {
        for (int i = 0; i < arr.length; i++) {
            int minIndex = i;
            for (int j = i; j < arr.length; j++) {
                if (arr[j].compareTo(arr[minIndex]) < 0) {
                    minIndex = j;
                }
            }
            swap(arr, i, minIndex);
        }
    }

    private static <E> void  swap(E[] arr, int i, int j) {
        E t = arr[i];
        arr[i] = arr[j];
        arr[j] = t;
    }
}

什么是插入排序

  • 插入排序是一种最简单的排序方法,它的基本思想是将一个记录插入到已经排好序的有序表中,从而一个新的、记录数增1的有序表。在其实现过程使用双层循环,外层循环对除了第一个元素之外的所有元素,内层循环对当前元素前面有序表进行待插入位置查找,并进行移动
  • 其实插入排序就是,正如其名字,把数据插入,相比于选择排序,我们的插入排序其实是在没有排序好的里面,排序,我们拍好的就不会再搜索,下面我同时也举一个例子,就是一排人抢位置坐,第一次的时候找谁坐第一个位置,注意我们其实主要在乎的是第一个位置,然后筛选完,这个时候第一个位置就已经确定好是谁坐,后面的第二次排序我们从第二个开始,这个时候,第一个座位和人是不再参加了(这里可能跟选择排序听起来有点差不多,但是确实是不同角度的,希望大家可以多多思考一下)
  • 其实大家应该有人能发现,我们其实和选择排序最大的区别就是,如果我这个已经是有序的时候,我们这时候插入排序的算法是O(n),所以插入排序也是一个不稳定的排序,如果你还是分不清楚选择排序和插入排序,就可以从这里入手去再分析一次:grin:

代码实现

/**
 * @Author Piwriw.
 * @Date 2022/1/19
 * @motto 你不能做我的诗,正如我不能做你的梦.
 */
 
/**
 * 插入排序
 * 时间复杂度 最坏n*n,最快 n
 */
public class InsertionSort {
    private InsertionSort() {
    }

    public static <E extends Comparable<E>> void sort(E[] arr) {
        for (int i = 0; i < arr.length; i++) {
            for (int j = i; j > 0 && arr[j].compareTo(arr[j - 1]) < 0; j--) {
                swap(arr, j, j - 1);
            }
        }
    }

    public static <E extends Comparable<E>> void sort2(E[] arr) {
        for (int i = 0; i < arr.length; i++) {
            E temp = arr[i];
            int j;
            for (j = i; j > 0 && temp.compareTo(arr[j - 1]) < 0; j--) {
                arr[j] = arr[j - 1];
            }
            arr[j] = temp;
        }
    }

    private static <E> void swap(E[] arr, int i, int j) {
        E t = arr[i];
        arr[i] = arr[j];
        arr[j] = t;
    }

}

总结

  • 今天我们就先讲解插入和选择排序,大家理解一下今天的内容,其实还是比较简单的:smirk:,对于大家当然是Easy,划一划水就能学会啦,今天我们所讲的是算法部分,明天我们讲的是数据结构,我们将会学习Stack栈和Queue队列,相对于今天的内容,明天对于没有接触过的同学是属于新的知识了。
  • 今天的习题,也比较简单,我就给出一道洛谷上一道虚假的普及-难度P1104 生日;
  • 这里是:春节不停更,此文正在参加「星光计划-春节更帖活动」,本人正在计划在这次活动中,跟大家分享一下,我学习数据结构与算法的心得,这是数据结构第二天的选择排序和插入排序:laughing::laughing::laughing:

©著作权归作者所有,如需转载,请注明出处,否则将追究法律责任
分类
已于2022-1-19 19:59:02修改
收藏
回复
举报
回复
    相关推荐