希尔排序算法

希尔排序(缩小增量排序算法):比较次数和移动次数均有改善。主要是利用直接插入排序的最好性质:元素少且基本有序。

希尔排序思想:

  1. 将记录序列分成若干个子序列分别进行直接插入排序

  2. 经过多次调整序列记录已基本有序最后再对记录进行直接插入排序。

具体如下:

  1. 对整个文件,按步长d1分组,组内进行直接插入排序

  2. 取d2<d1(缩小增量),继续以d2为步长排序,直到dt=1(此时进行直接插入排序)为止。

所谓步长 就是两个元素的下标的差值 例如 若步长为 4( 元素下标从 0 1 均可 ), 1 个元素 5 个元素会在一组 一次类推

待排序序列:46, 55, 13, 42, 94, 17, 5, 70

d1= 4:(46, 17, 5, 42, 94, 55, 13, 70)

d2= 2:(5, 17, 13, 42, 46, 55, 94, 70)

d3= 1:(5, 13, 17, 42, 46, 55, 70, 94)

distance=4 46,17,5,42,94,55,13,70,

distance=2 5,17,13,42,46,55,94,70,

distance=1 5,13,17,42,46,55,70,94,

证明希尔排序的性能需要用到逆转数的概念。

时间复杂度:O(n1.5)。

稳定性:不稳定,举一个反例即可。例如:(2, 4, 1, 2)

希尔排序的java代码实现如下:

java 复制代码
public class ShellSort {
	public static void shellSort(int[] sourceArray) {
		int len = sourceArray.length;
		// 起始增量(步长)
		int distance = len / 2;
		while (distance >= 1) {
			// 本次增量情况下的循环组数,每一组进行直接插入排序
			for (int groupidx = 0; groupidx < distance; groupidx++) {
				// 组内进行直接插入排序
				for (int idx = groupidx + distance; idx < len; idx += distance) {
					// 正在遍历的元素
					int monitor = sourceArray[idx];
					/* while循环寻找每一组的插入位置 */
					// 索引j表示每一组到这个位置都是排好序的
					int j = idx - distance;
					while ((j >= 0) && (sourceArray[j] > monitor)) {
						// 移动元素
						sourceArray[j + distance] = sourceArray[j];
						j -= distance;
					}
					sourceArray[j + distance] = monitor;
				}
			}
			// 增量缩小
			distance /= 2;
		}
	}

	public static void main(String[] args) {
		// int[] sourceArray = { 46, 55, 13, 42, 94, 17, 5, 70 };
		int[] sourceArray = { 19, 2, 3, 6, 1, 8, 13 };
		shellSort(sourceArray);
		for (int tmp : sourceArray) {
			System.out.print(tmp + " ");
		}
	}
}
相关推荐
福尔摩斯张1 小时前
C语言文件操作详解(一):文件的打开与关闭(详细)
java·linux·运维·服务器·c语言·数据结构·算法
white-persist1 小时前
【攻防世界】reverse | answer_to_everything 详细题解 WP
c语言·开发语言·汇编·python·算法·网络安全·everything
K哥11251 小时前
【9天Redis系列】数据结构+string
数据结构·数据库·redis
minji...1 小时前
Linux 进程控制(二) (进程等待wait/waitpid)
linux·运维·服务器·数据结构
Ynchen. ~1 小时前
[工程实战] 攻克“数据孤岛”:基于隐语纵向联邦学习的金融风控建模全解析
算法·金融·逻辑回归·隐语
程序员-King.1 小时前
day107—同向双指针—无重复字符的最长字串(LeetCode-3)
算法·leetcode·双指针
风掣长空1 小时前
【LeetCode】面试经典150题:合并两个有序数组
算法·leetcode·面试
im_AMBER1 小时前
Leetcode 69 正整数和负整数的最大计数
数据结构·笔记·学习·算法·leetcode
fufu03111 小时前
Linux环境下的C语言编程(三十六)
linux·c语言·开发语言·数据结构·算法