插入排序(java实现)

64 阅读2分钟

小知识,大挑战!本文正在参与“程序员必备小知识”创作活动

插入排序是我们排序算法中一种比较基础算法 今天我将分享3中插入排序算法的累哦下

基本思想:将一个待排序的数插入到已排好序的关键字中,直到所有数排好。如 2 5 8 12 插入数7  则需要找到插入的位置即位置3,则需要移动8 12 移动元素后插入 说明:数组A[0]不放排序元素 从A[1]开始排序

1. 直接插入排序

public class InsertSort {
	//核心算法
	//A是待排序数组 n是表长
	public void insertSort(int[] A,int n ){
		int i,j;
		for(i=2;i<=n;i++){
			//待插入的数据A[i]大于A[i-1],则直接插入,反之则往前进行比较,
			//选择合适的插入的位置
			if(A[i]<A[i-1]){
				//A[0]仅是哨兵
				A[0]=A[i];
				//边查找边移动位置
				for(j=i-1;A[i]<A[j];j--){
					A[j+1]=A[j];
				}
				//找到插入位置
				A[j+1]=A[0];
			}
		}
	}
 
	//测试
    public static void main(String[] args) {
    	int[] A={0,2,12,6,8,11,31,18,27};
    	int n =A.length-1;
    	InsertSort insertSort = new InsertSort();
    	insertSort.insertSort(A, n);
    	for(int i=0;i<=n;i++){
    		System.out.println(A[i]);
    	}
	}
}

直接插入排序算法可以看出是边查找边移动位置 是否可以减少查找次数呢?

2.折半插入排序

选择一个待排序数插入一个序列时,这一个序列时有序的,那么就可以想到折半查找(测试代码都一样,这里只贴核心代码)

	//核心算法
	//A是待排序数组 n是表长
	public void insertSort(int[] A,int n ){
		int i,j,low,high,mid;
		for(i=2;i<=n;i++){
			A[0]=A[i];//将待排序数放到A[0]暂存
			low=1;
			high=i-1;
			//1.先利用折半查找找到插入的位置(查找和移动位置是分开进行的)
			while(low<=high){
				mid=(low+high)/2;
				if (A[mid]>A[0]) high=mid-1;
				else low=low+1;
			}
			//2.找到插入位置,移动元素
			for(j=i-1;j>=high+1;j--){
				A[j+1]=A[j];
			}
			//2.将待排元素插入
			A[high+1]=A[0];
		}
	}
        

与直接插入排序比较,只是减少了比较的次数,但是移动次数是没有变的

3. 希尔排序

什么是希尔排序算法:(自己理解的)希尔排序本质上就是直接插入排序,从一个例子来看:

image.png 希尔排序就是将原数组先划分为几个小组,分别排序,然后将增量减小再分组 ,再排序 直到增量为1,排序就完成了。所以希尔排序我们要知道增量怎么确定,一般增量d1=n/2;d2=d1/2;.......

//核心算法
	//A是待排序数组 n是表长
	public void ShellSort(int[] A,int n ){
		int i,j,d;//d是增量
		//注意和直接插入排序进行比较  实际上是多了一层for循环 这一层循环就是分组排序的次数
		for(d=n/2;d>=1;d=d/2){
			//这一个for循环和直接插入排序算法基本是一样的 (把d换成1)
			for(i=d+1;i<=n;i++){
				if(A[i]<A[i-d]){
					A[0]=A[i];
					for(j=i-d;j>0&&A[0]<A[j];j=j-d){
						A[j+d]=A[j];
					}
					A[j+d]=A[0];
				}
			}
		}
	}

4.总结

插入排序:核心思想就是 找到插入位置---移动元素---插入元素 基本就是这三个步骤 不同的插入算法 可能对于查找和移动的次数有所不同