插入排序,希尔排序,堆排序

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了插入排序,希尔排序,堆排序相关的知识,希望对你有一定的参考价值。

本文将介绍三种排序算法--插入排序,希尔排序,堆排序。本文所有例子都是使用升序

  一.插入排序

   算法思想

    维护一个有序数组,将要插入的数据与有序数组自最后一个元素直到合适位置的数一一比较。

eg: 有序数组:1,3,5,6,7   现在待插入数据为2,那么他将会和7,6,5,3,依次作比较,当带插入数据小于有序数组最后的元素大小,则将该元素后移,直到待插入元素找到合适位置为止。

   代码实现

void InsertSort(int* a, int size)
{
	assert(a);
	for (int i = 0; i < size - 1; ++i)
	{
		int end = i;                                 //标识有序数组的最后一位
		int tmp = a[end + 1];
		while (end >= 0 && tmp < a[end])
		{
			a[end + 1] = a[end];                     //待插入数据比有序数组的最后一个数小,将有序数组最后一位向后移位
			--end;
		}
		a[end + 1] = tmp;
	}
}

   总结

技术分享    1.插入排序可以认为是间距为1的插入算法,说这个是为了待会儿更好的理解希尔排序。

    2.插入排序的时间复杂度为O(n^2);

    3.插入排序的空间复杂度为O(1);

    4.具有稳定性


 排序算法的稳定性是指,经过排序算法排序的相同元素的相对位置不会发生改变。

  二.希尔排序

   算法思想

    希尔排序可以认为是插入排序的增强版,因为,他加入了一个预排的过程,即在实现间距为1的插入算法之前,他已经预先将间距为gap(gap一直减减直到>0)的数组排列过了。所以,当进行gap = 1的插入排序之前使得待排序数组已经高度接近有序,使得这次进行的gap = 1的排序的时间复杂度,可以小于O(N^2)(gap = 1的插入排序,最好情况的时间复杂度为O(1),前面的预排过程正是出于这个目的)。

   代码实现

//希尔排序
void ShellSort(int* a,size_t size)
{
	assert(a);
	int gap = size / 2;
	while (gap > 0)
	{
		for (int i = 0; i < size - gap; ++i)
		{
			int end = i;                                
			int tmp = a[end + gap];
			while (end >= 0 && tmp < a[end])
			{
				a[end + gap] = a[end];                    
				end -= gap;
			}
			a[end + gap] = tmp;
		}
		--gap;
	}
}

  总结

技术分享 上图为gap = 5 的时候的预排效果图

 1.希尔排序预排的思想和插入排序的思想是一致的,只是,他把原数组分成不同的区间。

 2.希尔排序的时间复杂度为O(N^2),空间复杂度为O(1);

 3,具有不稳定性


 三.堆排序

  算法思想

技术分享代码实现

void AdjustDown(int* a, size_t size, int parent)
{
	assert(a);
	int child = parent * 2 + 1;
	while (child<size)
	{
		if (child+1<size && a[child] < a[child + 1])
			++child;
		if (a[parent] < a[child])
		{
			swap(a[parent], a[child]);
			parent = child;
			child = parent * 2 + 1;
		}
		else
		{
			break;
		}
		
	}
}
void HeapSort(int* a,size_t size)
{
	assert(a);
	//建堆
	for (int i = (size - 2) / 2; i >= 0; --i)  //从第一个非叶子节点开始调
	{
		AdjustDown(a, size, i);
	}
	for (size_t i = 0; i < size; ++i)
	{
		swap(a[0], a[size - 1 - i]);
		AdjustDown(a, size - i - 1, 0);
	}
}

 总结

 1.时间复杂度为O(N*lgN),空间复杂度为O(1);

 2.具有不稳定性


 以上就是本人在学习过程中的一些经验总结。当然,本人能力有限,难免会有纰漏,希望大家可以指正。


本文出自 “做一个小小小司机” 博客,请务必保留此出处http://10799170.blog.51cto.com/10789170/1782078

以上是关于插入排序,希尔排序,堆排序的主要内容,如果未能解决你的问题,请参考以下文章

常见排序算法的实现(归并排序快速排序堆排序选择排序插入排序希尔排序)

插入排序,希尔排序,堆排序

插入排序,希尔排序,堆排序详解

Java实现常见排序--希尔排序快排序堆排序归并排序等Java实现代码

C# 各种内部排序方法的实现(直接插入排序希尔排序冒泡排序快速排序直接选择排序堆排序归并排序基数排序)

C# 各种内部排序方法的实现(直接插入排序希尔排序冒泡排序快速排序直接选择排序堆排序归并排序基数排序)