插入排序和希尔排序(分组插排)
插入排序:
1 直接插入排序-原理
整个区间被分为
- 有序区间
- 无序区间
每次选择无序区间的第一个元素,在有序区间内选择合适的位置插入
代码实现:
import java.util.Arrays;
import java.util.Random;
//插入排序
//具备稳定性
public class insertSort
{
public static void insertSort1(long[] array)
{
//数据一共 array.length 个
//
for (int i = 0; i < array.length - 1; i++)
{
//有序:[0,i + 1)
//无序:[i + 1,array.length - 1]
long key = array[i + 1];
//依次在有序期间进行比较
int j;
for (j = i; j >= 0; j--)
{
//array[j] 与 key 比较
if (key < array[j])
{
array[j + 1] = array[j];
} else
{
break;
}
}
array[j + 1] = key;
}
}
public static long[] func() //随机数组
{
Random random = new Random(20210320);
long[] array = new long[10];
for (int i = 0; i < 10; i++)
{
array[i] = random.nextInt(100);
}
return array;
}
public static long[] func2() //有序数组
{
long[] a = func();
Arrays.sort(a);
return a;
}
public static long[] func3() //逆序数组
{
long[] a = func2();
for (int i = 0; i < a.length / 2; i++)
{
long t = a[i];
a[i] = a[a.length - i - 1];
a[a.length - i - 1] = t;
}
return a;
}
public static void main(String[] args)
{
long[] a1 = func();
System.out.println(Arrays.toString(a1));
insertSort1(a1);
System.out.println(Arrays.toString(a1));
long[] a2 = func2();
System.out.println(Arrays.toString(a2));
insertSort1(a2);
System.out.println(Arrays.toString(a2));
long[] a3 = func3();
System.out.println(Arrays.toString(a3));
insertSort1(a3);
System.out.println(Arrays.toString(a3));
}
}
希尔排序
1 原理
希尔排序法又称缩小增量法。希尔排序法的基本思想是:先选定一个整数gap,把待排序文件中所有记录分成若干个组,所有距离为gap的记录分在同一组内,并对每一组内的记录进行排序。然后,取,重复上述分组和排序的工作。当gap到达=1时,
所有记录在统一组内排好序。
1. 希尔排序是对直接插入排序的优化。
2. 当gap > 1时都是预排序,目的是让数组更接近于有序。当gap == 1时,数组已经接近有序的了,这样就会很快。这样整体而言,可以达到优化的效果。我们实现后可以进行性能测试的对比。
代码实现:
import java.util.Arrays;
import java.util.Random;
//希尔排序(分组插排)
public class shellSort
{
public static long[] func() //无序数组
{
Random random = new Random(20210320);
long[] array = new long[10];
for (int i = 0; i < 10; i++)
{
array[i] = random.nextInt(100);
}
return array;
}
public static long[] func2() //有序数组
{
long[] a = func();
Arrays.sort(a);
return a;
}
public static long[] func3() //逆置数组
{
long[] a = func2();
for (int i = 0; i < a.length / 2; i++)
{
long t = a[i];
a[i] = a[a.length - i - 1];
a[a.length - i - 1] = t;
}
return a;
}
public static void main(String[] args)
{
long[] a1 = func();
System.out.println(Arrays.toString(a1));
shellSort1(a1);
System.out.println(Arrays.toString(a1) + "\n");
long[] a2 = func2();
System.out.println(Arrays.toString(a2));
shellSort1(a2);
System.out.println(Arrays.toString(a2) + "\n");
long[] a3 = func3();
System.out.println(Arrays.toString(a3));
shellSort1(a3);
System.out.println(Arrays.toString(a3) + "\n\n");
}
public static void shellSort1(long[] array)
{
int gap = array.length;
while (gap > 1)
{
insertSortGap(array, gap);
gap = (gap / 3) + 1; // OR gap = gap / 2;
}
insertSortGap(array, 1);
}
private static void insertSortGap(long[] array, int gap)
{
for (int i = 1; i < array.length; i++)
{
long v = array[i];
int j = i - gap;
for (; j >= 0 && array[j] > v; j -= gap)
{
array[j + gap] = array[j];
}
array[j + gap] = v;
}
}
}