插入排序、希尔排序、归并排序、快速排序

本文介绍了四种基本排序算法:插入排序、希尔排序、归并排序和快速排序。插入排序通过不断插入元素到已排序部分来实现排序;希尔排序通过比较间隔元素来提高效率;归并排序利用分治法将序列分解再合并;快速排序则选取主元进行划分。文章详细阐述了每种排序算法的原理、代码实现以及时间复杂度。
摘要由CSDN通过智能技术生成

插入排序

插入排序将序列分成已排序未排序两部分。每次从未排序序列中拿一个元素,接着找到这个元素在已排序中可以插入的位置后插入,然后从未排序序列中将这个元素删除,这就完成了一个元素的排序。类似于我们抓扑克牌,手上的牌都拍好了序,桌上的拍没有排好序,每次我们从桌上抓取一张牌插入到手上的牌中。重复这个过程,我们就可以得到一个排好序的序列。
在这里插入图片描述
下面我们使用代码来实现插入排序。

/*
	 	思路:
	 		1. 从未排序的序列中拿取元素ele
	 		2. 在已排序的序列中找到元素ele的插入位置
	 		3. 在找到的位置中插入元素ele
	 		4. 重复上述直到未排序的序列中没有元素
	 */
	@Test
	public void insertSort() { 
		int[] arr = { 1, 23, 41, 231, 31, 5, 4, 2, 67 };
		for (int i = 1; i < arr.length; i++) { // 控制插入的数字为第几个
			int temp = arr[i];	// 需要插入的元素
			int index = i - 1;	// 记录temp在已排好序的位置
			// 寻找插入位置
			while(index >= 0 && temp<arr[index]) {	// 找位置
				// 将元素往后移动一个位置,为temp腾出插入空间
				arr[index+1] = arr[index];
				index--;
			}
			arr[index+1] = temp;	// 插入
		}
	}

上述的for循环中,arr[0 … i] 总是保存已经排好序的序列,而arr[i+1 … arr.length-1]总是保存着未排序的序列,我们把这种性质称为循环不变式,下面我们先介绍循环不变式。


循环不变式

循环不变式主要帮助我们来理解算法的正确性,关于循环不变式总是有三条性质需要我们证明

  • 初始化
      循环的第一次迭代之前,它为真
  • 保持
      如果循环的某次迭代之前它为真,那么下一次迭代它也为真
  • 终止
      在循环终止时,不变式为我们提供一个有用的性质,该性质有助于证明算法是正确的。

在插入排序中,初始化arr[0 … i] 中只有一个元素,并已经排好序,arr[i+1 … arr.length - 1] 有a.length -1 个元素,且无序。循环体内的代码为我们保持初始化的中的特性,当i = arr.length时,循环终止。
插入排序的最坏情况下的时间复杂度为 O ( n 2 ) O(n^2) O(n2),外层循环循环n次,里层循环n次。


希尔排序

希尔排序源自于Donald Shell,希尔排序是通过比较一定间隔的元素来进行排序的,每一趟比较所用的距离随着算法的进行而缩小,直到只比较相邻元素的下一趟排序为止,因为这个原因希尔排序也叫缩减增量排序。希尔排序中影响排序性能的可控变量是**增量序列(如序列h1,h2,h3…ht,其中h1等于1)**的选择,合适的增量序列能够提高性能。Shell建议的增量序列是ht = N/2 、hk = hk+1/2。下面给出进行一次希尔排序
在这里插入图片描述
下面是希尔排序的代码实现

	@Test
	public void shellSort1() {
		int[] arr = {12,32,123,42,121,41,56,72,45};
		for(int gap = arr.length/2 ; gap > 0 ; gap /=2) {// 计算增量序列,终止条件gap=0
			for(int i = gap ; i < arr.length; i++) { // 从index = gap开始逐渐比较
				int temp = arr[i];	// 保存gap的值,下面可能会被覆盖
				int index; // 保存temp应该放置的为止
				// 间隔比较,满足条件则交换
				for(index = i ; index >= gap && temp < arr[index-gap] ; index-=gap) {	
					arr[index] = arr[index-gap];
				}
				arr[index] = temp;	// 将temp放到对于的为止
			}
		}
	}

每次循环后都有 a r

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值