简单插入排序和希尔排序(原理和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 }
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。