常见排序算法总结——2、插入排序

常见排序方法

原创文章,转载请添加本网页链接
https://blog.csdn.net/qq_37334950/article/details/104378361

2、插入排序:将数组分为有序组(数组的第一个元素)和无序组(数组的第二个元素~最后一个元素),每次取出无序组的第一个元素,经过比较插入有序组的合适位置

举例:
   初始数组:9 3 4 2 6 7 5 1
     分组:(9)(3 4 2 6 7 5 1) 9为有序组,3~1为无序组
  第一次插入:(3 9)(4 2 6 7 5 1) 将无序组的3取出,插入有序组9的前面
  第二次插入:(3 4 9)(2 6 7 5 1) 将无序组的4取出,插入有序组9的前面
  第三次插入:(2 3 4 9)(6 7 5 1) 将无序组的2取出,插入有序组3的前面
  第四次插入:(2 3 4 6 9)(7 5 1) 将无序组的6取出,插入有序组9的前面
  第五次插入:(2 3 4 6 7 9)(5 1) 将无序组的7取出,插入有序组9的前面
  第六次插入:(2 3 4 5 6 7 9)(1) 将无序组的5取出,插入有序组6的前面
  第七次插入:(1 2 3 4 5 6 7 9) 将无序组的1取出,插入有序组2的前面,至此无序组已经没有元素,所有元素均正序在有序组内

分析:进行了(n-1)次插入,第一次插入判断1次,第二次插入最多判断2次,最后一次插入最多判断(n-1)次,总计最少(n-1)1=(n-1)次,最多(n-1)[1+2+…+(n-1)]=(n-1)*n/2次。

代码逻辑:首先将初始数组list拆分为有序数组orderedList和无序数组unorderedList,其中有序数组orderedList里面有初始数组list的第一个元素,无需数组unorderedList里面有初始数组list的第二至最后一个元素。然后进行(n-1)次for循环A代表(n-1)次插入。接着在A的内部进行一个以1至(n-1)为上限的循环B代表比较的次数,最后循环B的内部比较元素大小,通过判断并插入元素后使用break跳出当前循环B,进行下一轮的循环B。

代码示例(代码工具-AS):

    public static void main(String args[]){
        ArrayList<Integer> list = new ArrayList<>();
        list.add(9);
        list.add(3);
        list.add(4);
        list.add(2);
        list.add(6);
        list.add(7);
        list.add(5);
        list.add(1);

        log(list,"默认数组:");//打印数组
        /**
         * 插入排序
         */
        int i = list.size();
        ArrayList<Integer> orderedList = new ArrayList<>(list.subList(0, 1));//有序组为第一个元素
        ArrayList<Integer> unorderedList = new ArrayList<>(list.subList(1, list.size()));//无序组为第二至最后一个元素
        for (int j = 1; j < i; j++) {
            int k = orderedList.size();
            int m = unorderedList.get(0);
            System.out.print("第" + j + "次插入,取得插入值为:" + m);
            for (int l = 0; l < k; l++) {
                if (orderedList.get(l) >= m){
                    orderedList.add(l,m);
                    System.out.println(",插入位置为:" + (l+1));
                    break;
                } else if (l==(k-1)){//走到这一步说明有序组的所有元素都比待插入元素小,需要在当前完成插入到最后一个元素后面的操作
                    orderedList.add(k,m);
                }
            }
            unorderedList.remove(0);
            log(orderedList,"当前有序组结果为:");//打印数组
        }

        log(orderedList,"最终结果为");//打印数组
    }
    /**
     * 打印数组
     * @param list 要打印的数组
     * @param string 打印前缀
     */
    private static void log(ArrayList<Integer> list,String string){
        String s = "";
        for (int m = 0; m < list.size(); m++) {
            if (m == 0){
                s = list.get(0)+"";
            } else {
                s = s + "," + (list.get(m)+"");
            }
        }
        if (string == null){
            System.out.println("--打印数组:" + s);
        } else {
            System.out.println(string + s);
        }
    }

结果一览:
在这里插入图片描述
结果分析:示例数组经过7次插入,(1+2+1+4+5+4+1)=18次比较后排序成功。对于插入排序来说,如果需要经过最少次的比较得到结果,每次至少都比较1次,意味着每次的插入值都比上一个值小,那么原数组需要完全倒序;如果需要经过最多次的比较得到结果,意味着每次的插入值都比上一个值大,那么原数组就是一个正序的数组。插入排序的性能结论:对于一个数组来说,如果它越偏向正序,则越耗费时间;如果它越偏向倒序,则越节省时间。

发布了2 篇原创文章 · 获赞 1 · 访问量 177

猜你喜欢

转载自blog.csdn.net/qq_37334950/article/details/104378361