zoukankan      html  css  js  c++  java
  • 数据结构学习笔记3:尝试手写一个插入排序

    之前我们说过了冒泡排序,现在我们再来看一个经常和冒泡排序拿出来比较的排序算法插入排序,为什么要学习数据模型和算法,为什么有现成的轮子还要自己再动手去写等等,这些问题的原因我都写在这里面了,欢迎大家批评斧正。

    冒泡排序

    插入排序

    老规矩,学习算法三板斧。

    第一斧:学习其原理思想

    插入排序我们可以将整个数组看做两个区间,分别是已排序区间和未排序区间。百度百科中对插入排序的基本思想描述如下:

    插入排序的工作方式像许多人排序一手扑克牌。开始时,我们的左手为空并且桌子上的牌面向下。然后,我们每次从桌子上拿走一张牌并将它插入左手中正确的位置。为了找到一张牌的正确位置,我们从右到左将它与已在手中的每张牌进行比较。拿在左手上的牌总是排序好的,原来这些牌是桌子上牌堆中顶部的牌 。

    插入排序是指在待排序的元素中,假设前面n-1(其中n>=2)个数已经是排好顺序的,现将第n个数插到前面已经排好的序列中,然后找到合适自己的位置,使得插入第n个数的这个序列也是排好顺序的。按照此法对所有元素进行插入,直到整个序列排为有序的过程,称为插入排序 。

    看明白了吗?如果没有看明白也没有关系,我们可以举一个具体的例子,画图看看。

    第二斧:“举例+画图”理解思想

    我们来举个例子,假设我们手头有一个int类型的数组a,它包含的元素为8 7 1 2 3 6 9

    int[] a = new int[]{8,7,1,2,3,6,9};
    

    那按照插入排序的思想,将数组分为两个区间,一个是已经排序的另外一个是没有排序的。很显然目前这个数组肯定是完全没有排序的,那么我们是否可以这么理解,当前这个数组结构的已排序区间为【】未排序区间为【8,7,1,2,3,6,9】。那我们仅需要将未排序区间内的元素逐个插入到已排序的区间内就好啦。

    还有点晕吗?那来吧,遇事不决就画图(图中红色的部分代表已排序区间,黄色的部分代表未排序区间):

    image-20200701142004756

    我们跟着图来看一下插入排序的过程是怎么样的。

    第一次插入的时候,将未排序区间中的第一个元素8插入了已排序区间中,因为这个时候已排序区间中没有元素,所以这里就相当于自旋了一下,并没有实际的发生插入操作。

    第二次插入的时候,将未排序区间中的第一个元素7插入了已排序区间中,开始从已排序区间的第0位开始遍历,那已排序区间的第0位是8。那7>8,所以将7插入到8的前面

    依次类推指导未排序区间中一个元素都没有了。

    第三斧:show me the code

    到现在位置大家已经看完了插入排序的原理和流程了,相信大家在脑海中对插入排序都有一个大概的认识了,那我们现在趁着印象很深,都动手写一个插入排序算法。

        public void insertSort(int[] items) {
            if (items.length <= 1) {
                return;
            }
            for (int i = 1; i < items.length; i++) {
                int value = items[i];
                int j = i - 1;
                // 循环遍历已排序部分
                for (; j >= 0; j--) {
                    // 如果当前元素比希望插入的元素大,则触发数据迁移
                    if (items[j] > value) {
                        items[j + 1] = items[j];
                    } else {
                        // 说明在已排序剩余的部分数据都比items小,没必要进行数据迁移了。
                        break;
                    }
                }
                // 数据迁移完成,将比较的数据插入希望插入的位置
                items[j + 1] = value;
            }
        }
    

    学习算法其实没啥诀窍,最简单就是最笨的办法,就是多看原理然后多写代码。如果后面你可以比着你自己画的图写出代码实现功能,就已经入门啦~

  • 相关阅读:
    对xml的操作使用的类XElement的使用
    在js和C#中split应用和去除字符串分组后的空值
    C# 预定义语言
    C# 中利用 Conditional 定义条件方法
    快速结束占用端口
    详解C++中命名空间的意义和用法
    Template、ItemsPanel、ItemContainerStyle、ItemTemplate
    C++入门(2)
    C++入门(1)
    VS中的配置管理器
  • 原文地址:https://www.cnblogs.com/joimages/p/13219133.html
Copyright © 2011-2022 走看看