插入排序
一共有三种:直接插入排序、希尔排序和折半插入排序。最后一个折半插入排序,感觉用在数组上面不太方便,就没写出来。
递归实现没有思路,使用的非递归算法。
直接插入排序
这个算法默认前n个数是已经排好序的,n随着你的插入逐渐变大,最开始是1。
然后从后往前逐渐查找应该插入的位置;我的算法是从小到大,那就依次对比当前位置的值是否比要插入的值大,如果大就往后移动一个位置,小于等于当前位置的值就进行插入结束这一次的插入操作,进入下一次。
希尔排序
这个排序算法的思路就是将数组分为好多组,然后逐渐减少,最终只剩下一组,就是最终的结果。
最开始将数组根据初始增量分为两两一组,在每一组内进行排序;逐渐缩短增量,直到增量为一,就是排好序的数组。
在组内排序的算法其实可以是别的算法。
折半插入排序
和直接插入排序思路相同,但是在查询插入点的时候,是从已经排好序的数组中间查询要插入的点,查询到之后将插入点之后的数依次后移,将数插入。
归并排序
数组从大依次切开,分为n组,然后再将相邻的两组进行合并,并排序,最后只剩下一组就是结果。这个算法使用递归会比较简单点。非递归实现,没思路。
代码
package 算法设计与分析;
public class Work3 {
public Work3(){
int[] nums = { 2, 3, 8, 4, 5, 7, 1, 9, 6 };
insertSort1( nums );
for ( int i : nums )
System.out.println( i );
}
//插入排序--直接插入排序
public void insertSort1( int[] array ){
//从第2个数开始,依次将数插在已经排序过的数组中,前i+1个数为已经排序的
for ( int i = 1; i < array.length; i++ ){
//存储将要插入的数,以及索引
int temp = array[i], j;
//依次比较,如果要插入的数小于当前位置的数了,就将前面的值依次向后移动一位
for ( j = i-1; j >= 0 && temp < array[j]; j-- ){
array[j+1] = array[j];
}
//将要插入的数存储在,最后查询到的位置上
array[j+1] = temp;
}
}
//插入排序--希尔排序
public void insertSort2( int[] array ){
//初始增量为数组长度的一半,之后依次减半,直到1停止
for ( int len = array.length/2; len >= 1; len/=2 ){
//对每组进行组内排序
for ( int i = 0; i < len; i++ ){
//进行组内排序,其实这就是一个直接插入排序
for ( int j = i+len; j < array.length; j+= len ){
int temp = array[j], k;
for ( k = j-len; k >= 0 && temp < array[k]; k-=len ){
array[k+len] = array[k];
}
array[k+len] = temp;
}
}
}
}
//归并排序--递归算法
public void mergeSort( int[] array ){
devideArray( 0, array.length-1, array );
}
//先对数组进行分割,然后进行合并,递归
public void devideArray( int start, int end, int[] array ){
//最小长度为1
if ( start < end ){
//对数组进行分割
int middle = (start+end)/2;
devideArray( start, middle, array);
devideArray( middle+1, end, array );
//合并
mergeArray( start, middle, end, array );
}
}
//对数组进行合并
public void mergeArray( int start, int middle, int end, int[] array ){
//用于临时存储合并后的排序数组
int[] tmp = new int[end-start+1];
int len = 0;
//标记在合并的两个数组中的位置
int left = start;
int right = middle+1;
while ( true ){
//当循环均在在两个部分的范围之内时,进行排序
if ( left <= middle && right <= end ){
if ( array[left] < array[right] ){
tmp[len++] = array[left++];
}else{
tmp[len++] = array[right++];
}
//只有左部在范围之内,直接添加上去,不需要再进行排序
}else if ( left <= middle && right > end ){
tmp[len++] = array[left++];
//只有右部在范围之内时,同样直接添加
}else if ( left > middle && right <= end ){
tmp[len++] = array[right++];
//结束循环
}else
break;
}
//将归并好的部分重新添加在原数组的位置
for ( int i = start; i <= end; i++ ){
array[i] = tmp[i-start];
}
}
public static void main(String[] args) {
Work3 work3 = new Work3();
}
}
来源:CSDN
作者:Le.diablew
链接:https://blog.csdn.net/weixin_45980031/article/details/104580754