首页 > 代码库 > 简单插入排序和希尔排序(原理和C语言实现)
简单插入排序和希尔排序(原理和C语言实现)
简单插入排序的原理很简单:
所谓插入排序,就是将新加入的数据插入到一个有序数组中,并且保证插入后有序。这就要求要找到插入的位置。
(图片来自维基百科)
对于一个已经存在的数组(乱序),要将其有序排列(这里取从小到大),就可以按照下面的步骤:
1.先假定一个有序数组,这个数组只有一个元素,就是第一个元素,它一定是有序的;
2.我们从第二个数(下标为1)开始向后遍历数组;
for(insert_index=1; insert_index < arr_len; insert_index++){
}
3.找到第二个数应该插入的位置,然后insert_index继续向后遍历;
问题来啦:怎么找到应该插入的位置?
insert_position从insert_index前面一个位置向前遍历(注意不要越界,它的范围是>=0的),直到找到比arr[insert_index]小的数,
此时position不再变化并且指向这个值。
注意,实际上插入的位置应该是insert_position之后的那个位置。
for(insert_pos=insert_index-1; insert_pos>=0; insert_pos--){
}
4.找到position后,要判断找到的这个位置是不是连续的,如果是连续的,就没有必要插入;
e.g. 34 45 56
pos insert_index
pos指向insert_index前一个位置,此时不用做插入操作。
if(insert_pos+1 != insert_index)...
5.先将这个insert_index所指向的值保存,temp=insert_index,然后数组依次后移;
int temp = arr[insert_index];
for(index=insert_index-1; index > insert_pos; insert_index--){
arr[index+1]=arr[index];
}
6.后移完成,此时将insert_index的值插入;
arr[insert_pos + 1] = temp; //还记得吗?是要插入到pos后面的; 此时的index是等于insert_pos的
好 此时我们整理一下:
要用到的变量:insert_index insert_pos index 数组 arr 长度arr_len
1 for(insert_index=1;insert_index<arr_len;insert_index++){ 2 //查找insert_pos 从insert_index前一个位置开始向前遍历 3 for(insert_pos=insert_index-1;insert_pos>=0;insert_pos--){ 4 //如果insert_pos<insert_index 查找成功 5 if(arr[insert_pos]<arr[insert_index]){ 6 break; 7 } 8 } 9 }10 11 //已经找到插入位置,将数组后移12 if(insert_pos+1!=insert_index){//判断是否是连续的 如果是连续的不需要做插入操作;13 //将insert_index 暂存14 temp=arr[insert_index];15 //遍历后移16 for(index=insert_index-1;index>insert_pos;index--){17 arr[index+1]=arr[index];18 }19 arr[insert_pos+1]=temp;//放置在pos的后面20 }
知道原理后,就可以将上述代码简化:
上述代码是先找到插入位置,然后再将数组后移
我们可以在遍历时判断交换直至到达插入位置
1 void sort(int *arr, int arr_len) 2 { 3 int i,j; 4 for(i=1;i<arr_len;i++){ 5 j=i-1; 6 temp=a[i]; 7 while(j>=0&&arr[j]>temp){ 8 arr[j+1]=arr[j]; 9 j=j-1;10 }11 arr[j+1]=temp;12 }13 }
这种方法就可以直接拿来转换成希尔排序;
所谓的希尔排序,就是对其设定步长,而不是每个都交换判断
(图片来自维基百科)
1 void shell(int *arr, int arr_len) 2 { 3 int i,j; 4 int gap=0; 5 int tamp; 6 while(gap<=arr_len){ 7 gap=3*gap+1; 8 } 9 while(gap>0){10 for(i=gap;i<arr_len;i++){11 j=i-gap;12 temp=arr[i];13 while(j>=0&&arr[j]>temp){14 arr[j+gap]=arr[j];15 j=j-gap;16 }17 arr[j+gap]=temp;18 }19 gap=(gap-1)/3;20 }21 }
简单插入排序和希尔排序(原理和C语言实现)