排序算法-插入排序
Posted 梦想田园
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了排序算法-插入排序相关的知识,希望对你有一定的参考价值。
//直接插入排序/*
插入排序的思想彻底理清楚了,代码实现起来就非常简单了
基本思想:就像打扑克一样,将提取的每个元素不断的插入到已经排好序的数组中。
思想很简单,但是要实现代码,还需要将整个过程描述一遍。
1、首先第一个元素是排好序的,不用再排序,那就从第二个元素开始。
2、假设前面的n个元素是排好序的,那么接下来应该将第n+1个元素放到合适的位置,如何放呢:
*首先将该元素作为关键字,并把它原来的位置空下来。
*将前面的元素不断跟关键字比较,只要比关键字大就要向后移动一位,这样空位置就不断往前移动
*当遇到比关键字小的元素或移动到头部,停止移动
*将该关键字放到空位置
*/
void InsertSort(int list[],int size)
for(int i=1;i<size;i++)//将后面的size-1个元素不断排序
int key=list[i];//将要排序的元素作为关键字。
int j=i-1;//j用来记录前边要比较的元素的序号
for(;j>=0&&list[j]>key;j--)//移动的条件
list[j+1]=list[j];//移动
list[j+1]=key;//当移动停止时,将关键字放到正确的位置
//
//直接插入搞明白了,希尔排序就非常简单了,希尔排序是插入排序的一种改善。
/*直接插入排序在将每个元素进行排序时需要移动比它大的所有元素,希尔排序则采用
分组的形式,分组形式采用等间隔方式,比如如果间隔为2,则1,3,5是一组,2,4,6是一组,然后对每组
采用直接插入排序方式,然后采用小间隔重复,直到间隔为1,当间隔为1时相当于对所有进行排序
*/
//希尔排序
void myShellSort(int list[],int size)
int gap=size/2;
while(gap>=1)
for(int i=0;i<gap;i++)//对所有组进行排序
for(int j=i+gap;j<size;j+=gap)//对每组进行排序
int key=list[j];
int k=j-gap;
for(;k>=0&&list[k]>key;k-=gap)//对元素的移动
list[k+gap]=list[k];
list[k+gap]=key;
gap/=2;//间隔不断缩小,直到为0停止
//仔细分析,可以将希尔排序的代码改善如下:
void shellSort(int list[],int size)
int gap = size / 2;
while (1 <= gap)
// 把距离为 gap 的元素编为一个组,扫描所有组
for (int i = gap; i < size; i++)
int j = 0;
int temp = list[i];
// 对距离为 gap 的元素组进行排序
for (j = i - gap; j >= 0 && temp < list[j]; j = j - gap)
list[j + gap] = list[j];
list[j + gap] = temp;
gap = gap / 2; // 减小增量
//使用折半搜索改进的插入排序
/*
希尔排序对插入排序的改进是通过减少移动次数,我们都知道,移动元素所花费的代价大于比较花费的代价
而采用折半搜索改进的是减少比较的次数。在直接插入排序中,每当将一个元素放到正确的排序位置时,都需要
与前边的排好序的数组进行比较,我们可以通过折半查找来减少比较次数
*/
/*
折半查找的思想很简单,就是在有序数组中,先与中间的元素比较,大的话在右边查找,小的话在左边查找,相等则找到,因此终止条件为相等或区间内没有元素
而对于插入排序来说,应该是要找到关键元素要插入的位置,因此终止条件应该为中间没有元素,可问题又来了,当中间没有元素时,应选用上界作为要插入的位置还是
下界呢,可以分析一下。在本次递归之前应该是index1==index2,即他们指向同一个元素,而key如果小于这个元素,则该元素的位置为index1,而如果大于等于这个元素
则位置为index2。而当key小于这个元素时,应该将该元素后移,即key插入到index1位置,当key大于等于这个元素,key应该保持原来的位置不变,而key应该插入到index2+1的位置,而此时index2+1==index1,因此返回index1,综上可述,应该返回index1
*/
int seekInsertPlace(int list[],int index1,int index2,int key)
if(index1>index2)
if(list[index1]>=key)
return index1;
else if(list[index1]<key)
return index1+1;
int index=(index1+index2)/2;
if(list[index]>key)
return seekInsertPlace(list,index1,index-1,key);
else
return seekInsertPlace(list,index+1,index2,key);
//使用折半搜索改进的插入排序
void binaryInsertSort(int list[],int size)
for(int i=1;i<size;i++)//将后面的size-1个元素依次排序
int key=list[i];//将要排序的元素作为关键字。
int insertIndex=seekInsertPlace(list,0,i-1,key);//寻找要插入的位置
for(int j=i-1;j>=insertIndex;j--)//移动的条件
list[j+1]=list[j];//移动
list[insertIndex]=key;//当移动停止时,将关键字放到正确的位置
//另外对于这几种插入排序算法的分析可参看http://www.cnblogs.com/heyuquan/p/insert-sort.html
以上是关于排序算法-插入排序的主要内容,如果未能解决你的问题,请参考以下文章