插入排序

插入排序

源自济南黑马程序员教程

一、插入排序(Insertion sort)

是一种简单直观且稳定的排序算法。

1. 排序原理

1.把所有的元素分为两组,已经排序的和未排序的;
2.找到未排序的组中的第一个元素,向已经排序的组中进行插入;
3.倒叙遍历已经排序的元素,依次和待插入的元素进行比较,直到找到一个元素小于等于待插入元素,那么就把待
插入元素放到这个位置,其他的元素向后移动一位;

enter description here
enter description here

2. 代码

这里我常用与输入的时候,就把已经输入的排好序了,输入前的一个数就是当前数组的最大值了,就不断的往前比较,如果比前面的要大就可以break

 import java.util.Arrays;

/**
 * @author shkstart
 * @create 2022-03-03 16:52
 */
public class Main {
    public static void main(String[] args) {
        Integer[] arr = {4,3,2,10,12,1,5,6};
        sort(arr);
    }
    public static void sort(Comparable[] a){
        for (int i = 1; i < a.length; i++) {

            for (int j = i; j > 0; j--) {

                if (greater(a[j - 1],a[j])){
                    exch(a,j - 1,j);
                }else {
                    break;
                }

            }
            System.out.println(Arrays.toString(a));
        }
    }
    //判断v比w大
    private static boolean greater(Comparable v,Comparable w){
        return v.compareTo(w)>0;
    }
    private static void exch(Comparable[] a,int i,int j){
        Comparable temp;
        temp = a[i];
        a[i] = a[j];
        a[j] = temp;
    }
}

二、希尔排序

希尔排序是插入排序的一种,又称“缩小增量排序”,是插入排序算法的一种更高效的改进版本。

1. 排序原理

1.选定一个增长量h,按照增长量h作为数据分组的依据,对数据进行分组;
2.对分好组的每一组数据完成插入排序;
3.减小增长量,最小减为1,重复第二步操作。

enter description here
enter description here

增长量h的确定:增长量h的值每一固定的规则,我们这里采用以下规则:

   	int h = 1;
   	while (h < N / 2) {
   		h = h * 2 + 1;
   	}
//循环结束后我们就可以确定h的最大值; 
//h的减小规则为: 
   	 h=h/2

2. 希尔排序的代码实现:

package XiRe;

import java.util.Arrays;

/**
* @author shkstart
* @create 2022-03-06 21:07
* <p>
* 插入排序的改进
*/
public class Main {
   public static void main(String[] args) {
       Integer[] arr = {9, 1, 2, 5, 7, 4, 8, 6, 3, 5};
       sort(arr);
       System.out.println(Arrays.toString(arr));

   }

   public static void sort(Comparable[] a) {
       int N = a.length;
       //确定增长量h的最大值
       int h = 1;
       while (h < N / 2) {
           h = h * 2 + 1;
       }
   	//增长量为1时结束
       while (h>=1){
   	//找到待插入的元素
           for (int i = h; i < N; i++) {
   		//a[i]就是待插入的元素 
   		//把a[i]插入到a[i-h],a[i-2h],a[i-3h]...序列中
               for (int j = i; j >= h; j-=h) {
   				//a[j]就是待插入元素,依次和a[j-h],a[j-2h],a[j-3h]进行比较,如果a[j]小,那么 交换位置,如果不小于,a[j]大,则插入完成。
                   if (greater(a[j - h],a[j])){
                       exch(a,j,j-h);
                   }

               }
           }
           h /=2 ;
       }

   }

   //判断v比w大
   private static boolean greater(Comparable v, Comparable w) {
       return v.compareTo(w) > 0;
   }

   private static void exch(Comparable[] a, int i, int j) {
       Comparable temp;
       temp = a[i];
       a[i] = a[j];
       a[j] = temp;
   }
}

在处理大批量数据时,希尔排序的性能确实高于插入排序。

3. 时间空间复杂度分析

enter description here
enter description here

插入排序
比较是从有序序列的末尾开始,也就是想要插入的元素和已经有序的最大者开始比起,如果比它大则直接插入在其后面,否则一直往前找直到找到它该插入的位置。如果碰见一个和插入元素相等的,那么把要插入的元素放在相等元素的后面。所以,相等元素的前后顺序没有改变,从原无序序列出去的顺序就是排好序后的顺序,所以插入排序
是稳定的。
希尔排序
希尔排序是按照不同步长对元素进行插入排序 ,虽然一次插入排序是稳定的,不会改变相同元素的相对顺序,但在不同的插入排序过程中,相同的元素可能在各自的插入排序中移动,最后其稳定性就会被打乱,所以希尔排序是不稳定的。

posted on 2022-04-29 15:55  钨丝  阅读(50)  评论(0)    收藏  举报

导航