一.直接插入排序
我们现在有一组数组 elem { 5 ,18,7,21,9 } ,我们现在想将他按从小到大的顺序排列,在直接插入排序中,我们将用到三个变量 j,i,tem。 i 将初始化为下标为 1 的值,tem 将初始化为下标为 i 的值,j 初始化为下标为 i - 1 的值。以上准备工作就完成了,我们将 j 的值与 tem 的值来比较,如果 j 的值大于 tem 的值,我们就令 elem[ j +1 ] = elem[ j ]; 并且 j--,直到 j 的值小于 tem 的值,此时我们需要让 elem[ j+1 ] = tem 并且结束循环 break 。 在此基础上,我们增加上循环,就可以实现直接插入排序。
public class insort {
public static void insersort(int[] elem) {
for (int i = 1; i < elem.length; i++) {
int tem = elem[i];
int j = i-1;
for (; j >=0; j--) {
if (elem[j] > tem){
elem[j+1] = elem[j];
}else {
break;
}
}
elem[j+1] = tem;
}
}
}
测试:
import java.util.Arrays;
public class test {
public static void main(String[] args) {
int[] elem = {5,18,7,21,9};
insort.insersort(elem);
System.out.println(Arrays.toString(elem));
}
}
运行结果: 符合预期
二.希尔排序
希尔排序是在直接插入排序的基础上,将要排序的数组进行分组,比如说我有一个数组elem{1,3,4,6,7,9,2,5,8,10} ,除了直接插入排序用到的三个变量 j i 和 tem ,我们还需要用到一个变量 gap ,gap 是我们分组的时候要用的,gap指的是 i 和 j 两个下标之间的间隔,(例如当 gap = 2,i = 5的时候,那么 j = i - gap,也就是说 j = 3)我们将 gap 初始化为 elem.length,当 gap > 1 的时候,每次循环我们令 gap/2,那么为什么说希尔排序是分了不同的组呢,如图:
可以看到,当gap = 5的时候,数组其实分为了 5 个组,每个组里面两个元素,那么当这五组排序完之后,gap/2,也就是 gap = 2 的时候,数据是分为了两个组的
最后也就是 gap = 1 的时候,这时候数据只有一个组,直接采用直接插入排序,那么我们为什么采用希尔排序而不是直接使用 直接插入排序呢,比较 希尔排序看起来更麻烦,这是因为在电脑的计算中, 要排序数组元素的时候,在处理时间上, {1,2,3,4,5}>{1,5,3,4,2,}>{5,4,3,2,1},我们用希尔排序的时间在一定程度上是比直接插入排序的时间复杂度要小的。
代码:
public class shellsort {
public static void shellsort(int[] elem){
int gap = elem.length;
while (gap > 1){
gap = gap/2;
shell(elem,gap);
}
}
public static void shell(int[] elem,int gap){
for (int i = 1; i < elem.length; i++) {
int tem = elem[i];
int j = i - gap;
for (; j >=0; j -= gap) {
if (elem[j] > tem){
elem[j + gap] = elem[j];
}else {
break;
}
}
elem[j + gap] = tem;
}
}
}
测试:
import java.util.Arrays;
public class test {
public static void main(String[] args) {
int[] elem = {1,3,4,6,7,9,2,5,8,10};
shellsort.shellsort(elem);
System.out.println(Arrays.toString(elem));
}
}
运行结果: 符合预期。
三.堆排序
在写堆排序前,我们需要先把创建大根堆的代码准备好,我们有一个数组 elem,我们首先把这个数组创建为大根堆,这样大根堆的堆顶元素肯定是最大的值,我们让堆顶元素和堆里面的最后一个元素通过 swap 代码 来交换位置,然后让其余元素重新进行向下调整,这样循环下去,我们就通过堆排序实现了数组元素从小到大排列。
代码:
public class Heapsort {
public static void Heapsort(int[] elem){
GreatHeap(elem);
for (int i = elem.length-1; i > 0; i--) {
swap(elem,0,i);
siftDown(elem,0,i);
}
}
public static void GreatHeap(int[] elem){
for (int parent =(elem.length-1-1)/2; parent >=0 ; parent--) {
siftDown(elem,parent,elem.length-1);
}
}
private static void siftDown(int[] elem,int parent,int len){
int child = 2*parent +1;
while (child < len){
if (child +1 < len && elem[child] < elem[child+1]){
child++;
}
if (elem[child] > elem[parent]){
swap(elem,parent,child);
parent = child;
child = 2*parent +1;
}else break;
}
}
private static void swap(int[] array,int i,int j){
int tem = array[i];
array[i] = array[j];
array[j] = tem;
}
}
测试:
import java.util.Arrays;
public class test {
public static void main(String[] args) {
int[] elem = {1,3,4,6,7,9,2,5,8};
Heapsort.Heapsort(elem);
System.out.println(Arrays.toString(elem));
}
}
运行结果: 符合预期
四.选择排序
我们现在有一个数组 elem{ 1, 3 , 4 , 6 , 7 , 9 , 2 , 5 , 8 },让你从小往大排列,我们需要用到 3 个变量 i j 和 tem,我们令 i 初始化为 0,tem 初始化为 i,令 j 初始化为 i +1,并且 j ++,让elem[ tem] 不断地与 elem[ j ]相比较,如果 elem[ j ] <elem[ tem ],那么我们就令 tem = j,这样一圈走下来,tem 就是这个数组 i —— elem.usedsize-1 里面最小的值的下标,我们让 elem 中 i 下标和 tem 下标的值更换位置,循环上述操作,最终我们就可以通过选择排序来得到我们想要的结果。
public class seleceSort {
public static void selsort(int[] elem){
for (int i = 0; i < elem.length; i++) {
int tem = i;
for (int j = i + 1; j < elem.length; j++) {
if (elem[j] < elem[tem]){
tem = j;
}
}
swap(elem,i,tem);
}
}
//进行数据的位置交换
private static void swap(int[] array,int i,int j){
int cur = array[i];
array[i] = array[j];
array[j] = cur;
}
}
测试:
import java.util.Arrays;
public class test {
public static void main(String[] args) {
int[] elem = {1,3,4,6,7,9,2,5,8};
seleceSort.selsort(elem);
System.out.println(Arrays.toString(elem));
}
}
运行结果: 符合预期