直接插入排序
插入排序就是:取出一个数,插入到有序数组中,首先,取出第一个元素放入有序数组中,然后取出第二个,两个数进行比较,如果它小,则有序数的最后一个向后移动一格,然后与有序数组倒数第二个比较,如果小,则继续向后移动。如果碰到比它小的,则插入在其后面。
算法思想为:外层循环是遍历数组的所有值 内层循环是,找到小于该值的下标,然后大于该下标的值向后移动。
public static void insertSort(int[] array) {
for (int i = 0; i < array.length; i++) {
int j;
for (j = i - 1; j >= 0 && array[i] < array[j]; j--){
}
int pos=j+1;
int key=array[i];
//把大于key的值都向后移动
for(int k=i;k>pos;k--){
array[k]=array[k-1];
}
//在pos位置插入key
array[pos]=key;
}
}
选择排序
选择排序的主要思想:首先找出整个数组中最小的一个数,然后第一个数和最小的数进行交换,然后,继续寻找最小的数,然后和数组第二个数进行交换。
public static void selectSort(int[] array) {
for (int i = 0; i < array.length; i++) {
int min = i;
//找到最小值的下标
for (int j = i + 1; j < array.length; j++) {
if (array[j] < array[min]) {
min = j;
}
}
swap(array, min, i);
}
}
public static void swap(int[] array, int a, int b) {
int tmp;
tmp = array[a];
array[a] = array[b];
array[b] = tmp;
}
冒泡排序
冒泡排序思想:首先从第一个数开始,将其作为最大的数,然后和下一个数进行比较,然后进行交换,永远保持大的数在后面,这样没进行一次循环都会找出一个最大的数,最终,最大的数会在数组的最后去
//优化版本
public static <T extends Comparable<T>> void bubbleSort(T[] t) {
boolean swap = true;
for (int i = 0; i < t.length && swap; i++) {
swap = false;
for (int j = 1; j < t.length - i - 1; j++) {
if (t[j].compareTo(t[j + 1]) > 0) {
T tmp = t[j];
t[j] = t[j + 1];
t[j + 1] = tmp;
swap = true;
}
}
}
}
public static void bubbleSort(int[] array) {
for (int i = 0; i < array.length-1; i++) {
for (int j = 0; j < array.length - i - 1; j++) {
if (array[j] > array[j+1]) {
int tmp = array[a];
array[a] = array[b];
array[b] = tmp;
}
}
}
}
堆排序
堆排序基本思路:首先创建一个大堆,将最大的元素放在最上面,然后再与最后一个元素交换,原来有N个数,现在最大的在最后面,去除后,剩余的N-1个数再进行创建大堆,然后再进行交换,直到个数变为1,这个时候就是完整的排序
static void heapSort(int[] array) {
for (int i = array.length / 2 - 1; i >= 0; i--) {
//调整堆,使所有的双亲节点都大于子节点
heapify(array, i, array.length);
}
//初步调整完毕,取出最顶上的节点,然后与最后一个结点交换,除去最后一个节点,然后继续调整堆,使所有的双亲节点都大于子节点
for (int j = array.length - 1; j > 0; j--) {
swap(array, 0, j);
//交换最后第一个和最后一个,去除最后一个,再进行调整
heapify(array, 0, j);
}
}
static void heapify(int[] arr, int i, int length) {
//找到非叶子节点
int tmp = arr[i];
//找到其子节点
for (int k = 2 * i + 1; k < length; k = 2 * k + 1) {
//比较两个子节点的大小
if (arr[k] < arr[k + 1] && k + 1 < length) {
k++;
}
//比较子节点与父节点的大小
//谁大谁在上
if (tmp < arr[k]) {
arr[i] = arr[k];
i = k;
} else {
break;
}
}
//此时顶上的数为arr[k], k位置的数应该变为tmp
arr[i]=tmp;
}
//交换堆顶元素与最后一个元素
public static void swap(int[] array, int a, int b) {
int tmp;
tmp = array[a];
array[a] = array[b];
array[b] = tmp;
}
归并排序
归并排序思想:采用分治算法,将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。
//归并排序
public static void mergeSort(int[] array) {
//创建一个额外的空间
int[] extra = new int[array.length];
mergeSortInner(array, 0, array.length, extra);
}
//进行分组
public static void mergeSortInner(int[] array, int low, int high, int[] extra) {
//分组结束条件,等于0或者只有一个数
if (low == high - 1) {
return;
}
if (low >= high) {
return;
}
//满足分组条件 进行分组
int mid = low + (high - low) / 2;
//运用递归 一直分组
//分左边的分组
mergeSortInner(array, low, mid, extra);
//分右边的分组
mergeSortInner(array, mid, high, extra);
//此时分组已经分好,这个时候要进行合并,然后排序。
merge(array, low, mid, high, extra);
}
//两个分组进行排序合并
public static void merge(int[] array, int low, int mid, int high, int[] extra) {
int i = low;
int j = mid;
int x = 0;
//遍历数组,按大小将数排入到extra中
while (i < mid && j < high) {
if (array[i] <=array[j]) {
extra[x++] = array[i++];
} else {
extra[x++] = array[j++];
}
}
//如果i>mid,说明左边的已经全部都放入extra中,此时直接将右边有序的插入到后面
while (j < high) {
extra[x++] = array[j++];
}
//如果j>high,说明右边的已经全部都放入extra中,此时直接将左边有序的插入到后面
while (i < mid) {
extra[x++] = array[i++];
}
//最后将extra已经排好的数放入到array中
for (int k = low; k < high; k++) {
array[k] = extra[k - low];
}
}
快速排序
快速排序主要思想::任取待排序元素序列中 的某元素作为基准值,按照该排序码将待排序集合分割成两子序列,左子序列中所有元素均小于基准值,右 子序列中所有元素均大于基准值,然后最左右子序列重复该过程,直到所有元素都排列在相应位置上为止。
public static void quickSort(int[] array, int low, int high) {
//递归终止条件
if (low > high) {
return;
}
int i = low, j = high, tmp = array[low], t;
while (i < j) {
//找到一个比基准值小的数
while (tmp <= array[j] && i < j) {
j--;
}
//找到一个比基准值大的数
while (tmp >= array[i] && i < j) {
i++;
}
//找到比基准值大的和比基准值小的数。进行交换
if (i < j) {
t = array[j];
array[j] = array[i];
array[i] = t;
}
}
//以上操作已经将所有大于和小于基准值的数分好。
//此时再将基准值放进去
array[low] = array[i];
array[i] = tmp;
//递归进行左右数组,进行上述步骤
quickSort(array, low, j - 1);
//递归调用右半数组
quickSort(array, j + 1, high);
}