常见的排序算法------插入排序

常见排序算法的实现:

1 插入排序

直接插入排序是一种简单的插入排序法,其基本思想是:
把待排序的记录按其关键码值的大小逐个插入到一个已经排好序的有序序列中,直到所有的记录插入完为止,得到一个新的有序序列 。
在实际生活中我们玩扑克牌时,就用了插入排序。
常见的排序算法------插入排序_第1张图片
1.2直接插入排序:
当插入第i(i>=1)个元素时,前面的array[0],array[1],…,array[i-1]已经排好序,此时用array[i]的排序码与array[i-1],array[i-2],…的排序码顺序进行比较,找到插入位置即将array[i]插入,原来位置上的元素顺序后移。

看到这里相信友友们还是很迷糊,来我这就分部操作。

一、假设前n-1项是有序的,整体不知到是不是有序的我们就可以挪动来是它有序。

常见的排序算法------插入排序_第2张图片

      int end = n-2;
		//首先保存要排序的数,一会就会被覆盖了
	   int tmp = a[end + 1];
		//只要前面的数大于end + 1,则前面的这些数都向后挪动一个位置
		while (end >= 0)
		{
			if (tmp < a[end])
			{
				//前面的这些数都向后挪动一个位置
				a[end + 1] = a[end];
				--end;
			}
			else
			{
				break;
			}
		}
		//1.tmp比它前面的所以的数小。
		//2.首次找到数组中元素比tmp小跳出。
		a[end + 1] = tmp;

二、我们可以从下表为0的数看为 有序的,在插入下标为一的的数,依次类推。
常见的排序算法------插入排序_第3张图片
依次类推。

// 插入排序
void InsertSort(int* a, int n)
{
	//最后一次,是要把n - 1这个数进行排序,则已经
	//排好序的尾部为n - 2
	int i = 0;
	for (i = 0; i < n - 1; i++)
	{
		//end表示已经排好序的尾标
		int end = i;
		//首先保存要排序的数,一会就会被覆盖了
		int tmp = a[end + 1];
		//只要前面的数大于end + 1,则前面的这些数都向后挪动一个位置
		while (end >= 0)
		{
			if (tmp < a[end])
			{
				a[end + 1] = a[end];
				--end;
			}
			else
			{
				break;
			}
		}
		//1.tmp比它前面的所以的数小。
		//2.首次找到数组中元素比tmp小跳出。
		a[end + 1] = tmp;

	}
}
int a[] = { 9,1,2,5,7,4,8,6,3,5 };
	int sz = sizeof(a) / sizeof(a[1]);
	InsertSort(a, sz);
	Print(a, sz);

排序后的结果为:
1234556789

在这里插入图片描述

直接插入排序的特性总结:

  1. 元素集合越接近有序,直接插入排序算法的时间效率越高
  2. 时间复杂度:O(N^2)
  3. 空间复杂度:O(1),它是一种稳定的排序算法
  4. 稳定性:稳定

1.3 希尔排序( 缩小增量排序 )

希尔排序法又称缩小增量法。希尔排序法的基本思想是:先选定一个整数,把待排序文件中所有记录分成个组,所有距离为的记录分在同一组内,并对每一组内的记录进行排序。然后,取,重复上述分组和排序的工作。当到达=1时,所有记录在统一组内排好序。

原理图:
常见的排序算法------插入排序_第4张图片

    int a[] = { 9,1,2,5,7,4,8,6,3,5 };
	int sz = sizeof(a) / sizeof(a[1]);
	ShellSort(a, sz);
	Print(a, sz);

代码段:

// 希尔排序
void ShellSort(int* a, int n)
{
	int gap = n;
	while (gap > 1)
	{
		// 只有gap最后为1,才能保证最后有序
		//所以这里要加1
		gap = gap / 3 + 1;
		//这里只是把插入排序的1换成gap即可
		//但是这里不是排序完一个分组,再去
		//排序另一个分组,而是整体只过一遍
		//这样每次对于每组数据只排一部分
		//整个循环结束之后,所有组的数据排序完成
		int i = 0;
		for (i = 0; i < n - gap; ++i)
		{
			int end = i;
			int tmp = a[end + gap];
			while (end >= 0)
			{
				if (a[end] > tmp)
				{
					a[end + gap] = a[end];
					end -= gap;
				}
				else
				{
					//找到数组中元素比tmp小跳出。
					break;
				}
			}
			//1.tmp比它前面的所以的数小。
			//2.首次找到数组中元素比tmp小跳出。
			a[end + gap] = tmp;

		}
	}
}

结果展示:
1234556789
在这里插入图片描述

你可能感兴趣的:(数据结构与算法,排序算法,算法,数据结构)