七大排序算法之希尔、插入

插入排序

大概率有序的或者元素较小(20个左右)的情况下使用;

思想:

将无序部分插入到有序的部分

找要插入的位置:(两种方法)

1、顺序查找(在大概率有序情况下)

2、二分查找(无序情况下,较顺序查找较快)

时间复杂度:

平均:O(N^2);

使用顺序查找时,最好的情况为O(N);

最坏:O(N^2)

空间复杂度:O(1)

稳定性:稳定排序(稳定:不会改变相同元素的相对顺序)

代码实现:

顺序查找插入排序(直接插入排序)

//升序
//顺序查找法
public static void insertSort(int[] arr) {
	//[0, i)有序区间
	for(int i = 1; i < arr.length; ++i) {
		//给属于无序位置i在有序区间[0, i)找合适的插入位置
		int boundValue = arr[i]; 
		int j = i;
		for(; j > 0; --j) {
			if(arr[j - 1] > boundValue) {//当前处理值的前一个值若大于当前i的值
				arr[j] = arr[j - 1];//就一个一个往前移动
			}else {//当前位置合适
				break;
			}
		}
		arr[j] = boundValue;//将当前找出合适位置的值赋值为之前未被覆盖之前i的值
	}
}

二分查找插入排序

//二分查找法
public static void insertSortBin(int[] arr) {
	for(int i = 1; i < arr.length; ++i) {
		int boundValue = arr[i]; 
		int index = BinSearch(arr, i - 1, boundValue);//返回找到的位置
		//将有序区间[0, i)中(index, i]后移,将index位置空出
		for(int j = i; j > index; j--) {
			arr[j] = arr[j-1];
		}
		arr[index] = boundValue;
	}
}

private static int BinSearch(int[] arr, int n, int boundValue) {
	int left = 0;
	int right = n;
	int mid = 0;
	while(left <= right) {
		mid = (left+right)/2;
		if(boundValue > arr[mid]) {
			left = mid + 1;
		}else {
			right = mid - 1;
		}
	}
	return left;
}



//二分查找
//mid已经比较,所以right/left需要前移/后移一位
class Solution {
    public int search(int[] nums, int target) {
        int left = 0;
        int right = nums.length - 1;
        int mid;

        while (left <= right) {
            mid = left + (right - left) / 2;
            if (nums[mid] == target) {
                return mid;
            }
            if (nums[mid] > target) {
                right = mid - 1;
            } else {
                left = mid + 1;
            }
        }
        return -1;
    }
}

希尔排序 

该排序算法是基于若排序序列尽可能有序,插入排序会很快的想法

思想:分组插排

1、先做预排序(使排序序列尽可能有序)

组内数据间隔逐渐变小,密度逐渐变小

2、开始插入排序

时间复杂度:

平均情况:O(N^1.3)

最好情况:O(N)

最坏情况:O(N^2)

空间复杂度:O(1)

代码实现:

public static void shellSort(int[] array) {
	// 使用希尔序列:n/2, n/4, n/8...1
	// 分组的组大小逐渐增大,一个组的数据间隔越来越小
	for (int group = array.length / 2; group >= 1; group /= 2) {
		for (int i = group; i < array.length; ++i) {
			int boundValue = array[i];
			int j = i;
			for (; j >= group; j -= group) {// 分组插排
				if (array[j - group] > boundValue) {
					array[j] = array[j - group];
				} else {
					break;
				}
			}
			array[j] = boundValue;
		}
	}

}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值