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

DSA之排序(2):插入排序

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

DSA之排序(2):插入排序

文章目录
  • 1 插入排序
    • 1.1 基本思想
    • 1.2 基本操作
    • 1.3 插入位置
  • 2 插入排序的种类
    • 2.1 直接插入排序
      • 2.1.1 直接插入排序算法
      • 2.1.2 性能分析
      • 2.1.3 结论
    • 2.2 折半插入排序
      • 2.2.1 折半插入排序算法
      • 2.2.2 性能分析
    • 2.3 希尔排序
      • 2.3.1 希尔排序算法
      • 2.3.2 性能分析
      • 2.3.3 结论

1 插入排序 1.1 基本思想

把待排序的,插入到已经排好序的合适的位置。

边插入边排序,保证子序列都是排好序的。

1.2 基本操作


1.3 插入位置


Q:如何找到插入位置?
A:下方的插入排序方法将会介绍。

2 插入排序的种类

2.1 直接插入排序

采用顺序查找法查找插入位置。

循环跳出条件为:j >= 0 && x < a[j]
从后往前找,但有个问题,每次循环都要判断两个,时间太久,之前在顺序查找法的时候,有个带哨兵的,现在可以用上。直接把待插入元素第i个位置上的元素放到下标为0的位置(哨兵位置)上面。

2.1.1 直接插入排序算法
void InsertSort(SqList &L)
{
	int i, j;
	for (i = 2; i <= L.length(); ++i)
	{
		if (L.r[i].key < L.r[i-1].key)//若"<",需要将L.r[i]插入到有序子表
		{
			L.r[0] = L.r[i];//复制2为哨兵,减少循环的比较条件
	for (j = i-1; L.r[0].key < L.r[j].key; --j)
			{
				L.r[j+1] = L.r[j];//记录后移
			}
			L.r[j+1] = L.r[0];//插入到正确的位置
		}
	}
}
2.1.2 性能分析



2.1.3 结论

2.2 折半插入排序

直接插入法是在查找位置的时候,从后往前依次进行比较的,这种一个一个进行比较的方法叫做顺序查找法。折半查找法定义一个low端一个high端,找到mid中间位置,与哨兵位置比较,mid比哨兵小,就在右半区域进行查找;反之亦然。找到后依然是要将位置向后移动,然后将哨兵位置的元素放到合适的位置。

2.2.1 折半插入排序算法
void BInsertSort(SqList &L)
{
	for (i = 2; i <= L.length(); ++i)//依次插入第2~第n个位置
	{
		L.r[0] = L.r[i];//当前插入元素存到哨兵位置
		low = 1;
		high = i-1;//采用二分查找法查找插入位置
		while(low <= high)
		{
			mid = (low + high) / 2;
			if (L.r[0].key < L.r[mid].key)
			{
				high = mid - 1;
			}
			else 
			{
				low = mid + 1;
			}
		}//循环结束,high+1则为插入位置
		for (j = i-1; j >= high+1; --j)
		{
			L.r[j+1] = L.r[j];//移动元素
		}
		L.r[high+1] = L.r[0];//插入到正确的位置
	}
}
2.2.2 性能分析


折半只是减少了比较的次数,移动的次数没有减少。

2.3 希尔排序


希尔排序算法的出发点,就是怎么能够在进行插入排序的时候基本有序,怎么能比较一次就移动一大步,相当于是继承了上方几种排序的优点。

基本思想:
先将整个待排记录序列分割成若干子序列(元素个数就少了,交换的时候可以移动一大步),分别进行直接插入排序,待整个序列中的记录“基本有序”时,再对全体记录进行一次直接插入排序。

希尔排序算法,特点:

  • 缩小增量
  • 多遍插入排序

思路:

最后一次是1间隔的插入排序。

特点:

2.3.1 希尔排序算法
//主程序
void ShellSort(SqList &L, int dlta[], int t)
{
//按增量序列dlta[0...t-1]对顺序表L作希尔排序
	for (k=0; k
		ShellInsert(L, dlta[k]);//一趟增量为dlta[k]得到插入排序,总共是循环的t趟
	}
}
//其中一趟的排序操作
void ShellInsert(SqList &L, int dk)
{
	for (i=dk+1; i<=L.length(); ++i)
	{
		if (r[i].key < r[i-dk].key)
		{
			r[0] = r[i];
for (j=i-dk; j>0 && (r[0].key
				r[j+dk]=r[j];
			}
			r[j+dk] = r[0];
		}
	}
}

本质上还是插入排序,但是按照间隔来的。

2.3.2 性能分析



非稳定性算法

2.3.3 结论

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

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

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