一、直接插入排序

  它的思想:每次从无序表中取出第一个元素,把它插入到有序表的合适位置,使有序表仍然有序。

     下面我来说一下我的思路:

          1.第一趟比较前两个数,然后把第二个数按大小插入到有序表中。

          2.第二趟把第三个数据与前两个数从前向后扫描,把第三个数按大小插入到有序表中。

          3.依次进行下去,进行了(n-1)趟扫描以后就完成了整个排序过程。

下面我用图来帮助大家理解:

wKiom1c5vWPD6XQdAAEyTTrgyrc502.jpg

实现代码:

void InsertSort(int *arr, size_t size)
{
	int end;//要排序的所有元素的最后一个元素的下标
	int tmp;
	for (int i = 0; i < size - 1; i++)
	{
		end = i;
		tmp = arr[end + 1];//最后一个元素保存起来
		//把所有大于最后一个元素的元素向后移动
		while (arr[end]>tmp&&end >= 0)
		{
			arr[end + 1] = arr[end];
			end--;
		}
		//把最后一个元素插入到不大于它的元素后面
		arr[end + 1] = tmp;
	}
}

二、希尔排序

     希尔排序,也称递减增量排序算法,是插入排序的一种更高效的改进版本。希尔排序是非稳定排序算法。

希尔排序:将无序数组分割为若干个子序列,子序列不是逐段分割的,而是相隔特定的增量的子序列,对各个子序列进行插入排序;然后再选择一个更小的增量,再将数组分割为多个子序列进行排序......最后选择增量为1,即使用直接插入排序,使最终数组成为有序。

增量的选择:在每趟的排序过程都有一个增量,至少满足一个规则 增量关系 d[1] > d[2] > d[3] >..> d[t] = 1 (t趟排序);根据增量序列的选取其时间复杂度也会有变化,这个不少论文进行了研究,在此处就不再深究;本文采用首选增量为n/2,以此递推,每次增量为原先的1/2,直到增量为1;

下图详细讲解了一次希尔排序的过程:


代码实现:

void ShillSort(int *arr, size_t size)
{
	int end;//要排序的所有元素的最后一个元素的下标
	int gap = size / 2;//将数组分为size/2个子序列
	int tmp;//临时值
	for (gap = size / 2; gap > 0; gap /= 2)//增量递减
	{
		for (int i = gap; i < size ; i++)
		{
			if (arr[i]<arr[i - gap])
			{
				end = i - gap;
				tmp = arr[i];
				//当arr[end]>tmp时,移动
				while (arr[end]>tmp&&end >= 0)
				{
					arr[end + gap] = arr[end];
					end -= gap;
				}
				arr[end + gap] = tmp;
			}	
		}
	}
}

希望大家能理解,写得不够好的地方,希望大家指出来。