![]()
- 插入排序
最佳情况:T(n) = O(n)
最坏情况:T(n) = O(n2)
平均情况:T(n) = O(n2)
public int[] insertionSort(int[] array) {
if (array.length == 0) {
return array;
}
int current;
for (int i = 0; i < array.length - 1; i++) {
current = array[i + 1];//从第二个元素开始,与之前的元素进行比较;之后的每个元素都做相同的操作
int preIndex = i;//从当前元素开始比较
while (preIndex >= 0 && current < array[preIndex]) {//如果preIndex元素比后一个元素大,就将preIndex元素移到下一位
array[preIndex + 1] = array[preIndex];
preIndex--;
}
array[preIndex + 1] = current;//前面做了--操作,避免越界-1以及补回多减掉的1,所以preIndex+1;把当前值的下一个赋到此处;如果current比它前面的所有值都大,位置就不变
}
return array;
}
- 归并排序
最佳情况:T(n) = O(n)
最差情况:T(n) = O(nlogn)
平均情况:T(n) = O(nlogn)
public int[] MergeSort(int[] array) {
if (array.length < 2) return array;
int mid = array.length / 2;//取中间索引
int[] left = Arrays.copyOfRange(array, 0, mid);//将初始数组分为两个数组,第一次分解
int[] right = Arrays.copyOfRange(array, mid, array.length);
return merge(MergeSort(left), MergeSort(right));//递归分解,再合并;会一直分解到单个数为止,到那个时候,left和right的长度都为1
}
public int[] merge(int[] left, int[] right) {
int[] result = new int[left.length + right.length];
for (int index = 0, i = 0, j = 0; index < result.length; index++) {
if (i >= left.length) {//如果左边left数组的值已经遍历完,那么result数组剩下的位置用right数组剩下的值来填
result[index] = right[j++];
} else if (j >= right.length) {//同理,如果right数组已经遍历完,就直接把left数组剩下的值来填result剩下的位置
result[index] = left[i++];
} else if (left[i] > right[j]) {
result[index] = right[j++];//如果前面的两个都没满足,就需要比较当前left数组和right数组的当前值,谁小就把谁填进result
} else {
result[index] = left[i++];
}
}
return result;
}
- 堆排序
最佳情况:T(n) = O(nlogn)
最差情况:T(n) = O(nlogn)
平均情况:T(n) = O(nlogn)
public int[] HeapSort(int[] array) {
int len = array.length;
if (len < 1) return array;
//先构建一个大顶堆
buildMaxHeap(array, len);
for (int i = len - 1; i > 0; i--) {
swap(array, 0, i);//把堆首和堆尾互换,此时堆尾成了最大
len--;//长度减1
adjustHeap(array, 0, len);//再调整
}
return array;
}
public void buildMaxHeap(int[] array, int len) {
//从最后一个非叶子节点开始往上构造大顶堆
//i的左子树和右子树分别为2i+1和2(i+1)
for (int i = (len / 2 - 1); i >= 0; i--) {
adjustHeap(array, i, len);
}
}
public void adjustHeap(int[] array, int i, int len) {
int maxIndex = i;
int left = i * 2 + 1;
int right = i * 2 + 2;
//如果有左子树,并且左子树大于父节点,将最大指针指向左子树
if (left < len && array[left] > array[maxIndex]) {
maxIndex = left;
}
//如果有右子树,并且右子树大于父节点,将最大指针指向右子树
if (right < len && array[right] > array[maxIndex]) {
maxIndex = right;
}
//如果经过了上面的操作,即存在左子树或右子树大于父节点的情况,最大指针已经改变了
if (maxIndex != i) {//调整当前小数(i,左,右)的值的位置,将最大的放到i位置
swap(array, i, maxIndex);//那么就交换此时最大指针指向的值和当前i指向的值
adjustHeap(array, maxIndex, len);//递归,对maxIndex做相同的操作
}
}
public void swap(int[] array, int i, int j) {
int temp = array[i];
array[i] = array[j];
array[j] = temp;
}