直接插入,希尔,选择排序

直接插入排序

1.思想

当插入第i(i>=1)个元素时,前面的array[0],array[1],…,array[i-1]已经排好序,此时用array[i]的排序码与array[i-1],array[i-2],…的排序码顺序进行比较,找到插入位置即将array[i]插入(这里我们采用交换)

当我们去排一组数字(排升序)时,我们应该把第一个元素当作为有序的, 然后把后面的数字与其进行比较,如果小于第一个数字,两者就交换,完成该步操作后,前2个数据有序的,然后我们在将第3个数字,与前面两个数字从后往前去比较,如果有个位置满足比前面的大,比后面的小,那么这个位置,就是它应该在的位置。据此要求,依次往后去遍历整个数据。

 2.代码实现

直接插入,希尔,选择排序_第1张图片

这样把下标为end的数据往前面去插入合适位置的前提是:end前面的数据是有序的(当只有1个数据,也是有序的)  

void Swap(int* p1, int* p2)
{
	int tmp = *p1;
	*p1 = *p2;
	*p2 = tmp;
}

//直接插入排序  排升序的代码
void InsertSort(int* a, int n)
//n为数组中的数据数量,a是指向数组地址的指针
{
	for (int i = 1; i <= n - 1; i++)
	{
		int	end = i;
		while (end >= 0)
		{
			if (a[end] > a[end -1])//当该下标为end的数据小于前面的数据就交换
			{
				Swap(&a[end],&a[end -1]);
				--end;
			}
			else//当下标为end的数据大于下标为end-1的数据,
                //就意味着下标为的end的数据大于下标小于end的数据,
                //这是因为前面的数据是有序的,并且拍的是升序
			{
				break;
			}
		}

	}
}

希尔排序

1.思想

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

  • gap>1 先进行预排序,就是先对数据进行处理,将其变成相对有序
  • 在当 gap=1,进行直接排序 ,就相当于上文中的直接插入排序

     这里我们是对该组数据依据gap进行分组,然后我们都对每个组进行直接排序,但非一次处理完一组的数据

  • 如果一次性处理完第一组,然后去处理第二组,再依次往后,这就会又导致出来一层for循环
  • 此时希尔就想到了,不要一次就将一组的数据就处理完,而是先处理各组的第一次,在处理各组的第二次,依次往下
  • 这就是多组并排
2代码实现 
//希尔排序
void ShellSort(int* a, int n)
{
	int gap = n;
	while (gap > 1)
	{
		gap = gap / 3 + 1;//这里gap这样处理,是因为这样处理时,可以很好的处理大多数数据,是前人所总结下来的
//如果一次性处理完第一组,然后去处理第二组,再一次往后,这就会又导致出来一层for循环
//此时希尔又想到了不要一次将所有的全部处理完,而是先处理各组的第一次,在处理各组的第二次,依次往下
//就是多组并排
		for (int i = 0; i < n - gap; ++i)
                         //i= 0)
			{
				if (a[end] > tmp)
				{
					a[end + gap] = a[end];
					end = end - gap;
				}
				else
				{
					break;
				}
			}
			a[end + gap] = tmp;
		}
	}
}

 选择排序

堆排序再之前的文章中有涉及,这里就不再涉及:堆的实现 堆排序 【用C语言实现】-CSDN博客

1.思想

排降序)创建2个变量begin和end,初始化两者begin=0 end=n-1(n为数据的数量),先假设最大数据的下标为begin,最小的数是下标为end的数,然后通过遍历数组,找到最大的和最小的,然后将最小的放在最后一个位置,将最大的数据放在第一个位置;再++begin --end再重复上面操作,当begin>end时就结束了。

当我们得到了最大值和最小值的下标后,我们要考虑当begin,end,minindex,maxindex其中有重合,由于我们首先交换begin和maxindex,故他们一定实现了最大值在最前面的效果,然后我们要考虑,minindex与end(begin)重和这种情况,

  • 当minindex与begin重和,那么我们就要将maxindex赋给minindex,这是因为最小值位置已经发生改变了,那么我们就要更新最小值的小标。
  • 当minindex与end重和,这样正好达到了我们要实现的目标,进行minindex与end所对应值交换,也不会有影响
2代码实现 
/利用选择排序来将其排成降序
void SelectSort(int* a, int n)
{
	int begin = 0;
	int end = n - 1;
	while (end >= begin)
	{
		int min = begin;
        int maxindex = 0;//要创建好两个变量来记录下标
        int minindex = end;
		int max = begin;
		for (int i = begin; i <= end; i++)
		{
			if (a[i] < a[min])
			{
				min = a[i];
                minindex=i;
			}
			if (a[i] > a[max])
			{
				max = a[i];
                maxindex=i;
			}
		}
		Swap(&a[begin], &a[maxindex]);
        if(minindex==begin)
        {
          minindex=maxindex;
        }
		Swap(&a[end], &a[minindex]);
		++begin; 
		--end;
	}
}

 

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