栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

数据结构 八大排序之直接插入排序与希尔排序

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

数据结构 八大排序之直接插入排序与希尔排序

目录

一.直接插入排序

1.1.直接插入排序引入1.2.直接插入排序的核心思想与算法分析1.3.实例说明1.4.直接插入排序代码实现1.5.直接插入排序性能分析 二.希尔排序

2.1希尔排序引入2.2希尔排序的核心思想与算法分析2.3实例说明2.4希尔排序代码实现2.5希尔排序性能分析

一.直接插入排序 1.1.直接插入排序引入

排序是我们生活中经常会面对的问题,以打扑克牌为例,你摸的手牌肯定是杂乱的,你一定会将小牌移动到大牌的左面,大牌移动到小牌的右面,这样顺序就算理好了。这里我们的理牌方法就是直接插入排序。

1.2.直接插入排序的核心思想与算法分析

核心思想: 就是将一个记录插入到已经排好序的有序表中,从而得到一个新的记录数增1的有序表。

算法分析:

    从序列第一个元素开始,该元素可以认为已经被排序取出下一个元素,设为待插入元素,在已经排序的元素序列中从后向前扫描,如果该元素(已排序)大于待插入元素,将该元素移到下一位置。重复步骤2,直到找到已排序的元素小于或者等于待排序元素的位置,插入元素。重复2,3步骤,完成排序。
1.3.实例说明

以12,2,9,8,18,7这几个数字为例,排序过程:

这里三角形表示要插入的值横线表示已经排好序的数字j是趟数,是这一趟开始的时候已排序队列的最后一个值的下标。 1.4.直接插入排序代码实现

代码如下:

void InsertSort(int* arr, int len)
{
	//assert arr!=NULL

	for (int i = 1; i < len; i++)//一共跑了多少趟  //01234   12345  
	{
		int tmp = arr[i];//待插入的值  
		//j 指向 这一趟开始的时候的已排序好的队列中最后一个值的下标
		int j;
		for (j = i - 1; j >= 0; j--)//这里控制待插入的值和 已排序队列的挨着比较(从右向左比较)
		{
			if (arr[j] <= tmp)
			{
				break;//这时应该停下来
			}
			else
			{
				arr[j + 1] = arr[j];
			}
		}
		arr[j + 1] = tmp;
	}
}
1.5.直接插入排序性能分析

    时间复杂度:
    (1)顺序排序时,只需比较(n-1)次,插入排序时间复杂度为O(n)
    (2)逆序排序时,需比较n(n-1)/2次,插入排序时间复杂度为O(n^2)
    (3)当原始序列杂乱无序时,平均时间复杂度为O(n^2)

    空间复杂度:
    插入排序过程中,需要一个临时变量temp存储待排序元素,因此空间复杂度为O(1)。

    算法稳定性:
    插入排序是一种稳定的排序算法。

二.希尔排序 2.1希尔排序引入

希尔排序其实就是对直接插入排序的优化,在第一部分我们说过==(1)直接插入排序数据越有序,插入的效率就越高;(2)记录数比较少时,直接插入的优势也很明显。==希尔排序就是根据这两个特点进行的优化。

2.2希尔排序的核心思想与算法分析

核心思想: 通过一个不断缩小的增量序列,对无序序列反复的进行拆分并且对拆分后的序列使用插入排序的。

算法分析:

    先将整个待排元素序列分割成若干个子序列(由相隔某个“增量”的元素组成的);分别进行直接插入排序,然后依次缩减增量再进行排序;待整个序列中的元素基本有序(增量足够小)时,再对全体元素进行一次直接插入排序;完成排序。
2.3实例说明

以12,2,9,8,5,88,99,10,7,17,77,66,89,10,21为例,排序过程如下:

这里相同颜色的线相同的分组每次增量取上一次的一半(向下取整)注意:最后一个增量值必须等于1才可以 2.4希尔排序代码实现

代码如下:

void Shell(int arr[], int len, int gap)//一趟希尔排序
{
	for (int i = gap; i < len; i++)//i++  不是i=i+gap;
	{
		int tmp = arr[i];//待插入的值  
		//j 指向 这一趟开始的时候的已排序好的队列中最后一个值的下标
		int j;
		for (j = i - gap; j >= 0; j = j - gap)//这里控制待插入的值和 已排序队列的挨着比较(从右向左比较)
		{
			if (arr[j] <= tmp)
			{
				break;//这时应该停下来
			}
			else
			{
				arr[j + gap] = arr[j];
			}
		}
		arr[j + gap] = tmp;
	}
}
void ShellSort(int arr[], int len)
{
	int gap[] = { 5, 3, 1 };//
	int gap_len = sizeof(gap) / sizeof(gap[0]);
	for (int i = 0; i < gap_len; i++)
	{
		Shell(arr, len, gap[i]);
	}
}
2.5希尔排序性能分析

    时间复杂度:
    希尔排序的时间复杂度依赖于增量序列的函数,当n在某个特定的范围后最优的情况下,希尔排序的时间复杂度为O(n ^ 1.3),在最差的情况下,希尔排序的时间复杂度为:O(n ^ 2)

    空间复杂度:
    希尔排序的空间复杂度:O(1)。

    算法稳定性:
    希尔排序并不是一种稳定的排序算法。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/786125.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号